Browse Source

qcacmn: Fix large RX desc pool memory allocation

During dp_rx_pdev_attach and dp_rx_pdev_mon_buf_attach we are allocating
three times as many rx descriptors as there are entries in the ring for
AP usecase. This is not needed for MCL and may need to kmalloc
failures for allocating that much contiguous memory

Allocate only as many RX descriptors as there are ring entries for MCL
usecase.

Change-Id: I8b559a85c3899bcbdc520e71ba5da409314db160
CRs-Fixed: 2342957
Mohit Khanna 6 years ago
parent
commit
705149946b
5 changed files with 69 additions and 75 deletions
  1. 15 16
      dp/wifi3.0/dp_rx.c
  2. 17 1
      dp/wifi3.0/dp_rx.h
  3. 2 2
      dp/wifi3.0/dp_rx_desc.c
  4. 16 31
      dp/wifi3.0/dp_rx_mon_dest.c
  5. 19 25
      dp/wifi3.0/dp_rx_mon_status.c

+ 15 - 16
dp/wifi3.0/dp_rx.c

@@ -28,6 +28,7 @@
 #endif
 #include "dp_internal.h"
 #include "dp_rx_mon.h"
+
 #ifdef RX_DESC_DEBUG_CHECK
 static inline void dp_rx_desc_prep(struct dp_rx_desc *rx_desc, qdf_nbuf_t nbuf)
 {
@@ -199,10 +200,10 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
 		dp_rx_desc_prep(&((*desc_list)->rx_desc), rx_netbuf);
 		(*desc_list)->rx_desc.in_use = 1;
 
-		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
-				"rx_netbuf=%pK, buf=%pK, paddr=0x%llx, cookie=%d",
-			rx_netbuf, qdf_nbuf_data(rx_netbuf),
-			(unsigned long long)paddr, (*desc_list)->rx_desc.cookie);
+		dp_debug("rx_netbuf=%pK, buf=%pK, paddr=0x%llx, cookie=%d",
+			 rx_netbuf, qdf_nbuf_data(rx_netbuf),
+			 (unsigned long long)paddr,
+			 (*desc_list)->rx_desc.cookie);
 
 		hal_rxdma_buff_addr_info_set(rxdma_ring_entry, paddr,
 						(*desc_list)->rx_desc.cookie,
@@ -213,10 +214,8 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
 
 	hal_srng_access_end(dp_soc->hal_soc, rxdma_srng);
 
-	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
-		"successfully replenished %d buffers", num_req_buffers);
-	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
-		"%d rx desc added back to free list", num_desc_to_free);
+	dp_debug("replenished buffers %d, rx desc added back to free list %u",
+		 num_req_buffers, num_desc_to_free);
 
 	DP_STATS_INC_PKT(dp_pdev, replenish.pkts, num_req_buffers,
 			(RX_BUFFER_SIZE * num_req_buffers));
@@ -1817,7 +1816,6 @@ dp_rx_pdev_attach(struct dp_pdev *pdev)
 {
 	uint8_t pdev_id = pdev->pdev_id;
 	struct dp_soc *soc = pdev->soc;
-	struct dp_srng rxdma_srng;
 	uint32_t rxdma_entries;
 	union dp_rx_desc_list_elem_t *desc_list = NULL;
 	union dp_rx_desc_list_elem_t *tail = NULL;
@@ -1831,20 +1829,21 @@ dp_rx_pdev_attach(struct dp_pdev *pdev)
 	}
 
 	pdev = soc->pdev_list[pdev_id];
-	rxdma_srng = pdev->rx_refill_buf_ring;
+	dp_rxdma_srng = &pdev->rx_refill_buf_ring;
+	rxdma_entries = dp_rxdma_srng->num_entries;
+
 	soc->process_rx_status = CONFIG_PROCESS_RX_STATUS;
-	rxdma_entries = rxdma_srng.alloc_size/hal_srng_get_entrysize(
-						     soc->hal_soc, RXDMA_BUF);
 
 	rx_desc_pool = &soc->rx_desc_buf[pdev_id];
-
-	dp_rx_desc_pool_alloc(soc, pdev_id, rxdma_entries*3, rx_desc_pool);
+	dp_rx_desc_pool_alloc(soc, pdev_id,
+			      DP_RX_DESC_ALLOC_MULTIPLIER * rxdma_entries,
+			      rx_desc_pool);
 
 	rx_desc_pool->owner = DP_WBM2SW_RBM;
 	/* For Rx buffers, WBM release ring is SW RING 3,for all pdev's */
-	dp_rxdma_srng = &pdev->rx_refill_buf_ring;
+
 	dp_rx_buffers_replenish(soc, pdev_id, dp_rxdma_srng, rx_desc_pool,
-		0, &desc_list, &tail);
+				0, &desc_list, &tail);
 
 	return QDF_STATUS_SUCCESS;
 }

+ 17 - 1
dp/wifi3.0/dp_rx.h

@@ -32,9 +32,25 @@
 
 #ifdef QCA_HOST2FW_RXBUF_RING
 #define DP_WBM2SW_RBM HAL_RX_BUF_RBM_SW1_BM
+
+/**
+ * For MCL cases, allocate as many RX descriptors as buffers in the SW2RXDMA
+ * ring. This value may need to be tuned later.
+ */
+#define DP_RX_DESC_ALLOC_MULTIPLIER 1
 #else
 #define DP_WBM2SW_RBM HAL_RX_BUF_RBM_SW3_BM
-#endif
+
+/**
+ * AP use cases need to allocate more RX Descriptors than the number of
+ * entries avaialable in the SW2RXDMA buffer replenish ring. This is to account
+ * for frames sitting in REO queues, HW-HW DMA rings etc. Hence using a
+ * multiplication factor of 3, to allocate three times as many RX descriptors
+ * as RX buffers.
+ */
+#define DP_RX_DESC_ALLOC_MULTIPLIER 3
+#endif /* QCA_HOST2FW_RXBUF_RING */
+
 #define RX_BUFFER_SIZE			2048
 #define RX_BUFFER_RESERVATION   0
 

+ 2 - 2
dp/wifi3.0/dp_rx_desc.c

@@ -36,13 +36,13 @@ QDF_STATUS dp_rx_desc_pool_alloc(struct dp_soc *soc, uint32_t pool_id,
 	uint32_t i;
 
 	rx_desc_pool->array =
-		qdf_mem_malloc(pool_size*sizeof(union dp_rx_desc_list_elem_t));
+			qdf_mem_malloc(pool_size *
+				       sizeof(union dp_rx_desc_list_elem_t));
 
 	if (!(rx_desc_pool->array)) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
 			"%s: RX Desc Pool[%d] allocation failed",
 			__func__, pool_id);
-
 		return QDF_STATUS_E_NOMEM;
 	}
 

+ 16 - 31
dp/wifi3.0/dp_rx_mon_dest.c

@@ -1131,50 +1131,35 @@ dp_rx_pdev_mon_buf_attach(struct dp_pdev *pdev, int mac_id) {
 	struct dp_soc *soc = pdev->soc;
 	union dp_rx_desc_list_elem_t *desc_list = NULL;
 	union dp_rx_desc_list_elem_t *tail = NULL;
-	struct dp_srng *rxdma_srng;
-	uint32_t rxdma_entries;
+	struct dp_srng *mon_buf_ring;
+	uint32_t num_entries;
 	struct rx_desc_pool *rx_desc_pool;
-	QDF_STATUS status;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	uint8_t mac_for_pdev = dp_get_mac_id_for_mac(soc, mac_id);
+	uint32_t rx_desc_pool_size;
 
-	rxdma_srng = &pdev->rxdma_mon_buf_ring[mac_for_pdev];
+	mon_buf_ring = &pdev->rxdma_mon_buf_ring[mac_for_pdev];
 
-	rxdma_entries = rxdma_srng->alloc_size/hal_srng_get_entrysize(
-				soc->hal_soc,
-				RXDMA_MONITOR_BUF);
+	num_entries = mon_buf_ring->num_entries;
 
 	rx_desc_pool = &soc->rx_desc_mon[mac_id];
 
-	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW,
-			  "%s: Mon RX Desc Pool[%d] allocation size=%d"
-			  , __func__, pdev_id, rxdma_entries*3);
+	dp_debug("Mon RX Desc Pool[%d] entries=%u",
+		 pdev_id, num_entries);
 
-	status = dp_rx_desc_pool_alloc(soc, mac_id,
-			rxdma_entries*3, rx_desc_pool);
-	if (!QDF_IS_STATUS_SUCCESS(status)) {
-		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-			"%s: dp_rx_desc_pool_alloc() failed ", __func__);
+	rx_desc_pool_size = DP_RX_DESC_ALLOC_MULTIPLIER * num_entries;
+	status = dp_rx_desc_pool_alloc(soc, mac_id, rx_desc_pool_size,
+				       rx_desc_pool);
+	if (!QDF_IS_STATUS_SUCCESS(status))
 		return status;
-	}
 
 	rx_desc_pool->owner = HAL_RX_BUF_RBM_SW3_BM;
 
-	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW,
-			  "%s: Mon RX Buffers Replenish pdev_id=%d",
-			  __func__, pdev_id);
-
-
-	status = dp_rx_buffers_replenish(soc, mac_id, rxdma_srng, rx_desc_pool,
-			rxdma_entries, &desc_list, &tail);
-
-	if (!QDF_IS_STATUS_SUCCESS(status)) {
-		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-				"%s: dp_rx_buffers_replenish() failed",
-				__func__);
-		return status;
-	}
+	status = dp_rx_buffers_replenish(soc, mac_id, mon_buf_ring,
+					 rx_desc_pool, num_entries,
+					 &desc_list, &tail);
 
-	return QDF_STATUS_SUCCESS;
+	return status;
 }
 
 static QDF_STATUS

+ 19 - 25
dp/wifi3.0/dp_rx_mon_status.c

@@ -983,50 +983,44 @@ dp_rx_pdev_mon_status_attach(struct dp_pdev *pdev, int ring_id) {
 	struct dp_soc *soc = pdev->soc;
 	union dp_rx_desc_list_elem_t *desc_list = NULL;
 	union dp_rx_desc_list_elem_t *tail = NULL;
-	struct dp_srng *rxdma_srng;
-	uint32_t rxdma_entries;
+	struct dp_srng *mon_status_ring;
+	uint32_t num_entries;
 	struct rx_desc_pool *rx_desc_pool;
 	QDF_STATUS status;
 	int mac_for_pdev = dp_get_mac_id_for_mac(soc, ring_id);
 
-	rxdma_srng = &pdev->rxdma_mon_status_ring[mac_for_pdev];
+	mon_status_ring = &pdev->rxdma_mon_status_ring[mac_for_pdev];
 
-	rxdma_entries = rxdma_srng->alloc_size/hal_srng_get_entrysize(
-		soc->hal_soc, RXDMA_MONITOR_STATUS);
+	num_entries = mon_status_ring->num_entries;
 
 	rx_desc_pool = &soc->rx_desc_status[ring_id];
 
-	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW,
-			"%s: Mon RX Status Pool[%d] allocation size=%d",
-			__func__, ring_id, rxdma_entries);
+	dp_info("Mon RX Status Pool[%d] entries=%d",
+		ring_id, num_entries);
 
-	status = dp_rx_desc_pool_alloc(soc, ring_id, rxdma_entries+1,
-			rx_desc_pool);
-	if (!QDF_IS_STATUS_SUCCESS(status)) {
-		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-			"%s: dp_rx_desc_pool_alloc() failed ", __func__);
+	status = dp_rx_desc_pool_alloc(soc, ring_id, num_entries + 1,
+				       rx_desc_pool);
+	if (!QDF_IS_STATUS_SUCCESS(status))
 		return status;
-	}
 
-	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW,
-			"%s: Mon RX Status Buffers Replenish ring_id=%d",
-			__func__, ring_id);
+	dp_debug("Mon RX Status Buffers Replenish ring_id=%d", ring_id);
+
+	status = dp_rx_mon_status_buffers_replenish(soc, ring_id,
+						    mon_status_ring,
+						    rx_desc_pool,
+						    num_entries,
+						    &desc_list, &tail,
+						    HAL_RX_BUF_RBM_SW3_BM);
 
-	status = dp_rx_mon_status_buffers_replenish(soc, ring_id, rxdma_srng,
-			rx_desc_pool, rxdma_entries, &desc_list, &tail,
-			HAL_RX_BUF_RBM_SW3_BM);
-	if (!QDF_IS_STATUS_SUCCESS(status)) {
-		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-			"%s: dp_rx_buffers_replenish() failed ", __func__);
+	if (!QDF_IS_STATUS_SUCCESS(status))
 		return status;
-	}
 
 	qdf_nbuf_queue_init(&pdev->rx_status_q);
 
 	pdev->mon_ppdu_status = DP_PPDU_STATUS_START;
 
 	qdf_mem_zero(&(pdev->ppdu_info.rx_status),
-		sizeof(pdev->ppdu_info.rx_status));
+		     sizeof(pdev->ppdu_info.rx_status));
 
 	qdf_mem_zero(&pdev->rx_mon_stats,
 		     sizeof(pdev->rx_mon_stats));