Browse Source

qcacmn: Add memory stats pertaining to DP usage

Add sysfs node for DP level memory stats:
/sys/kernel/wifi/wlan/wlan_dp_mem_stats
These include Tx, Rx SKB memory allocated, Tx/Rx
buffer count, outstanding Tx desc count.
Add and subtract the skb memory for Rx/Tx when
the map/unmap functions are invoked.

Change-Id: If62cc47bb60f7eb63f60e861f755f3417248677f
CRs-Fixed: 2724482
Nisha Menon 5 years ago
parent
commit
3db73f1414
5 changed files with 502 additions and 21 deletions
  1. 241 3
      qdf/inc/qdf_mem.h
  2. 2 14
      qdf/inc/qdf_nbuf.h
  3. 47 1
      qdf/linux/src/i_qdf_nbuf.h
  4. 206 1
      qdf/linux/src/qdf_mem.c
  5. 6 2
      qdf/linux/src/qdf_nbuf.c

+ 241 - 3
qdf/inc/qdf_mem.h

@@ -28,6 +28,7 @@
 #include <qdf_types.h>
 #include <i_qdf_mem.h>
 #include <i_qdf_trace.h>
+#include <qdf_atomic.h>
 
 #define QDF_CACHE_LINE_SZ __qdf_cache_line_sz
 
@@ -604,7 +605,85 @@ void qdf_mem_skb_inc(qdf_size_t size);
  */
 void qdf_mem_skb_dec(qdf_size_t size);
 
+/**
+ * qdf_mem_skb_total_inc() - increment total skb allocation size
+ * in host driver in both debug and perf builds
+ * @size: size to be added
+ *
+ * Return: none
+ */
+void qdf_mem_skb_total_inc(qdf_size_t size);
+
+/**
+ * qdf_mem_skb_total_dec() - decrement total skb allocation size
+ * in the host driver in debug and perf flavors
+ * @size: size to be decremented
+ *
+ * Return: none
+ */
+void qdf_mem_skb_total_dec(qdf_size_t size);
+
+/**
+ * qdf_mem_dp_tx_skb_inc() - Increment Tx skb allocation size
+ * @size: size to be added
+ *
+ * Return: none
+ */
+void qdf_mem_dp_tx_skb_inc(qdf_size_t size);
+
+/**
+ * qdf_mem_dp_tx_skb_dec() - Decrement Tx skb allocation size
+ * @size: size to be decreased
+ *
+ * Return: none
+ */
+void qdf_mem_dp_tx_skb_dec(qdf_size_t size);
+
+/**
+ * qdf_mem_dp_rx_skb_inc() - Increment Rx skb allocation size
+ * @size: size to be added
+ *
+ * Return: none
+ */
+void qdf_mem_dp_rx_skb_inc(qdf_size_t size);
+
+/**
+ * qdf_mem_dp_rx_skb_dec() - Decrement Rx skb allocation size
+ * @size: size to be decreased
+ *
+ * Return: none
+ */
+void qdf_mem_dp_rx_skb_dec(qdf_size_t size);
+
+/**
+ * qdf_mem_dp_tx_skb_cnt_inc() - Increment Tx buffer count
+ *
+ * Return: none
+ */
+void qdf_mem_dp_tx_skb_cnt_inc(void);
+
+/**
+ * qdf_mem_dp_tx_skb_cnt_dec() - Decrement Tx buffer count
+ *
+ * Return: none
+ */
+void qdf_mem_dp_tx_skb_cnt_dec(void);
+
+/**
+ * qdf_mem_dp_rx_skb_cnt_inc() - Increment Rx buffer count
+ *
+ * Return: none
+ */
+void qdf_mem_dp_rx_skb_cnt_inc(void);
+
+/**
+ * qdf_mem_dp_rx_skb_cnt_dec() - Decrement Rx buffer count
+ *
+ * Return: none
+ */
+void qdf_mem_dp_rx_skb_cnt_dec(void);
 #else
+
 static inline void qdf_mem_skb_inc(qdf_size_t size)
 {
 }
@@ -612,6 +691,46 @@ static inline void qdf_mem_skb_inc(qdf_size_t size)
 static inline void qdf_mem_skb_dec(qdf_size_t size)
 {
 }
+
+static inline void qdf_mem_skb_total_inc(qdf_size_t size)
+{
+}
+
+static inline void qdf_mem_skb_total_dec(qdf_size_t size)
+{
+}
+
+static inline void qdf_mem_dp_tx_skb_inc(qdf_size_t size)
+{
+}
+
+static inline void qdf_mem_dp_tx_skb_dec(qdf_size_t size)
+{
+}
+
+static inline void qdf_mem_dp_rx_skb_inc(qdf_size_t size)
+{
+}
+
+static inline void qdf_mem_dp_rx_skb_dec(qdf_size_t size)
+{
+}
+
+static inline void qdf_mem_dp_tx_skb_cnt_inc(void)
+{
+}
+
+static inline void qdf_mem_dp_tx_skb_cnt_dec(void)
+{
+}
+
+static inline void qdf_mem_dp_rx_skb_cnt_inc(void)
+{
+}
+
+static inline void qdf_mem_dp_rx_skb_cnt_dec(void)
+{
+}
 #endif /* CONFIG_WLAN_SYSFS_MEM_STATS */
 
 /**
@@ -868,7 +987,7 @@ static inline void qdf_mem_shared_mem_free(qdf_device_t osdev,
  * qdf_dma_mem_stats_read() - Return the DMA memory allocated in
  * host driver
  *
- * Return: None
+ * Return: Total DMA memory allocated
  */
 int32_t qdf_dma_mem_stats_read(void);
 
@@ -876,7 +995,7 @@ int32_t qdf_dma_mem_stats_read(void);
  * qdf_heap_mem_stats_read() - Return the heap memory allocated
  * in host driver
  *
- * Return: None
+ * Return: Total heap memory allocated
  */
 int32_t qdf_heap_mem_stats_read(void);
 
@@ -884,8 +1003,127 @@ int32_t qdf_heap_mem_stats_read(void);
  * qdf_skb_mem_stats_read() - Return the SKB memory allocated in
  * host driver
  *
- * Return: None
+ * Return: Total SKB memory allocated
  */
 int32_t qdf_skb_mem_stats_read(void);
 
+/**
+ * qdf_skb_total_mem_stats_read() - Return the SKB memory allocated
+ * in the host driver tracked in both debug and perf builds
+ *
+ * Return: Total SKB memory allocated
+ */
+int32_t qdf_skb_total_mem_stats_read(void);
+
+/**
+ * qdf_skb_max_mem_stats_read() - Return the max SKB memory
+ * allocated in host driver. This is the high watermark for the
+ * total SKB allocated in the host driver
+ *
+ * Return: None
+ */
+int32_t qdf_skb_max_mem_stats_read(void);
+
+/**
+ * qdf_mem_tx_desc_cnt_read() - Return the outstanding Tx descs
+ * which are waiting on Tx completions
+ *
+ * Return: Outstanding Tx desc count
+ */
+int32_t qdf_mem_tx_desc_cnt_read(void);
+
+/**
+ * qdf_mem_tx_desc_max_read() - Return the max outstanding Tx
+ * descs which are waiting on Tx completions. This is the high
+ * watermark for the pending desc count
+ *
+ * Return: Max outstanding Tx desc count
+ */
+int32_t qdf_mem_tx_desc_max_read(void);
+
+/**
+ * qdf_mem_stats_init() - Initialize the qdf memstats fields on
+ * creating the sysfs node
+ *
+ * Return: None
+ */
+void qdf_mem_stats_init(void);
+
+/**
+ * qdf_dp_tx_skb_mem_stats_read() - Return the SKB memory
+ * allocated for Tx data path
+ *
+ * Return: Tx SKB memory allocated
+ */
+int32_t qdf_dp_tx_skb_mem_stats_read(void);
+
+/**
+ * qdf_dp_rx_skb_mem_stats_read() - Return the SKB memory
+ * allocated for Rx data path
+ *
+ * Return: Rx SKB memory allocated
+ */
+int32_t qdf_dp_rx_skb_mem_stats_read(void);
+
+/**
+ * qdf_dp_tx_skb_max_mem_stats_read() - Return the high
+ * watermark for the SKB memory allocated for Tx data path
+ *
+ * Return: Max Tx SKB memory allocated
+ */
+int32_t qdf_dp_tx_skb_max_mem_stats_read(void);
+
+/**
+ * qdf_dp_rx_skb_max_mem_stats_read() - Return the high
+ * watermark for the SKB memory allocated for Rx data path
+ *
+ * Return: Max Rx SKB memory allocated
+ */
+int32_t qdf_dp_rx_skb_max_mem_stats_read(void);
+
+/**
+ * qdf_mem_dp_tx_skb_cnt_read() - Return number of buffers
+ * allocated in the Tx data path by the host driver or
+ * buffers coming from the n/w stack
+ *
+ * Return: Number of DP Tx buffers allocated
+ */
+int32_t qdf_mem_dp_tx_skb_cnt_read(void);
+
+/**
+ * qdf_mem_dp_tx_skb_max_cnt_read() - Return max number of
+ * buffers allocated in the Tx data path
+ *
+ * Return: Max number of DP Tx buffers allocated
+ */
+int32_t qdf_mem_dp_tx_skb_max_cnt_read(void);
+
+/**
+ * qdf_mem_dp_rx_skb_cnt_read() - Return number of buffers
+ * allocated in the Rx data path
+ *
+ * Return: Number of DP Rx buffers allocated
+ */
+int32_t qdf_mem_dp_rx_skb_cnt_read(void);
+
+/**
+ * qdf_mem_dp_rx_skb_max_cnt_read() - Return max number of
+ * buffers allocated in the Rx data path
+ *
+ * Return: Max number of DP Rx buffers allocated
+ */
+int32_t qdf_mem_dp_rx_skb_max_cnt_read(void);
+
+/**
+ * qdf_mem_tx_desc_cnt_update() - Update the pending tx desc
+ * count and the high watermark for pending tx desc count
+ *
+ * @pending_tx_descs: outstanding Tx desc count
+ * @tx_descs_max: high watermark for outstanding Tx desc count
+ *
+ * Return: None
+ */
+void qdf_mem_tx_desc_cnt_update(qdf_atomic_t pending_tx_descs,
+				int32_t tx_descs_max);
+
 #endif /* __QDF_MEMORY_H */

+ 2 - 14
qdf/inc/qdf_nbuf.h

@@ -1702,12 +1702,7 @@ static inline qdf_nbuf_t
 qdf_nbuf_alloc_fl(qdf_device_t osdev, qdf_size_t size, int reserve, int align,
 		  int prio, const char *func, uint32_t line)
 {
-	qdf_nbuf_t nbuf;
-
-	nbuf = __qdf_nbuf_alloc(osdev, size, reserve, align, prio, func, line);
-	if (qdf_likely(nbuf))
-		qdf_mem_skb_inc(nbuf->truesize);
-	return nbuf;
+	return __qdf_nbuf_alloc(osdev, size, reserve, align, prio, func, line);
 }
 
 /**
@@ -1727,14 +1722,7 @@ static inline qdf_nbuf_t
 qdf_nbuf_alloc_no_recycler_fl(size_t size, int reserve, int align,
 			      const char *func, uint32_t line)
 {
-	qdf_nbuf_t nbuf;
-
-	nbuf = __qdf_nbuf_alloc_no_recycler(size, reserve, align, func, line);
-
-	if (qdf_likely(nbuf))
-		qdf_mem_skb_inc(nbuf->truesize);
-
-	return nbuf;
+	return __qdf_nbuf_alloc_no_recycler(size, reserve, align, func, line);
 }
 
 static inline void qdf_nbuf_free(qdf_nbuf_t buf)

+ 47 - 1
qdf/linux/src/i_qdf_nbuf.h

@@ -2230,6 +2230,47 @@ static inline void __qdf_nbuf_orphan(struct sk_buff *skb)
 	return skb_orphan(skb);
 }
 
+#ifdef CONFIG_WLAN_SYSFS_MEM_STATS
+/**
+ * __qdf_record_nbuf_nbytes() - add or subtract the size of the nbuf
+ * from the total skb mem and DP tx/rx skb mem
+ * @nbytes: number of bytes
+ * @dir: direction
+ * @is_mapped: is mapped or unmapped memory
+ *
+ * Return: none
+ */
+static inline void __qdf_record_nbuf_nbytes(
+	int nbytes, qdf_dma_dir_t dir, bool is_mapped)
+{
+	if (is_mapped) {
+		if (dir == QDF_DMA_TO_DEVICE) {
+			qdf_mem_dp_tx_skb_cnt_inc();
+			qdf_mem_dp_tx_skb_inc(nbytes);
+		} else if (dir == QDF_DMA_FROM_DEVICE) {
+			qdf_mem_dp_rx_skb_cnt_inc();
+			qdf_mem_dp_rx_skb_inc(nbytes);
+		}
+		qdf_mem_skb_total_inc(nbytes);
+	} else {
+		if (dir == QDF_DMA_TO_DEVICE) {
+			qdf_mem_dp_tx_skb_cnt_dec();
+			qdf_mem_dp_tx_skb_dec(nbytes);
+		} else if (dir == QDF_DMA_FROM_DEVICE) {
+			qdf_mem_dp_rx_skb_cnt_dec();
+			qdf_mem_dp_rx_skb_dec(nbytes);
+		}
+		qdf_mem_skb_total_dec(nbytes);
+	}
+}
+
+#else /* CONFIG_WLAN_SYSFS_MEM_STATS */
+static inline void __qdf_record_nbuf_nbytes(
+	int nbytes, qdf_dma_dir_t dir, bool is_mapped)
+{
+}
+#endif /* CONFIG_WLAN_SYSFS_MEM_STATS */
+
 /**
  * __qdf_nbuf_map_nbytes_single() - map nbytes
  * @osdev: os device
@@ -2255,13 +2296,17 @@ static inline QDF_STATUS __qdf_nbuf_map_nbytes_single(
 		qdf_dma_dir_t dir, int nbytes)
 {
 	qdf_dma_addr_t paddr;
+	QDF_STATUS ret;
 
 	/* assume that the OS only provides a single fragment */
 	QDF_NBUF_CB_PADDR(buf) = paddr =
 		dma_map_single(osdev->dev, buf->data,
 			       nbytes, __qdf_dma_dir_to_os(dir));
-	return dma_mapping_error(osdev->dev, paddr) ?
+	ret =  dma_mapping_error(osdev->dev, paddr) ?
 		QDF_STATUS_E_FAULT : QDF_STATUS_SUCCESS;
+	if (QDF_IS_STATUS_SUCCESS(ret))
+		__qdf_record_nbuf_nbytes(nbytes, dir, true);
+	return ret;
 }
 #endif
 /**
@@ -2288,6 +2333,7 @@ __qdf_nbuf_unmap_nbytes_single(qdf_device_t osdev, struct sk_buff *buf,
 	qdf_dma_addr_t paddr = QDF_NBUF_CB_PADDR(buf);
 
 	if (qdf_likely(paddr)) {
+		__qdf_record_nbuf_nbytes(nbytes, dir, false);
 		dma_unmap_single(osdev->dev, paddr, nbytes,
 				 __qdf_dma_dir_to_os(dir));
 		return;

+ 206 - 1
qdf/linux/src/qdf_mem.c

@@ -28,7 +28,6 @@
 #include "qdf_mc_timer.h"
 #include "qdf_module.h"
 #include <qdf_trace.h>
-#include "qdf_atomic.h"
 #include "qdf_str.h"
 #include "qdf_talloc.h"
 #include <linux/debugfs.h>
@@ -60,11 +59,35 @@ static bool is_initial_mem_debug_disabled;
  * @kmalloc: total kmalloc allocations
  * @dma: total dma allocations
  * @skb: total skb allocations
+ * @skb_total: total skb allocations in host driver
+ * @dp_tx_skb: total Tx skb allocations in datapath
+ * @dp_rx_skb: total Rx skb allocations in datapath
+ * @skb_mem_max: high watermark for skb allocations
+ * @dp_tx_skb_mem_max: high watermark for Tx DP skb allocations
+ * @dp_rx_skb_mem_max: high watermark for Rx DP skb allocations
+ * @dp_tx_skb_count: DP Tx buffer count
+ * @dp_tx_skb_count_max: High watermark for DP Tx buffer count
+ * @dp_rx_skb_count: DP Rx buffer count
+ * @dp_rx_skb_count_max: High watermark for DP Rx buffer count
+ * @tx_descs_outstanding: Current pending Tx descs count
+ * @tx_descs_max: High watermark for pending Tx descs count
  */
 static struct __qdf_mem_stat {
 	qdf_atomic_t kmalloc;
 	qdf_atomic_t dma;
 	qdf_atomic_t skb;
+	qdf_atomic_t skb_total;
+	qdf_atomic_t dp_tx_skb;
+	qdf_atomic_t dp_rx_skb;
+	int32_t skb_mem_max;
+	int32_t dp_tx_skb_mem_max;
+	int32_t dp_rx_skb_mem_max;
+	qdf_atomic_t dp_tx_skb_count;
+	int32_t dp_tx_skb_count_max;
+	qdf_atomic_t dp_rx_skb_count;
+	int32_t dp_rx_skb_count_max;
+	qdf_atomic_t tx_descs_outstanding;
+	int32_t tx_descs_max;
 } qdf_mem_stat;
 
 #ifdef MEMORY_DEBUG
@@ -1044,6 +1067,83 @@ void qdf_mem_skb_dec(qdf_size_t size)
 {
 	qdf_atomic_sub(size, &qdf_mem_stat.skb);
 }
+
+void qdf_mem_skb_total_inc(qdf_size_t size)
+{
+	int32_t skb_mem_max = 0;
+
+	qdf_atomic_add(size, &qdf_mem_stat.skb_total);
+	skb_mem_max = qdf_atomic_read(&qdf_mem_stat.skb_total);
+	if (qdf_mem_stat.skb_mem_max < skb_mem_max)
+		qdf_mem_stat.skb_mem_max = skb_mem_max;
+}
+
+void qdf_mem_skb_total_dec(qdf_size_t size)
+{
+	qdf_atomic_sub(size, &qdf_mem_stat.skb_total);
+}
+
+void qdf_mem_dp_tx_skb_inc(qdf_size_t size)
+{
+	int32_t curr_dp_tx_skb_mem_max = 0;
+
+	qdf_atomic_add(size, &qdf_mem_stat.dp_tx_skb);
+	curr_dp_tx_skb_mem_max = qdf_atomic_read(&qdf_mem_stat.dp_tx_skb);
+	if (qdf_mem_stat.dp_tx_skb_mem_max < curr_dp_tx_skb_mem_max)
+		qdf_mem_stat.dp_tx_skb_mem_max = curr_dp_tx_skb_mem_max;
+}
+
+void qdf_mem_dp_tx_skb_dec(qdf_size_t size)
+{
+	qdf_atomic_sub(size, &qdf_mem_stat.dp_tx_skb);
+}
+
+void qdf_mem_dp_rx_skb_inc(qdf_size_t size)
+{
+	int32_t curr_dp_rx_skb_mem_max = 0;
+
+	qdf_atomic_add(size, &qdf_mem_stat.dp_rx_skb);
+	curr_dp_rx_skb_mem_max = qdf_atomic_read(&qdf_mem_stat.dp_rx_skb);
+	if (qdf_mem_stat.dp_rx_skb_mem_max < curr_dp_rx_skb_mem_max)
+		qdf_mem_stat.dp_rx_skb_mem_max = curr_dp_rx_skb_mem_max;
+}
+
+void qdf_mem_dp_rx_skb_dec(qdf_size_t size)
+{
+	qdf_atomic_sub(size, &qdf_mem_stat.dp_rx_skb);
+}
+
+void qdf_mem_dp_tx_skb_cnt_inc(void)
+{
+	int32_t curr_dp_tx_skb_count_max = 0;
+
+	qdf_atomic_add(1, &qdf_mem_stat.dp_tx_skb_count);
+	curr_dp_tx_skb_count_max =
+		qdf_atomic_read(&qdf_mem_stat.dp_tx_skb_count);
+	if (qdf_mem_stat.dp_tx_skb_count_max < curr_dp_tx_skb_count_max)
+		qdf_mem_stat.dp_tx_skb_count_max = curr_dp_tx_skb_count_max;
+}
+
+void qdf_mem_dp_tx_skb_cnt_dec(void)
+{
+	qdf_atomic_sub(1, &qdf_mem_stat.dp_tx_skb_count);
+}
+
+void qdf_mem_dp_rx_skb_cnt_inc(void)
+{
+	int32_t curr_dp_rx_skb_count_max = 0;
+
+	qdf_atomic_add(1, &qdf_mem_stat.dp_rx_skb_count);
+	curr_dp_rx_skb_count_max =
+		qdf_atomic_read(&qdf_mem_stat.dp_rx_skb_count);
+	if (qdf_mem_stat.dp_rx_skb_count_max < curr_dp_rx_skb_count_max)
+		qdf_mem_stat.dp_rx_skb_count_max = curr_dp_rx_skb_count_max;
+}
+
+void qdf_mem_dp_rx_skb_cnt_dec(void)
+{
+	qdf_atomic_sub(1, &qdf_mem_stat.dp_rx_skb_count);
+}
 #endif
 
 void qdf_mem_kmalloc_dec(qdf_size_t size)
@@ -2543,3 +2643,108 @@ int32_t qdf_skb_mem_stats_read(void)
 
 qdf_export_symbol(qdf_skb_mem_stats_read);
 
+int32_t qdf_skb_total_mem_stats_read(void)
+{
+	return qdf_atomic_read(&qdf_mem_stat.skb_total);
+}
+
+qdf_export_symbol(qdf_skb_total_mem_stats_read);
+
+int32_t qdf_skb_max_mem_stats_read(void)
+{
+	return qdf_mem_stat.skb_mem_max;
+}
+
+qdf_export_symbol(qdf_skb_max_mem_stats_read);
+
+int32_t qdf_dp_tx_skb_mem_stats_read(void)
+{
+	return qdf_atomic_read(&qdf_mem_stat.dp_tx_skb);
+}
+
+qdf_export_symbol(qdf_dp_tx_skb_mem_stats_read);
+
+int32_t qdf_dp_rx_skb_mem_stats_read(void)
+{
+	return qdf_atomic_read(&qdf_mem_stat.dp_rx_skb);
+}
+
+qdf_export_symbol(qdf_dp_rx_skb_mem_stats_read);
+
+int32_t qdf_mem_dp_tx_skb_cnt_read(void)
+{
+	return qdf_atomic_read(&qdf_mem_stat.dp_tx_skb_count);
+}
+
+qdf_export_symbol(qdf_mem_dp_tx_skb_cnt_read);
+
+int32_t qdf_mem_dp_tx_skb_max_cnt_read(void)
+{
+	return qdf_mem_stat.dp_tx_skb_count_max;
+}
+
+qdf_export_symbol(qdf_mem_dp_tx_skb_max_cnt_read);
+
+int32_t qdf_mem_dp_rx_skb_cnt_read(void)
+{
+	return qdf_atomic_read(&qdf_mem_stat.dp_rx_skb_count);
+}
+
+qdf_export_symbol(qdf_mem_dp_rx_skb_cnt_read);
+
+int32_t qdf_mem_dp_rx_skb_max_cnt_read(void)
+{
+	return qdf_mem_stat.dp_rx_skb_count_max;
+}
+
+qdf_export_symbol(qdf_mem_dp_rx_skb_max_cnt_read);
+
+int32_t qdf_dp_tx_skb_max_mem_stats_read(void)
+{
+	return qdf_mem_stat.dp_tx_skb_mem_max;
+}
+
+qdf_export_symbol(qdf_dp_tx_skb_max_mem_stats_read);
+
+int32_t qdf_dp_rx_skb_max_mem_stats_read(void)
+{
+	return qdf_mem_stat.dp_rx_skb_mem_max;
+}
+
+qdf_export_symbol(qdf_dp_rx_skb_max_mem_stats_read);
+
+int32_t qdf_mem_tx_desc_cnt_read(void)
+{
+	return qdf_atomic_read(&qdf_mem_stat.tx_descs_outstanding);
+}
+
+qdf_export_symbol(qdf_mem_tx_desc_cnt_read);
+
+int32_t qdf_mem_tx_desc_max_read(void)
+{
+	return qdf_mem_stat.tx_descs_max;
+}
+
+qdf_export_symbol(qdf_mem_tx_desc_max_read);
+
+void qdf_mem_tx_desc_cnt_update(qdf_atomic_t pending_tx_descs,
+				int32_t tx_descs_max)
+{
+	qdf_mem_stat.tx_descs_outstanding = pending_tx_descs;
+	qdf_mem_stat.tx_descs_max = tx_descs_max;
+}
+
+qdf_export_symbol(qdf_mem_tx_desc_cnt_update);
+
+void qdf_mem_stats_init(void)
+{
+	qdf_mem_stat.skb_mem_max = 0;
+	qdf_mem_stat.dp_tx_skb_mem_max = 0;
+	qdf_mem_stat.dp_rx_skb_mem_max = 0;
+	qdf_mem_stat.dp_tx_skb_count_max = 0;
+	qdf_mem_stat.dp_rx_skb_count_max = 0;
+	qdf_mem_stat.tx_descs_max = 0;
+}
+
+qdf_export_symbol(qdf_mem_stats_init);
+

+ 6 - 2
qdf/linux/src/qdf_nbuf.c

@@ -697,7 +697,6 @@ void __qdf_nbuf_free(struct sk_buff *skb)
 	qdf_nbuf_frag_count_dec(skb);
 
 	qdf_nbuf_count_dec(skb);
-	qdf_mem_skb_dec(skb->truesize);
 	if (nbuf_free_cb)
 		nbuf_free_cb(skb);
 	else
@@ -1088,6 +1087,8 @@ __qdf_nbuf_map_single(qdf_device_t osdev, qdf_nbuf_t buf, qdf_dma_dir_t dir)
 		dma_map_single(osdev->dev, buf->data,
 				skb_end_pointer(buf) - buf->data,
 				__qdf_dma_dir_to_os(dir));
+	__qdf_record_nbuf_nbytes(
+		__qdf_nbuf_get_data_len(buf), dir, true);
 	return dma_mapping_error(osdev->dev, paddr)
 		? QDF_STATUS_E_FAILURE
 		: QDF_STATUS_SUCCESS;
@@ -1111,10 +1112,13 @@ void __qdf_nbuf_unmap_single(qdf_device_t osdev, qdf_nbuf_t buf,
 void __qdf_nbuf_unmap_single(qdf_device_t osdev, qdf_nbuf_t buf,
 					qdf_dma_dir_t dir)
 {
-	if (QDF_NBUF_CB_PADDR(buf))
+	if (QDF_NBUF_CB_PADDR(buf)) {
+		__qdf_record_nbuf_nbytes(
+			__qdf_nbuf_get_data_len(buf), dir, false);
 		dma_unmap_single(osdev->dev, QDF_NBUF_CB_PADDR(buf),
 			skb_end_pointer(buf) - buf->data,
 			__qdf_dma_dir_to_os(dir));
+	}
 }
 #endif
 qdf_export_symbol(__qdf_nbuf_unmap_single);