mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 10:51:27 +00:00
343 lines
10 KiB
Diff
343 lines
10 KiB
Diff
From e16e606c956892bda991ffc50dedc85042ddd3ca Mon Sep 17 00:00:00 2001
|
|
From: Maharaja Kennadyrajan <mkenna@codeaurora.org>
|
|
Date: Mon, 4 Jan 2021 23:47:57 +0530
|
|
Subject: [PATCH 2/2] ath11k/mac80211: Add support to account memory stats
|
|
|
|
Memory allocations in the driver & mac80211 are logged
|
|
and populate those values to the user space via debugfs.
|
|
This stats will give the snapshot of the memory being
|
|
used by the driver at the time of dumping these
|
|
memory stats.
|
|
|
|
Command:
|
|
cat /sys/kernel/debug/ath11k/ipq8074\ hw2.0/memory_stats
|
|
|
|
Sample output of the stats
|
|
MEMORY STATS IN BYTES:
|
|
malloc size : 6287583
|
|
ce_ring_alloc size: 109308
|
|
dma_alloc size:: 10831860
|
|
htc_skb_alloc size: 3840
|
|
wmi alloc size: 0
|
|
per peer object: 4644
|
|
rx_post_buf size: 5091840
|
|
Total size: 22329075
|
|
|
|
User can disable/enable the memory stats accounting with
|
|
the below command.
|
|
|
|
echo N > /sys/kernel/debug/ath11k/ipq8074\ hw2.0/enable_memory_stats
|
|
where N = 0 to disable logging, 1 to enable the logging.
|
|
|
|
Note: This should be enabled/disabled only after wifi is down.
|
|
User shouldn't enable/disable when the wifi is up to avoid
|
|
accounting the negative values which cause incorrect values
|
|
in the memory stats.
|
|
|
|
Command:
|
|
cat /sys/kernel/debug/ieee80211/phyX/memory_stats
|
|
memory stats: malloc_size: 108
|
|
|
|
Signed-off-by: Maharaja Kennadyrajan <mkenna@codeaurora.org>
|
|
---
|
|
net/mac80211/chan.c | 12 ++++++++++++
|
|
net/mac80211/debugfs.c | 4 ++++
|
|
net/mac80211/ieee80211_i.h | 6 ++++++
|
|
net/mac80211/iface.c | 5 +++++
|
|
net/mac80211/mesh.c | 4 ++++
|
|
net/mac80211/mesh_hwmp.c | 5 +++++
|
|
net/mac80211/mesh_pathtbl.c | 12 ++++++++++++
|
|
net/mac80211/offchannel.c | 7 +++++++
|
|
net/mac80211/scan.c | 18 ++++++++++++++++++
|
|
net/mac80211/sta_info.c | 16 ++++++++++++++++
|
|
10 files changed, 89 insertions(+)
|
|
|
|
--- a/net/mac80211/chan.c
|
|
+++ b/net/mac80211/chan.c
|
|
@@ -631,6 +631,9 @@ ieee80211_alloc_chanctx(struct ieee80211
|
|
if (!ctx)
|
|
return NULL;
|
|
|
|
+ atomic_add(sizeof(*ctx) + local->hw.chanctx_data_size,
|
|
+ &local->memory_stats.malloc_size);
|
|
+
|
|
INIT_LIST_HEAD(&ctx->assigned_links);
|
|
INIT_LIST_HEAD(&ctx->reserved_links);
|
|
ctx->conf.def = *chandef;
|
|
@@ -691,6 +694,8 @@ ieee80211_new_chanctx(struct ieee80211_l
|
|
|
|
err = ieee80211_add_chanctx(local, ctx);
|
|
if (err) {
|
|
+ atomic_sub(sizeof(*ctx) + local->hw.chanctx_data_size,
|
|
+ &local->memory_stats.malloc_size);
|
|
kfree(ctx);
|
|
return ERR_PTR(err);
|
|
}
|
|
@@ -743,6 +748,8 @@ static void ieee80211_free_chanctx(struc
|
|
|
|
list_del_rcu(&ctx->list);
|
|
ieee80211_del_chanctx(local, ctx);
|
|
+ atomic_sub(sizeof(*ctx) + local->hw.chanctx_data_size,
|
|
+ &local->memory_stats.malloc_size);
|
|
kfree_rcu(ctx, rcu_head);
|
|
}
|
|
|
|
@@ -1420,6 +1427,9 @@ static int ieee80211_chsw_switch_vifs(st
|
|
if (!vif_chsw)
|
|
return -ENOMEM;
|
|
|
|
+ atomic_add(sizeof(vif_chsw[0]) * n_vifs,
|
|
+ &local->memory_stats.malloc_size);
|
|
+
|
|
i = 0;
|
|
list_for_each_entry(ctx, &local->chanctx_list, list) {
|
|
if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
|
|
@@ -1449,6 +1459,8 @@ static int ieee80211_chsw_switch_vifs(st
|
|
CHANCTX_SWMODE_SWAP_CONTEXTS);
|
|
|
|
out:
|
|
+ atomic_sub(sizeof(vif_chsw[0]) * n_vifs,
|
|
+ &local->memory_stats.malloc_size);
|
|
kfree(vif_chsw);
|
|
return err;
|
|
}
|
|
--- a/net/mac80211/debugfs.c
|
|
+++ b/net/mac80211/debugfs.c
|
|
@@ -71,6 +71,8 @@ DEBUGFS_READONLY_FILE(wep_iv, "%#08x",
|
|
local->wep_iv & 0xffffff);
|
|
DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s",
|
|
local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver");
|
|
+DEBUGFS_READONLY_FILE(memory_stats, "memory stats: malloc_size: %u",
|
|
+ atomic_read(&local->memory_stats.malloc_size));
|
|
|
|
static ssize_t aqm_read(struct file *file,
|
|
char __user *user_buf,
|
|
@@ -680,6 +682,8 @@ void debugfs_hw_add(struct ieee80211_loc
|
|
if (!statsd)
|
|
return;
|
|
|
|
+ DEBUGFS_ADD(memory_stats);
|
|
+
|
|
#ifdef CPTCFG_MAC80211_DEBUG_COUNTERS
|
|
DEBUGFS_STATS_ADD(dot11TransmittedFragmentCount);
|
|
DEBUGFS_STATS_ADD(dot11MulticastTransmittedFrameCount);
|
|
--- a/net/mac80211/ieee80211_i.h
|
|
+++ b/net/mac80211/ieee80211_i.h
|
|
@@ -1270,6 +1270,10 @@ enum mac80211_scan_state {
|
|
|
|
DECLARE_STATIC_KEY_FALSE(aql_disable);
|
|
|
|
+struct mac80211_memory_stats {
|
|
+ atomic_t malloc_size;
|
|
+};
|
|
+
|
|
struct ieee80211_local {
|
|
/* embed the driver visible part.
|
|
* don't cast (use the static inlines below), but we keep
|
|
@@ -1555,6 +1559,8 @@ struct ieee80211_local {
|
|
struct ieee80211_sub_if_data __rcu *monitor_sdata;
|
|
struct cfg80211_chan_def monitor_chandef;
|
|
|
|
+ struct mac80211_memory_stats memory_stats;
|
|
+
|
|
/* extended capabilities provided by mac80211 */
|
|
u8 ext_capa[8];
|
|
};
|
|
--- a/net/mac80211/iface.c
|
|
+++ b/net/mac80211/iface.c
|
|
@@ -1365,6 +1365,9 @@ int ieee80211_add_virtual_monitor(struct
|
|
return ret;
|
|
}
|
|
|
|
+ atomic_add(sizeof(*sdata) + local->hw.vif_data_size,
|
|
+ &local->memory_stats.malloc_size);
|
|
+
|
|
skb_queue_head_init(&sdata->skb_queue);
|
|
skb_queue_head_init(&sdata->status_queue);
|
|
INIT_WORK(&sdata->work, ieee80211_iface_work);
|
|
@@ -1402,6 +1405,8 @@ void ieee80211_del_virtual_monitor(struc
|
|
|
|
drv_remove_interface(local, sdata);
|
|
|
|
+ atomic_sub(sizeof(*sdata) + local->hw.vif_data_size,
|
|
+ &local->memory_stats.malloc_size);
|
|
kfree(sdata);
|
|
}
|
|
|
|
--- a/net/mac80211/mesh.c
|
|
+++ b/net/mac80211/mesh.c
|
|
@@ -174,6 +174,8 @@ int mesh_rmc_init(struct ieee80211_sub_i
|
|
sdata->u.mesh.rmc = kmalloc(sizeof(struct mesh_rmc), GFP_KERNEL);
|
|
if (!sdata->u.mesh.rmc)
|
|
return -ENOMEM;
|
|
+ atomic_add(sizeof(struct mesh_rmc),
|
|
+ &sdata->local->memory_stats.malloc_size);
|
|
sdata->u.mesh.rmc->idx_mask = RMC_BUCKETS - 1;
|
|
for (i = 0; i < RMC_BUCKETS; i++)
|
|
INIT_HLIST_HEAD(&sdata->u.mesh.rmc->bucket[i]);
|
|
@@ -197,6 +199,8 @@ void mesh_rmc_free(struct ieee80211_sub_
|
|
}
|
|
}
|
|
|
|
+ atomic_sub(sizeof(struct mesh_rmc),
|
|
+ &sdata->local->memory_stats.malloc_size);
|
|
kfree(rmc);
|
|
sdata->u.mesh.rmc = NULL;
|
|
}
|
|
--- a/net/mac80211/mesh_hwmp.c
|
|
+++ b/net/mac80211/mesh_hwmp.c
|
|
@@ -1006,6 +1006,9 @@ static void mesh_queue_preq(struct mesh_
|
|
return;
|
|
}
|
|
|
|
+ atomic_add(sizeof(struct mesh_preq_queue),
|
|
+ &sdata->local->memory_stats.malloc_size);
|
|
+
|
|
memcpy(preq_node->dst, mpath->dst, ETH_ALEN);
|
|
preq_node->flags = flags;
|
|
|
|
@@ -1120,6 +1123,8 @@ void mesh_path_start_discovery(struct ie
|
|
|
|
enddiscovery:
|
|
rcu_read_unlock();
|
|
+ atomic_sub(sizeof(struct mesh_preq_queue),
|
|
+ &sdata->local->memory_stats.malloc_size);
|
|
kfree(preq_node);
|
|
}
|
|
|
|
--- a/net/mac80211/offchannel.c
|
|
+++ b/net/mac80211/offchannel.c
|
|
@@ -170,6 +170,7 @@ void ieee80211_offchannel_return(struct
|
|
|
|
static void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
|
|
{
|
|
+ struct ieee80211_sub_if_data *sdata = roc->sdata;
|
|
/* was never transmitted */
|
|
if (roc->frame) {
|
|
cfg80211_mgmt_tx_status(&roc->sdata->wdev, roc->mgmt_tx_cookie,
|
|
@@ -188,6 +189,8 @@ static void ieee80211_roc_notify_destroy
|
|
roc->chan, GFP_KERNEL);
|
|
|
|
list_del(&roc->list);
|
|
+ atomic_sub(sizeof(*roc),
|
|
+ &sdata->local->memory_stats.malloc_size);
|
|
kfree(roc);
|
|
}
|
|
|
|
@@ -550,6 +553,8 @@ static int ieee80211_start_roc_work(stru
|
|
if (!roc)
|
|
return -ENOMEM;
|
|
|
|
+ atomic_add(sizeof(*roc), &local->memory_stats.malloc_size);
|
|
+
|
|
/*
|
|
* If the duration is zero, then the driver
|
|
* wouldn't actually do anything. Set it to
|
|
@@ -595,6 +600,8 @@ static int ieee80211_start_roc_work(stru
|
|
ret = drv_remain_on_channel(local, sdata, channel,
|
|
duration, type);
|
|
if (ret) {
|
|
+ atomic_sub(sizeof(*roc),
|
|
+ &local->memory_stats.malloc_size);
|
|
kfree(roc);
|
|
return ret;
|
|
}
|
|
--- a/net/mac80211/scan.c
|
|
+++ b/net/mac80211/scan.c
|
|
@@ -469,6 +469,12 @@ static void __ieee80211_scan_completed(s
|
|
scan_req = rcu_dereference_protected(local->scan_req,
|
|
lockdep_is_held(&local->mtx));
|
|
|
|
+ atomic_sub(sizeof(*local->hw_scan_req) +
|
|
+ scan_req->n_channels *
|
|
+ sizeof(scan_req->channels[0]) +
|
|
+ local->hw_scan_ies_bufsize,
|
|
+ &local->memory_stats.malloc_size);
|
|
+
|
|
if (scan_req != local->int_scan_req) {
|
|
local->scan_info.aborted = aborted;
|
|
cfg80211_scan_done(scan_req, &local->scan_info);
|
|
@@ -738,6 +744,12 @@ static int __ieee80211_start_scan(struct
|
|
if (!local->hw_scan_req)
|
|
return -ENOMEM;
|
|
|
|
+ atomic_add(sizeof(*local->hw_scan_req) +
|
|
+ req->n_channels *
|
|
+ sizeof(req->channels[0]) +
|
|
+ local->hw_scan_ies_bufsize,
|
|
+ &local->memory_stats.malloc_size);
|
|
+
|
|
local->hw_scan_req->req.chandef = req->chandef;
|
|
local->hw_scan_req->req.ssids = req->ssids;
|
|
local->hw_scan_req->req.n_ssids = req->n_ssids;
|
|
@@ -829,6 +841,12 @@ static int __ieee80211_start_scan(struct
|
|
}
|
|
|
|
if (rc) {
|
|
+ atomic_sub(sizeof(*local->hw_scan_req) +
|
|
+ req->n_channels *
|
|
+ sizeof(req->channels[0]) +
|
|
+ local->hw_scan_ies_bufsize,
|
|
+ &local->memory_stats.malloc_size);
|
|
+
|
|
kfree(local->hw_scan_req);
|
|
local->hw_scan_req = NULL;
|
|
local->scanning = 0;
|
|
--- a/net/mac80211/sta_info.c
|
|
+++ b/net/mac80211/sta_info.c
|
|
@@ -354,6 +354,7 @@ static void sta_remove_link(struct sta_i
|
|
*/
|
|
void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
|
|
{
|
|
+ struct ieee80211_hw *hw = &local->hw;
|
|
int i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(sta->link); i++) {
|
|
@@ -390,9 +391,13 @@ void sta_info_free(struct ieee80211_loca
|
|
kfree(to_txq_info(sta->sta.txq[0]));
|
|
kfree(rcu_dereference_raw(sta->sta.rates));
|
|
#ifdef CPTCFG_MAC80211_MESH
|
|
+ if (sta->mesh)
|
|
+ atomic_sub(sizeof(*sta->mesh),
|
|
+ &local->memory_stats.malloc_size);
|
|
kfree(sta->mesh);
|
|
#endif
|
|
-
|
|
+ atomic_sub(sizeof(*sta) + hw->sta_data_size,
|
|
+ &local->memory_stats.malloc_size);
|
|
sta_info_free_link(&sta->deflink);
|
|
kfree(sta);
|
|
}
|
|
@@ -493,6 +498,9 @@ __sta_info_alloc(struct ieee80211_sub_if
|
|
sta->local = local;
|
|
sta->sdata = sdata;
|
|
|
|
+ atomic_add(sizeof(*sta) + hw->sta_data_size,
|
|
+ &local->memory_stats.malloc_size);
|
|
+
|
|
if (sta_info_alloc_link(local, &sta->deflink, gfp))
|
|
return NULL;
|
|
|
|
@@ -514,6 +522,8 @@ __sta_info_alloc(struct ieee80211_sub_if
|
|
sta->mesh = kzalloc(sizeof(*sta->mesh), gfp);
|
|
if (!sta->mesh)
|
|
goto free;
|
|
+ atomic_add(sizeof(*sta->mesh),
|
|
+ &local->memory_stats.malloc_size);
|
|
sta->mesh->plink_sta = sta;
|
|
spin_lock_init(&sta->mesh->plink_lock);
|
|
if (!sdata->u.mesh.user_mpm)
|
|
@@ -645,8 +655,12 @@ free_txq:
|
|
free:
|
|
sta_info_free_link(&sta->deflink);
|
|
#ifdef CPTCFG_MAC80211_MESH
|
|
+ atomic_sub(sizeof(*sta->mesh),
|
|
+ &local->memory_stats.malloc_size);
|
|
kfree(sta->mesh);
|
|
#endif
|
|
+ atomic_sub(sizeof(*sta) + hw->sta_data_size,
|
|
+ &local->memory_stats.malloc_size);
|
|
kfree(sta);
|
|
return NULL;
|
|
}
|