Browse Source

qcacmn: Use page_frag_cache to avoid fragmentation

Use page_frag_cache to avoid memory fragmentation
in WKK RxMON

CRs-Fixed: 3234833
Change-Id: I2e42a41999694a91b0f3f9386a1ad0c691bf5caf
Amir Patel 3 years ago
parent
commit
09ae481644

+ 1 - 1
dp/wifi3.0/dp_rx.c

@@ -125,7 +125,7 @@ dp_pdev_frag_alloc_and_map(struct dp_soc *dp_soc,
 	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
 
 	(nbuf_frag_info_t->virt_addr).vaddr =
-			qdf_frag_alloc(rx_desc_pool->buf_size);
+			qdf_frag_alloc(NULL, rx_desc_pool->buf_size);
 
 	if (!((nbuf_frag_info_t->virt_addr).vaddr)) {
 		dp_err("Frag alloc failed");

+ 2 - 1
dp/wifi3.0/monitor/2.0/dp_mon_2.0.c

@@ -194,7 +194,8 @@ dp_mon_frag_alloc_and_map(struct dp_soc *dp_soc,
 {
 	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
 
-	mon_desc->buf_addr = qdf_frag_alloc(mon_desc_pool->buf_size);
+	mon_desc->buf_addr = qdf_frag_alloc(&mon_desc_pool->pf_cache,
+					    mon_desc_pool->buf_size);
 
 	if (!mon_desc->buf_addr) {
 		dp_mon_err("Frag alloc failed");

+ 2 - 0
dp/wifi3.0/monitor/2.0/dp_mon_2.0.h

@@ -117,6 +117,7 @@ union dp_mon_desc_list_elem_t {
  * @owner: owner for nbuf
  * @buf_size: Buffer size
  * @buf_alignment: Buffer alignment
+ * @pf_cache: page frag cache
  */
 struct dp_mon_desc_pool {
 	uint32_t pool_size;
@@ -126,6 +127,7 @@ struct dp_mon_desc_pool {
 	uint8_t owner;
 	uint16_t buf_size;
 	uint8_t buf_alignment;
+	qdf_frag_cache_t pf_cache;
 };
 
 /**

+ 4 - 0
dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c

@@ -23,6 +23,8 @@
 #include "hal_be_api_mon.h"
 #include "dp_internal.h"
 #include "qdf_mem.h"   /* qdf_mem_malloc,free */
+#include <qdf_flex_mem.h>
+#include "qdf_nbuf_frag.h"
 #include "dp_mon.h"
 #include <dp_rx_mon.h>
 #include <dp_mon_2.0.h>
@@ -1508,6 +1510,8 @@ dp_rx_mon_buf_desc_pool_deinit(struct dp_soc *soc)
 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
 
+	/* Drain page frag cachce before pool deinit */
+	qdf_frag_cache_drain(&mon_soc_be->rx_desc_mon.pf_cache);
 	dp_mon_desc_pool_deinit(&mon_soc_be->rx_desc_mon);
 }
 

+ 28 - 5
qdf/inc/qdf_nbuf_frag.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 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
@@ -28,6 +29,12 @@
 #include <i_qdf_trace.h>
 #include <i_qdf_nbuf_frag.h>
 
+/*
+ * typedef qdf_frag_cache_t - Platform independent
+ * frag cache abstraction
+ */
+typedef __qdf_frag_cache_t qdf_frag_cache_t;
+
 /*
  * typedef qdf_frag_t - Platform independent frag address abstraction
  */
@@ -109,18 +116,21 @@ void qdf_frag_debug_delete_node(qdf_frag_t fragp, const char *func_name,
 void qdf_frag_debug_update_addr(qdf_frag_t p_fragp, qdf_frag_t n_fragp,
 				const char *func_name, uint32_t line_num);
 
-#define qdf_frag_alloc(s) \
-	qdf_frag_alloc_debug(s, __func__, __LINE__)
+#define qdf_frag_alloc(p, s) \
+	qdf_frag_alloc_debug(p, s, __func__, __LINE__)
 
 /**
  * qdf_frag_alloc_debug() - Allocate frag memory
+ * @pf_cache: page frag cache
  * @fragsz: Size of frag memory to be allocated
  * @func_name: Caller function name
  * @line_num: Caller function line no.
  *
  * Return: Allocated frag address
  */
-qdf_frag_t qdf_frag_alloc_debug(unsigned int fragsz, const char *func_name,
+qdf_frag_t qdf_frag_alloc_debug(qdf_frag_cache_t *pf_cache,
+				unsigned int fragsz,
+				const char *func_name,
 				uint32_t line_num);
 
 #define qdf_frag_free(p) \
@@ -180,13 +190,15 @@ static inline void qdf_frag_debug_update_addr(qdf_frag_t p_fragp,
 
 /**
  * qdf_frag_alloc() - Allocate frag memory
+ * @pf_cache: page frag cache
  * @fragsz: Size of frag memory to be allocated
  *
  * Return: Allocated frag address
  */
-static inline qdf_frag_t qdf_frag_alloc(unsigned int fragsz)
+static inline qdf_frag_t qdf_frag_alloc(qdf_frag_cache_t *pf_cache,
+					unsigned int fragsz)
 {
-	return __qdf_frag_alloc(fragsz);
+	return __qdf_frag_alloc(pf_cache, fragsz);
 }
 
 /**
@@ -284,4 +296,15 @@ static inline void qdf_mem_unmap_page(qdf_device_t osdev, qdf_dma_addr_t paddr,
 	__qdf_mem_unmap_page(osdev, paddr, nbytes, dir);
 }
 
+/*
+ * qdf_frag_cache_drain() - Drain page frag cache
+ *
+ * @pf_cache: page frag cache
+ *
+ * Return: void
+ */
+static inline void qdf_frag_cache_drain(qdf_frag_cache_t *pf_cache)
+{
+	__qdf_frag_cache_drain(pf_cache);
+}
 #endif /* _QDF_NBUF_FRAG_H */

+ 37 - 1
qdf/linux/src/i_qdf_nbuf_frag.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 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
@@ -30,6 +31,11 @@
 #define QDF_NBUF_FRAG_DEBUG_COUNT_ZERO    0
 #define QDF_NBUF_FRAG_DEBUG_COUNT_ONE     1
 
+/**
+ * typedef __qdf_frag_cache_t - Abstraction for void * for frag address
+ */
+typedef struct page_frag_cache __qdf_frag_cache_t;
+
 /**
  * typedef __qdf_frag_t - Abstraction for void * for frag address
  */
@@ -126,6 +132,14 @@ QDF_STATUS __qdf_mem_map_page(qdf_device_t osdev, __qdf_frag_t buf,
 			      qdf_dma_dir_t dir, size_t nbytes,
 			      qdf_dma_addr_t *phy_addr);
 
+/**
+ * __qdf_frag_cache_drain() - Drain page frag cache
+ * @pf_cache: page frag cache
+ *
+ * Return: void
+ */
+void __qdf_frag_cache_drain(__qdf_frag_cache_t *pf_cache);
+
 /**
  * __qdf_frag_free() - Free allocated frag memory
  * @vaddr: Frag address to be freed
@@ -142,17 +156,39 @@ static inline void __qdf_frag_free(__qdf_frag_t vaddr)
 
 /**
  * __qdf_frag_alloc() - Allocate frag Memory
+ * @pf_cache: page frag cache
  * @fragsz: Size of frag memory to be allocated
  *
  * Return: Allocated frag addr.
  */
-static inline __qdf_frag_t __qdf_frag_alloc(unsigned int fragsz)
+#if defined(QDF_FRAG_CACHE_SUPPORT)
+static inline __qdf_frag_t __qdf_frag_alloc(__qdf_frag_cache_t *pf_cache,
+					    unsigned int fragsz)
+{
+	__qdf_frag_t p_frag;
+
+	if (pf_cache) {
+		unsigned int sz = SKB_DATA_ALIGN(fragsz);
+
+		p_frag =  page_frag_alloc(pf_cache, sz, GFP_ATOMIC);
+	} else {
+		p_frag = netdev_alloc_frag(fragsz);
+	}
+	if (p_frag)
+		__qdf_frag_count_inc(QDF_NBUF_FRAG_DEBUG_COUNT_ONE);
+	return p_frag;
+}
+#else
+static inline __qdf_frag_t __qdf_frag_alloc(__qdf_frag_cache_t *pf_cache,
+					    unsigned int fragsz)
 {
 	__qdf_frag_t p_frag = netdev_alloc_frag(fragsz);
 
 	if (p_frag)
 		__qdf_frag_count_inc(QDF_NBUF_FRAG_DEBUG_COUNT_ONE);
+
 	return p_frag;
 }
+#endif
 
 #endif /* _I_QDF_NBUF_FRAG_H */

+ 23 - 3
qdf/linux/src/qdf_nbuf_frag.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 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
@@ -748,15 +749,17 @@ void qdf_frag_debug_update_addr(qdf_frag_t p_fragp, qdf_frag_t n_fragp,
 	}
 }
 
-qdf_frag_t qdf_frag_alloc_debug(unsigned int frag_size, const char *func_name,
+qdf_frag_t qdf_frag_alloc_debug(qdf_frag_cache_t *pf_cache,
+				unsigned int frag_size,
+				const char *func_name,
 				uint32_t line_num)
 {
 	qdf_frag_t p_frag;
 
 	if (is_initial_mem_debug_disabled)
-		return __qdf_frag_alloc(frag_size);
+		return __qdf_frag_alloc(pf_cache, frag_size);
 
-	p_frag =  __qdf_frag_alloc(frag_size);
+	p_frag =  __qdf_frag_alloc(pf_cache, frag_size);
 
 	/* Store frag in QDF Frag Tracking Table */
 	if (qdf_likely(p_frag))
@@ -827,3 +830,20 @@ void __qdf_mem_unmap_page(qdf_device_t osdev, qdf_dma_addr_t paddr,
 #endif
 
 qdf_export_symbol(__qdf_mem_unmap_page);
+
+#if defined(QDF_FRAG_CACHE_SUPPORT)
+void __qdf_frag_cache_drain(qdf_frag_cache_t *pf_cache)
+{
+	struct page *page;
+
+	page  = virt_to_page(pf_cache->va);
+	__page_frag_cache_drain(page, pf_cache->pagecnt_bias);
+	memset(pf_cache, 0, sizeof(*pf_cache));
+}
+#else
+void __qdf_frag_cache_drain(qdf_frag_cache_t *pf_cache)
+{
+}
+#endif
+
+qdf_export_symbol(__qdf_frag_cache_drain);