From 20ecfccc511da5c178ab000e8d75760f4a72d63f Mon Sep 17 00:00:00 2001 From: Bapiraju Alla Date: Tue, 30 Nov 2021 18:22:13 +0530 Subject: [PATCH] qcacld-3.0: Fix mem leak with NDP peer multicast address list Currently, NDP peer multicast address is derived from peer MAC address and cached in the host. While removing the NDP peer, peer MAC address is used to search the cached multicast address list. Because of this, peer multicast address list is not getting freed. To resolve this, derive peer multicast address from the peer MAC address while clearing the cached multicast address list. Since MAX NDP sessions are 8, allocate memory for peer multicast address list during the NAN vdev private object allocation. This avoids the special handling for peer multicast list in multiple error scenarios. Change-Id: Ifbf890a4b9c8be54d84a5b57ed8f6c237ecd51ca CRs-Fixed: 3085069 --- components/nan/core/src/nan_main_i.h | 5 +- components/nan/dispatcher/inc/cfg_nan.h | 6 +- components/nan/dispatcher/src/nan_ucfg_api.c | 60 +++++++------------- 3 files changed, 29 insertions(+), 42 deletions(-) diff --git a/components/nan/core/src/nan_main_i.h b/components/nan/core/src/nan_main_i.h index 63e1ef12183b..e5ca11c43f51 100644 --- a/components/nan/core/src/nan_main_i.h +++ b/components/nan/core/src/nan_main_i.h @@ -30,6 +30,7 @@ #include "qdf_status.h" #include "nan_public_structs.h" #include "wlan_objmgr_cmn.h" +#include "cfg_nan.h" struct wlan_objmgr_vdev; struct wlan_objmgr_psoc; @@ -152,7 +153,6 @@ struct nan_psoc_priv_obj { * @ndp_init_done: Flag to indicate NDP initialization complete after first peer * connection. * @peer_mc_addr_list: Peer multicast address list - * @num_peer_mc_addr: Number of entries in peer multicast list */ struct nan_vdev_priv_obj { qdf_spinlock_t lock; @@ -165,8 +165,7 @@ struct nan_vdev_priv_obj { struct qdf_mac_addr primary_peer_mac; void *disable_context; bool ndp_init_done; - struct qdf_mac_addr *peer_mc_addr_list; - uint8_t num_peer_mc_addr; + struct qdf_mac_addr peer_mc_addr_list[MAX_NDP_SESSIONS]; }; /** diff --git a/components/nan/dispatcher/inc/cfg_nan.h b/components/nan/dispatcher/inc/cfg_nan.h index 2ac7241be3dc..5f1bdf1292b0 100644 --- a/components/nan/dispatcher/inc/cfg_nan.h +++ b/components/nan/dispatcher/inc/cfg_nan.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -168,6 +169,9 @@ CFG_VALUE_OR_DEFAULT, \ "Keep alive timeout of a peer") +/* MAX NDP sessions supported */ +#define MAX_NDP_SESSIONS 8 + /* * * ndp_max_sessions - To configure max ndp sessions @@ -189,7 +193,7 @@ #define CFG_NDP_MAX_SESSIONS CFG_INI_UINT( \ "ndp_max_sessions", \ 1, \ - 8, \ + MAX_NDP_SESSIONS, \ 8, \ CFG_VALUE_OR_DEFAULT, \ "max ndp sessions host supports") diff --git a/components/nan/dispatcher/src/nan_ucfg_api.c b/components/nan/dispatcher/src/nan_ucfg_api.c index ad3b4bf4b12c..7b23364a52a8 100644 --- a/components/nan/dispatcher/src/nan_ucfg_api.c +++ b/components/nan/dispatcher/src/nan_ucfg_api.c @@ -203,37 +203,24 @@ inline void ucfg_nan_set_peer_mc_list(struct wlan_objmgr_vdev *vdev, return; } - qdf_spin_lock_bh(&priv_obj->lock); - if (!priv_obj->peer_mc_addr_list) { - cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions); + cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions); - priv_obj->peer_mc_addr_list = - qdf_mem_malloc(max_ndp_sessions * - sizeof(struct qdf_mac_addr)); - if (!priv_obj->peer_mc_addr_list) { - nan_err("Failed to allocate multicast address list"); - goto end; - } - priv_obj->num_peer_mc_addr = 0; - } else { - for (i = 0; i < max_ndp_sessions; i++) { - if (qdf_is_macaddr_zero( - &priv_obj->peer_mc_addr_list[i])) { - list_idx = i; - break; - } - } - if (list_idx == max_ndp_sessions) { - nan_err("Peer multicast address list is full"); - goto end; + qdf_spin_lock_bh(&priv_obj->lock); + for (i = 0; i < max_ndp_sessions; i++) { + if (qdf_is_macaddr_zero(&priv_obj->peer_mc_addr_list[i])) { + list_idx = i; + break; } } + if (list_idx == max_ndp_sessions) { + nan_err("Peer multicast address list is full"); + goto end; + } /* Derive peer multicast addr */ peer_mac_addr.bytes[0] = 0x33; peer_mac_addr.bytes[1] = 0x33; peer_mac_addr.bytes[2] = 0xff; priv_obj->peer_mc_addr_list[list_idx] = peer_mac_addr; - priv_obj->num_peer_mc_addr++; end: qdf_spin_unlock_bh(&priv_obj->lock); @@ -260,28 +247,25 @@ inline void ucfg_nan_clear_peer_mc_list(struct wlan_objmgr_psoc *psoc, struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev); int i; uint32_t max_ndp_sessions = 0; + struct qdf_mac_addr derived_peer_mc_addr; if (!priv_obj) { nan_err("priv_obj is null"); return; } + /* Derive peer multicast addr */ + derived_peer_mc_addr = *peer_mac_addr; + derived_peer_mc_addr.bytes[0] = 0x33; + derived_peer_mc_addr.bytes[1] = 0x33; + derived_peer_mc_addr.bytes[2] = 0xff; qdf_spin_lock_bh(&priv_obj->lock); - if (priv_obj->peer_mc_addr_list) { - cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions); - for (i = 0; i < max_ndp_sessions; i++) { - if (qdf_is_macaddr_equal( - &priv_obj->peer_mc_addr_list[i], - peer_mac_addr)) { - qdf_zero_macaddr( - &priv_obj->peer_mc_addr_list[i]); - priv_obj->num_peer_mc_addr--; - break; - } - } - if (priv_obj->num_peer_mc_addr == 0) { - qdf_mem_free(priv_obj->peer_mc_addr_list); - priv_obj->peer_mc_addr_list = NULL; + cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions); + for (i = 0; i < max_ndp_sessions; i++) { + if (qdf_is_macaddr_equal(&priv_obj->peer_mc_addr_list[i], + &derived_peer_mc_addr)) { + qdf_zero_macaddr(&priv_obj->peer_mc_addr_list[i]); + break; } } qdf_spin_unlock_bh(&priv_obj->lock);