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
This commit is contained in:

committad av
Madan Koyyalamudi

förälder
71f5251684
incheckning
6058846058
@@ -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];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -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
|
||||
|
||||
/*
|
||||
* <ini>
|
||||
* 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")
|
||||
|
@@ -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);
|
||||
|
Referens i nytt ärende
Block a user