wlan-ap-Telecominfraproject/feeds/wifi-ax/mac80211/patches/qca/233-001-ath11k-add-support-memory-stats.patch
John Crispin 43d7ca31d6 wifi-ax/mac80211: make the 11.4 ath11k work inside the v5.4 kernel
Fixes: WIFI-7570
Signed-off-by: John Crispin <john@phrozen.org>
2022-05-27 10:05:52 +02:00

982 lines
29 KiB
Diff

From 9c99e124a279391dbe2cef66226fd4e86bde8f4d Mon Sep 17 00:00:00 2001
From: Maharaja Kennadyrajan <mkenna@codeaurora.org>
Date: Mon, 4 Jan 2021 23:46:53 +0530
Subject: [PATCH 1/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>
---
drivers/net/wireless/ath/ath11k/ce.c | 24 ++++
drivers/net/wireless/ath/ath11k/core.c | 2 +-
drivers/net/wireless/ath/ath11k/core.h | 19 +++
drivers/net/wireless/ath/ath11k/coredump.c | 15 ++-
drivers/net/wireless/ath/ath11k/dbring.c | 3 +
drivers/net/wireless/ath/ath11k/debugfs.c | 115 ++++++++++++++++++
drivers/net/wireless/ath/ath11k/debugfs.h | 29 +++++
drivers/net/wireless/ath/ath11k/debugfs_sta.c | 4 +
drivers/net/wireless/ath/ath11k/dp.c | 13 ++
drivers/net/wireless/ath/ath11k/hal.c | 6 +
drivers/net/wireless/ath/ath11k/htc.c | 5 +
drivers/net/wireless/ath/ath11k/mac.c | 15 ++-
drivers/net/wireless/ath/ath11k/nss.c | 46 +++++++
drivers/net/wireless/ath/ath11k/peer.c | 5 +
drivers/net/wireless/ath/ath11k/wmi.c | 4 +
15 files changed, 302 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/ath/ath11k/ce.c
+++ b/drivers/net/wireless/ath/ath11k/ce.c
@@ -357,6 +357,9 @@ static int ath11k_ce_rx_post_pipe(struct
dev_kfree_skb_any(skb);
goto exit;
}
+
+ ATH11K_MEMORY_STATS_INC(ab, ce_rx_pipe, skb->truesize);
+
}
exit:
@@ -425,6 +428,9 @@ static void ath11k_ce_recv_process_cb(st
__skb_queue_head_init(&list);
while (ath11k_ce_completed_recv_next(pipe, &skb, &nbytes) == 0) {
max_nbytes = skb->len + skb_tailroom(skb);
+
+ ATH11K_MEMORY_STATS_DEC(ab, ce_rx_pipe, skb->truesize);
+
dma_unmap_single(ab->dev, ATH11K_SKB_RXCB(skb)->paddr,
max_nbytes, DMA_FROM_DEVICE);
@@ -618,6 +624,9 @@ ath11k_ce_alloc_ring(struct ath11k_base
if (ce_ring == NULL)
return ERR_PTR(-ENOMEM);
+ ATH11K_MEMORY_STATS_INC(ab, ce_ring_alloc,
+ struct_size(ce_ring, skb, nentries));
+
ce_ring->nentries = nentries;
ce_ring->nentries_mask = nentries - 1;
@@ -633,6 +642,9 @@ ath11k_ce_alloc_ring(struct ath11k_base
return ERR_PTR(-ENOMEM);
}
+ ATH11K_MEMORY_STATS_INC(ab, ce_ring_alloc,
+ nentries * desc_sz + CE_DESC_RING_ALIGN);
+
ce_ring->base_addr_ce_space_unaligned = base_addr;
ce_ring->base_addr_owner_space = PTR_ALIGN(
@@ -812,6 +824,9 @@ static void ath11k_ce_rx_pipe_cleanup(st
continue;
ring->skb[i] = NULL;
+
+ ATH11K_MEMORY_STATS_DEC(ab, ce_rx_pipe, skb->truesize);
+
dma_unmap_single(ab->dev, ATH11K_SKB_RXCB(skb)->paddr,
skb->len + skb_tailroom(skb), DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
@@ -991,6 +1006,9 @@ void ath11k_ce_free_pipes(struct ath11k_
CE_DESC_RING_ALIGN,
pipe->src_ring->base_addr_owner_space,
pipe->src_ring->base_addr_ce_space);
+ ATH11K_MEMORY_STATS_DEC(ab, ce_ring_alloc,
+ pipe->src_ring->nentries * desc_sz +
+ CE_DESC_RING_ALIGN);
kfree(pipe->src_ring);
pipe->src_ring = NULL;
}
@@ -1002,6 +1020,9 @@ void ath11k_ce_free_pipes(struct ath11k_
CE_DESC_RING_ALIGN,
pipe->dest_ring->base_addr_owner_space,
pipe->dest_ring->base_addr_ce_space);
+ ATH11K_MEMORY_STATS_DEC(ab, ce_ring_alloc,
+ pipe->dest_ring->nentries * desc_sz +
+ CE_DESC_RING_ALIGN);
kfree(pipe->dest_ring);
pipe->dest_ring = NULL;
}
@@ -1014,6 +1035,9 @@ void ath11k_ce_free_pipes(struct ath11k_
CE_DESC_RING_ALIGN,
pipe->status_ring->base_addr_owner_space,
pipe->status_ring->base_addr_ce_space);
+ ATH11K_MEMORY_STATS_DEC(ab, ce_ring_alloc,
+ pipe->status_ring->nentries * desc_sz +
+ CE_DESC_RING_ALIGN);
kfree(pipe->status_ring);
pipe->status_ring = NULL;
}
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -1353,6 +1353,8 @@ int ath11k_core_pre_init(struct ath11k_b
if (nss_offload)
ab->nss.stats_enabled = 1;
+ ab->enable_memory_stats = ATH11K_DEBUG_ENABLE_MEMORY_STATS;
+
return 0;
}
EXPORT_SYMBOL(ath11k_core_pre_init);
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -801,6 +801,23 @@ struct ath11k_internal_pci {
wait_queue_head_t qgic_msi_waitq;
};
+struct ath11k_memory_stats {
+ /* Account kzalloc and valloc */
+ atomic_t malloc_size;
+ /* Account dma_alloc in dp.c & hal.c */
+ atomic_t dma_alloc;
+ /* Account memory used in ce rings */
+ atomic_t ce_ring_alloc;
+ /* Account memory used in htc_send */
+ atomic_t htc_skb_alloc;
+ /* Account memory used in wmi tx skb alloc */
+ atomic_t wmi_tx_skb_alloc;
+ /* Account memory consumed for peer object */
+ atomic_t per_peer_object;
+ /* Account memory used in ce rx pipe */
+ atomic_t ce_rx_pipe;
+};
+
/* Master structure to hold the hw data which may be used in core module */
struct ath11k_base {
enum ath11k_hw_rev hw_rev;
@@ -878,6 +895,7 @@ struct ath11k_base {
enum ath11k_dfs_region dfs_region;
#ifdef CPTCFG_ATH11K_DEBUGFS
struct dentry *debugfs_soc;
+ struct ath11k_memory_stats memory_stats;
#endif
struct ath11k_soc_dp_stats soc_stats;
@@ -916,6 +934,7 @@ struct ath11k_base {
struct ath11k_num_vdevs_peers *num_vdevs_peers;
int userpd_id;
struct ath11k_internal_pci ipci;
+ bool enable_memory_stats;
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
--- a/drivers/net/wireless/ath/ath11k/coredump.c
+++ b/drivers/net/wireless/ath/ath11k/coredump.c
@@ -109,6 +109,8 @@ void ath11k_coredump_build_inline(struct
if (!buf)
return;
+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, header_size);
+
file_data = (struct ath11k_dump_file_data *)buf;
strlcpy(file_data->df_magic, "ATH11K-FW-DUMP",
sizeof(file_data->df_magic));
@@ -132,8 +134,10 @@ void ath11k_coredump_build_inline(struct
memcpy(file_data->seg, segments, num_seg * sizeof(*segments));
dump_state = vzalloc(sizeof(*dump_state));
- if(!dump_state)
+ if(!dump_state) {
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, header_size);
return;
+ }
dump_state->header = file_data;
dump_state->num_seg = num_seg;
@@ -145,6 +149,8 @@ void ath11k_coredump_build_inline(struct
/* Wait until the dump is read and free is called */
wait_for_completion(&dump_state->dump_done);
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(*dump_state));
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, header_size);
vfree(dump_state);
vfree(file_data);
}
@@ -274,14 +280,19 @@ void ath11k_coredump_qdss_dump(struct at
return;
}
+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, len);
+
if (event_data->total_size &&
event_data->total_size <= ab->qmi.qdss_mem[0].size)
dump = vzalloc(event_data->total_size);
if (!dump) {
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, len);
vfree(segment);
return;
}
+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, event_data->total_size);
+
if (num_seg == 1) {
segment->len = event_data->mem_seg[0].size;
segment->vaddr = ab->qmi.qdss_mem[0].vaddr;
@@ -339,6 +350,8 @@ void ath11k_coredump_qdss_dump(struct at
}
ath11k_coredump_build_inline(ar_pci, segment, 1);
out:
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, event_data->total_size);
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, len);
vfree(segment);
vfree(dump);
}
--- a/drivers/net/wireless/ath/ath11k/dbring.c
+++ b/drivers/net/wireless/ath/ath11k/dbring.c
@@ -104,6 +104,7 @@ static int ath11k_dbring_fill_bufs(struc
break;
}
num_remain--;
+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, size);
}
spin_unlock_bh(&srng->lock);
@@ -348,6 +349,8 @@ void ath11k_dbring_buf_cleanup(struct at
idr_remove(&ring->bufs_idr, buf_id);
dma_unmap_single(ar->ab->dev, buff->paddr,
ring->buf_sz, DMA_FROM_DEVICE);
+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, sizeof(*buff) +
+ ring->buf_sz + ring->buf_align - 1);
kfree(buff);
}
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
@@ -1358,6 +1358,8 @@ static ssize_t ath11k_debugfs_dump_soc_d
if (!buf)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, size);
+
len += scnprintf(buf + len, size - len, "SOC RX STATS:\n\n");
len += scnprintf(buf + len, size - len, "err ring pkts: %u\n",
soc_stats->err_ring_pkts);
@@ -1399,6 +1401,8 @@ static ssize_t ath11k_debugfs_dump_soc_d
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, size);
+
return retval;
}
@@ -1476,6 +1480,106 @@ static const struct file_operations fops
.open = simple_open,
};
+static ssize_t
+ath11k_debug_read_enable_memory_stats(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k_base *ab = file->private_data;
+ char buf[10];
+ size_t len;
+
+ len = scnprintf(buf, sizeof(buf), "%d\n", ab->enable_memory_stats);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t
+ath11k_debug_write_enable_memory_stats(struct file *file,
+ char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k_base *ab = file->private_data;
+ bool enable;
+ int ret;
+
+ if (kstrtobool_from_user(ubuf, count, &enable))
+ return -EINVAL;
+
+ if (enable == ab->enable_memory_stats) {
+ ret = count;
+ goto exit;
+ }
+
+ ab->enable_memory_stats = enable;
+ ret = count;
+exit:
+ return ret;
+}
+
+static const struct file_operations fops_enable_memory_stats = {
+ .read = ath11k_debug_read_enable_memory_stats,
+ .write = ath11k_debug_write_enable_memory_stats,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+ .open = simple_open,
+};
+
+static ssize_t ath11k_debug_dump_memory_stats(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k_base *ab = file->private_data;
+ struct ath11k_memory_stats *memory_stats = &ab->memory_stats;
+ int len = 0, retval;
+ const int size = 4096;
+
+ char *buf;
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ len += scnprintf(buf + len, size - len, "MEMORY STATS IN BYTES:\n");
+ len += scnprintf(buf + len, size - len, "malloc size : %u\n",
+ atomic_read(&memory_stats->malloc_size));
+ len += scnprintf(buf + len, size - len, "ce_ring_alloc size: %u\n",
+ atomic_read(&memory_stats->ce_ring_alloc));
+ len += scnprintf(buf + len, size - len, "dma_alloc size:: %u\n",
+ atomic_read(&memory_stats->dma_alloc));
+ len += scnprintf(buf + len, size - len, "htc_skb_alloc size: %u\n",
+ atomic_read(&memory_stats->htc_skb_alloc));
+ len += scnprintf(buf + len, size - len, "wmi tx skb alloc size: %u\n",
+ atomic_read(&memory_stats->wmi_tx_skb_alloc));
+ len += scnprintf(buf + len, size - len, "per peer object: %u\n",
+ atomic_read(&memory_stats->per_peer_object));
+ len += scnprintf(buf + len, size - len, "rx_post_buf size: %u\n",
+ atomic_read(&memory_stats->ce_rx_pipe));
+ len += scnprintf(buf + len, size - len, "Total size: %u\n\n",
+ (atomic_read(&memory_stats->malloc_size) +
+ atomic_read(&memory_stats->ce_ring_alloc) +
+ atomic_read(&memory_stats->dma_alloc) +
+ atomic_read(&memory_stats->htc_skb_alloc) +
+ atomic_read(&memory_stats->wmi_tx_skb_alloc) +
+ atomic_read(&memory_stats->per_peer_object) +
+ atomic_read(&memory_stats->ce_rx_pipe)));
+
+ if (len > size)
+ len = size;
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return retval;
+}
+
+static const struct file_operations fops_memory_stats = {
+ .read = ath11k_debug_dump_memory_stats,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
{
if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
@@ -1639,6 +1743,12 @@ static ssize_t ath11k_write_pktlog_filte
}
}
+ debugfs_create_file("enable_memory_stats", 0600, ab->debugfs_soc,
+ ab, &fops_enable_memory_stats);
+
+ debugfs_create_file("memory_stats", 0600, ab->debugfs_soc, ab,
+ &fops_memory_stats);
+
#define HTT_RX_FILTER_TLV_LITE_MODE \
(HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
@@ -2225,6 +2335,8 @@ static ssize_t ath11k_dump_mgmt_stats(st
if (!buf)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, size);
+
mutex_lock(&ar->conf_mutex);
spin_lock_bh(&ar->data_lock);
@@ -2275,6 +2387,9 @@ static ssize_t ath11k_dump_mgmt_stats(st
ret = simple_read_from_buffer(ubuf, count, ppos, buf, len);
mutex_unlock(&ar->conf_mutex);
kfree(buf);
+
+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, size);
+
return ret;
}
--- a/drivers/net/wireless/ath/ath11k/debugfs.h
+++ b/drivers/net/wireless/ath/ath11k/debugfs.h
@@ -10,6 +10,7 @@
#define ATH11K_TX_POWER_MAX_VAL 70
#define ATH11K_TX_POWER_MIN_VAL 0
+#define ATH11K_DEBUG_ENABLE_MEMORY_STATS 1
/* htt_dbg_ext_stats_type */
enum ath11k_dbg_htt_ext_stats_type {
@@ -163,6 +164,24 @@ void ath11k_debugfs_wmi_ctrl_stats(struc
void ath11k_wmi_crl_path_stats_list_free(struct list_head *head);
#ifdef CPTCFG_ATH11K_DEBUGFS
+#define ATH11K_MEMORY_STATS_INC(_struct, _field, _size) \
+do { \
+ if (ath11k_debug_is_memory_stats_enabled(_struct)) \
+ atomic_add(_size, &_struct->memory_stats._field); \
+} while(0)
+
+#define ATH11K_MEMORY_STATS_DEC(_struct, _field, _size) \
+do { \
+ if (ath11k_debug_is_memory_stats_enabled(_struct)) \
+ atomic_sub(_size, &_struct->memory_stats._field); \
+} while(0)
+
+#else
+#define ATH11K_MEMORY_STATS_INC(_struct, _field, _size)
+#define ATH11K_MEMORY_STATS_DEC(_struct, _field, _size)
+#endif
+
+#ifdef CPTCFG_ATH11K_DEBUGFS
int ath11k_debugfs_create(void);
void ath11k_debugfs_destroy(void);
int ath11k_debugfs_soc_create(struct ath11k_base *ab);
@@ -208,6 +227,11 @@ static inline int ath11k_debugfs_rx_filt
return ar->debug.rx_filter;
}
+static inline int ath11k_debug_is_memory_stats_enabled(struct ath11k_base *ab)
+{
+ return ab->enable_memory_stats;
+}
+
#else
static inline int ath11k_debugfs_create(void)
{
@@ -285,6 +309,11 @@ static inline bool ath11k_debugfs_is_pkt
return false;
}
+static inline int ath11k_debug_is_memory_stats_enabled(struct ath11k_base *ab)
+{
+ return 0;
+}
+
static inline int ath11k_debugfs_rx_filter(struct ath11k *ar)
{
return 0;
--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
@@ -492,6 +492,8 @@ static ssize_t ath11k_dbg_sta_dump_rx_st
if (!buf)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, size);
+
he_rates_avail = (rx_stats->pream_cnt[HAL_RX_PREAMBLE_11AX] > 1) ? 1 : 0;
rate_table_len = he_rates_avail ? ATH11K_RX_RATE_TABLE_11AX_NUM :
ATH11K_RX_RATE_TABLE_NUM;
@@ -636,6 +638,8 @@ static ssize_t ath11k_dbg_sta_dump_rx_st
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, size);
+
mutex_unlock(&ar->conf_mutex);
return retval;
}
--- a/drivers/net/wireless/ath/ath11k/dp.c
+++ b/drivers/net/wireless/ath/ath11k/dp.c
@@ -109,6 +109,8 @@ void ath11k_dp_srng_cleanup(struct ath11
dma_free_coherent(ab->dev, ring->size, ring->vaddr_unaligned,
ring->paddr_unaligned);
+ ATH11K_MEMORY_STATS_DEC(ab, dma_alloc, ring->size);
+
ring->vaddr_unaligned = NULL;
}
@@ -253,6 +255,8 @@ int ath11k_dp_srng_setup(struct ath11k_b
if (!ring->vaddr_unaligned)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ab, dma_alloc, ring->size);
+
ring->vaddr = PTR_ALIGN(ring->vaddr_unaligned, HAL_RING_BASE_ALIGN);
ring->paddr = ring->paddr_unaligned + ((unsigned long)ring->vaddr -
(unsigned long)ring->vaddr_unaligned);
@@ -485,6 +489,7 @@ static void ath11k_dp_scatter_idle_link_
dma_free_coherent(ab->dev, HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX,
slist[i].vaddr, slist[i].paddr);
slist[i].vaddr = NULL;
+ ATH11K_MEMORY_STATS_DEC(ab, dma_alloc, HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX);
}
}
@@ -522,6 +527,7 @@ static int ath11k_dp_scatter_idle_link_d
ret = -ENOMEM;
goto err;
}
+ ATH11K_MEMORY_STATS_INC(ab, dma_alloc, HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX);
}
scatter_idx = 0;
@@ -576,6 +582,7 @@ ath11k_dp_link_desc_bank_free(struct ath
link_desc_banks[i].vaddr_unaligned,
link_desc_banks[i].paddr_unaligned);
link_desc_banks[i].vaddr_unaligned = NULL;
+ ATH11K_MEMORY_STATS_DEC(ab, dma_alloc, link_desc_banks[i].size);
}
}
}
@@ -609,6 +616,7 @@ static int ath11k_dp_link_desc_bank_allo
((unsigned long)desc_bank[i].vaddr -
(unsigned long)desc_bank[i].vaddr_unaligned);
desc_bank[i].size = desc_sz;
+ ATH11K_MEMORY_STATS_INC(ab, dma_alloc, desc_bank[i].size);
}
return 0;
@@ -1023,8 +1031,11 @@ static int ath11k_dp_tx_pending_cleanup(
void ath11k_dp_free(struct ath11k_base *ab)
{
struct ath11k_dp *dp = &ab->dp;
+ size_t size = 0;
int i;
+ size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE;
+
ath11k_dp_link_desc_cleanup(ab, dp->link_desc_banks,
HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring);
@@ -1038,6 +1049,7 @@ void ath11k_dp_free(struct ath11k_base *
ath11k_dp_tx_pending_cleanup, ab);
idr_destroy(&dp->tx_ring[i].txbuf_idr);
spin_unlock_bh(&dp->tx_ring[i].tx_idr_lock);
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, size);
kfree(dp->tx_ring[i].tx_status);
}
@@ -1095,6 +1107,7 @@ int ath11k_dp_alloc(struct ath11k_base *
ret = -ENOMEM;
goto fail_cmn_srng_cleanup;
}
+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, size);
}
for (i = 0; i < HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX; i++)
--- a/drivers/net/wireless/ath/ath11k/hal.c
+++ b/drivers/net/wireless/ath/ath11k/hal.c
@@ -200,6 +200,8 @@ static int ath11k_hal_alloc_cont_rdp(str
if (!hal->rdp.vaddr)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ab, dma_alloc, size);
+
return 0;
}
@@ -214,6 +216,7 @@ static void ath11k_hal_free_cont_rdp(str
size = sizeof(u32) * HAL_SRNG_RING_ID_MAX;
dma_free_coherent(ab->dev, size,
hal->rdp.vaddr, hal->rdp.paddr);
+ ATH11K_MEMORY_STATS_DEC(ab, dma_alloc, size);
hal->rdp.vaddr = NULL;
}
@@ -228,6 +231,8 @@ static int ath11k_hal_alloc_cont_wrp(str
if (!hal->wrp.vaddr)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ab, dma_alloc, size);
+
return 0;
}
@@ -242,6 +247,7 @@ static void ath11k_hal_free_cont_wrp(str
size = sizeof(u32) * HAL_SRNG_NUM_LMAC_RINGS;
dma_free_coherent(ab->dev, size,
hal->wrp.vaddr, hal->wrp.paddr);
+ ATH11K_MEMORY_STATS_DEC(ab, dma_alloc, size);
hal->wrp.vaddr = NULL;
}
--- a/drivers/net/wireless/ath/ath11k/htc.c
+++ b/drivers/net/wireless/ath/ath11k/htc.c
@@ -28,6 +28,7 @@ struct sk_buff *ath11k_htc_alloc_skb(str
static void ath11k_htc_control_tx_complete(struct ath11k_base *ab,
struct sk_buff *skb)
{
+ ATH11K_MEMORY_STATS_DEC(ab, htc_skb_alloc, skb->truesize);
kfree_skb(skb);
}
@@ -650,6 +651,8 @@ int ath11k_htc_connect_service(struct at
return status;
}
+ ATH11K_MEMORY_STATS_INC(ab, htc_skb_alloc, skb->truesize);
+
/* wait for response */
time_left = wait_for_completion_timeout(&htc->ctl_resp,
ATH11K_HTC_CONN_SVC_TIMEOUT_HZ);
@@ -773,6 +776,8 @@ int ath11k_htc_start(struct ath11k_htc *
return status;
}
+ ATH11K_MEMORY_STATS_INC(ab, htc_skb_alloc, skb->truesize);
+
return 0;
}
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -3535,6 +3535,8 @@ static int ath11k_mac_op_hw_scan(struct
goto exit;
}
+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, sizeof(*arg));
+
ath11k_wmi_start_scan_init(ar, arg);
arg->vdev_id = arvif->vdev_id;
arg->scan_id = ATH11K_SCAN_ID;
@@ -3546,6 +3548,8 @@ static int ath11k_mac_op_hw_scan(struct
memcpy(arg->extraie.ptr, req->ie, req->ie_len);
}
+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, req->ie_len);
+
if (req->n_ssids) {
arg->num_ssids = req->n_ssids;
for (i = 0; i < arg->num_ssids; i++) {
@@ -3597,8 +3601,13 @@ static int ath11k_mac_op_hw_scan(struct
exit:
if (arg) {
- if (arg->extraie.ptr)
+ if (arg->extraie.ptr) {
+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, req->ie_len);
kfree(arg->extraie.ptr);
+ }
+
+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, sizeof(*arg));
+
kfree(arg);
}
@@ -6770,6 +6779,8 @@ ath11k_mac_update_active_vif_chan(struct
if (!arg.vifs)
return;
+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, sizeof(arg.vifs[0]));
+
ieee80211_iterate_active_interfaces_atomic(ar->hw,
IEEE80211_IFACE_ITER_NORMAL,
ath11k_mac_change_chanctx_fill_iter,
@@ -6777,6 +6788,8 @@ ath11k_mac_update_active_vif_chan(struct
ath11k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, sizeof(arg.vifs[0]));
+
kfree(arg.vifs);
}
--- a/drivers/net/wireless/ath/ath11k/nss.c
+++ b/drivers/net/wireless/ath/ath11k/nss.c
@@ -876,6 +876,8 @@ int ath11k_nss_vdev_set_cmd(struct ath11
if (!vdev_msg)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, sizeof(*vdev_msg));
+
/* TODO: Convert to function for conversion in case of many
* such commands
*/
@@ -906,6 +908,7 @@ int ath11k_nss_vdev_set_cmd(struct ath11
ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev set cmd success cmd:%d val:%d\n",
cmd, val);
free:
+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, sizeof(*vdev_msg));
kfree(vdev_msg);
return status;
}
@@ -922,6 +925,9 @@ static int ath11k_nss_vdev_configure(str
if (!vdev_msg)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size,
+ sizeof(struct nss_wifi_vdev_msg));
+
vdev_cfg = &vdev_msg->msg.vdev_config;
vdev_cfg->radio_ifnum = ar->nss.if_num;
@@ -957,6 +963,8 @@ static int ath11k_nss_vdev_configure(str
ret = 0;
free:
+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size,
+ sizeof(struct nss_wifi_vdev_msg));
kfree(vdev_msg);
return ret;
@@ -1180,6 +1188,9 @@ int ath11k_nss_vdev_up(struct ath11k_vif
if (!vdev_msg)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size,
+ sizeof(struct nss_wifi_vdev_msg));
+
vdev_en = &vdev_msg->msg.vdev_enable;
ether_addr_copy(vdev_en->mac_addr, arvif->vif->addr);
@@ -1198,6 +1209,8 @@ int ath11k_nss_vdev_up(struct ath11k_vif
ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev up tx msg success\n");
free:
+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size,
+ sizeof(struct nss_wifi_vdev_msg));
kfree(vdev_msg);
return ret;
}
@@ -1220,6 +1233,8 @@ int ath11k_nss_vdev_down(struct ath11k_v
if (!vdev_msg)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size,
+ sizeof(struct nss_wifi_vdev_msg));
nss_wifi_vdev_msg_init(vdev_msg, arvif->nss.if_num,
NSS_WIFI_VDEV_INTERFACE_DOWN_MSG,
sizeof(struct nss_wifi_vdev_disable_msg),
@@ -1234,6 +1249,8 @@ int ath11k_nss_vdev_down(struct ath11k_v
ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev down tx msg success\n");
free:
+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size,
+ sizeof(struct nss_wifi_vdev_msg));
kfree(vdev_msg);
return ret;
}
@@ -1257,6 +1274,9 @@ int ath11k_nss_set_peer_sec_type(struct
if (!wlmsg)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size,
+ sizeof(struct nss_wifili_msg));
+
sec_msg = &wlmsg->msg.securitymsg;
sec_msg->peer_id = peer->peer_id;
@@ -1288,6 +1308,8 @@ int ath11k_nss_set_peer_sec_type(struct
ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss peer id %d security cfg complete\n",
peer->peer_id);
free:
+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size,
+ sizeof(struct nss_wifili_msg));
kfree(wlmsg);
return status;
}
@@ -1886,6 +1908,7 @@ static void ath11k_nss_tx_desc_mem_free(
ab->nss.tx_desc_vaddr[i],
ab->nss.tx_desc_paddr[i]);
ab->nss.tx_desc_vaddr[i] = NULL;
+ ATH11K_MEMORY_STATS_DEC(ab, dma_alloc, ab->nss.tx_desc_size[i]);
}
ath11k_dbg(ab, ATH11K_DBG_NSS, "allocated tx desc mem freed\n");
@@ -1917,6 +1940,8 @@ static int ath11k_nss_tx_desc_mem_alloc(
ab->nss.tx_desc_size[curr_page_idx] = alloc_size;
curr_page_idx++;
+ ATH11K_MEMORY_STATS_INC(ab, dma_alloc, alloc_size);
+
ath11k_dbg(ab, ATH11K_DBG_NSS,
"curr page %d, allocated %d, total allocated %d\n",
curr_page_idx, alloc_size, i + alloc_size);
@@ -2093,6 +2118,8 @@ static int ath11k_nss_init(struct ath11k
if (!wlmsg)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, sizeof(struct nss_wifili_msg));
+
wim = &wlmsg->msg.init;
wim->target_type = target_type;
@@ -2211,6 +2238,7 @@ unregister:
nss_unregister_wifili_if(ab->nss.if_num);
free:
ath11k_nss_tx_desc_mem_free(ab);
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg));
kfree(wlmsg);
return -EINVAL;
}
@@ -2316,6 +2344,8 @@ int ath11k_nss_pdev_init(struct ath11k_b
goto unregister;
}
+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, sizeof(struct nss_wifili_msg));
+
pdevmsg = &wlmsg->msg.pdevmsg;
pdevmsg->radio_id = radio_id;
@@ -2361,6 +2391,8 @@ int ath11k_nss_pdev_init(struct ath11k_b
goto free;
}
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg));
+
kfree(wlmsg);
/* Disable nss sojourn stats by default */
@@ -2379,6 +2411,7 @@ int ath11k_nss_pdev_init(struct ath11k_b
return 0;
free:
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg));
kfree(wlmsg);
unregister:
nss_unregister_wifili_radio_if(ar->nss.if_num);
@@ -2401,6 +2434,8 @@ int ath11k_nss_start(struct ath11k_base
if (!wlmsg)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, sizeof(struct nss_wifili_msg));
+
msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive;
/* Empty message for NSS Start message */
@@ -2441,6 +2476,7 @@ int ath11k_nss_start(struct ath11k_base
ath11k_dbg(ab, ATH11K_DBG_NSS, "nss start success\n");
free:
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg));
kfree(wlmsg);
return ret;
}
@@ -2459,6 +2495,8 @@ static void ath11k_nss_reset(struct ath1
return;
}
+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, sizeof(struct nss_wifili_msg));
+
msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive;
/* Empty message for NSS Reset message */
@@ -2497,6 +2535,7 @@ static void ath11k_nss_reset(struct ath1
nss_unregister_wifili_if(ab->nss.if_num);
free:
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg));
kfree(wlmsg);
}
@@ -2512,6 +2551,8 @@ static int ath11k_nss_stop(struct ath11k
if (!wlmsg)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, sizeof(struct nss_wifili_msg));
+
msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive;
/* Empty message for Stop command */
@@ -2551,6 +2592,8 @@ static int ath11k_nss_stop(struct ath11k
/* NSS Stop success */
ret = 0;
free:
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg));
+
kfree(wlmsg);
return ret;
}
@@ -2576,6 +2619,8 @@ int ath11k_nss_pdev_deinit(struct ath11k
if (!wlmsg)
return -ENOMEM;
+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, sizeof(struct nss_wifili_msg));
+
deinit = &wlmsg->msg.pdevdeinit;
deinit->ifnum = radio_id;
@@ -2618,6 +2663,7 @@ int ath11k_nss_pdev_deinit(struct ath11k
nss_dynamic_interface_dealloc_node(ar->nss.if_num, dyn_if_type);
nss_unregister_wifili_radio_if(ar->nss.if_num);
free:
+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg));
kfree(wlmsg);
return ret;
}
--- a/drivers/net/wireless/ath/ath11k/peer.c
+++ b/drivers/net/wireless/ath/ath11k/peer.c
@@ -633,6 +633,9 @@ int ath11k_peer_delete(struct ath11k *ar
if (ret)
return ret;
+ ATH11K_MEMORY_STATS_DEC(ar->ab, per_peer_object,
+ sizeof(struct ath11k_peer));
+
ar->num_peers--;
return 0;
@@ -729,6 +732,8 @@ int ath11k_peer_create(struct ath11k *ar
ath11k_dp_sta_tx_attach(arsta, peer->peer_id);
}
+ ATH11K_MEMORY_STATS_INC(ar->ab, per_peer_object, sizeof(*peer));
+
ar->num_peers++;
spin_unlock_bh(&ar->ab->base_lock);
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -599,6 +599,8 @@ struct sk_buff *ath11k_wmi_alloc_skb(str
if (!skb)
return NULL;
+ ATH11K_MEMORY_STATS_INC(ab, wmi_tx_skb_alloc, skb->truesize);
+
skb_reserve(skb, WMI_SKB_HEADROOM);
if (!IS_ALIGNED((unsigned long)skb->data, 4))
ath11k_warn(ab, "unaligned WMI skb data\n");
@@ -6666,6 +6668,7 @@ static void ath11k_wmi_htc_tx_complete(s
if (wmi_ep_count > ab->hw_params.max_radios)
goto out;
+ ATH11K_MEMORY_STATS_DEC(ab, wmi_tx_skb_alloc, skb->truesize);
dev_kfree_skb(skb);
for (i = 0; i < ab->htc.wmi_ep_count; i++) {
@@ -6679,6 +6682,7 @@ static void ath11k_wmi_htc_tx_complete(s
return;
out:
+ ATH11K_MEMORY_STATS_DEC(ab, wmi_tx_skb_alloc, skb->truesize);
dev_kfree_skb(skb);
}