Ver Fonte

qcacld-3.0: Pre-allocate pdev context

Pre-allocate pdev context as size (53KB) exceeds threshold
of dynamic allocation (4KB).

Change-Id: Ib2adfc556ca1096ab7a800cd14a7da44ccd4f01a
CRs-Fixed: 2828243
Ananya Gupta há 4 anos atrás
pai
commit
d5395e3340
3 ficheiros alterados com 110 adições e 0 exclusões
  1. 2 0
      core/cds/src/cds_api.c
  2. 83 0
      core/dp/txrx3.0/dp_txrx.c
  3. 25 0
      core/dp/txrx3.0/dp_txrx.h

+ 2 - 0
core/cds/src/cds_api.c

@@ -123,6 +123,8 @@ static struct ol_if_ops  dp_ol_if_ops = {
 	.send_delba = cds_send_delba,
 	.dp_rx_get_pending = dp_rx_tm_get_pending,
 #ifdef DP_MEM_PRE_ALLOC
+	.dp_prealloc_get_context = dp_prealloc_get_context_memory,
+	.dp_prealloc_put_context = dp_prealloc_put_context_memory,
 	.dp_prealloc_get_consistent = dp_prealloc_get_coherent,
 	.dp_prealloc_put_consistent = dp_prealloc_put_coherent,
 	.dp_get_multi_pages = dp_prealloc_get_multi_pages,

+ 83 - 0
core/dp/txrx3.0/dp_txrx.c

@@ -211,6 +211,24 @@ struct dp_consistent_prealloc_unaligned {
 	qdf_dma_addr_t pa_unaligned;
 };
 
+/**
+ * struct dp_prealloc_context - element representing DP prealloc context memory
+ * @ctxt_type: DP context type
+ * @size: size of pre-alloc memory
+ * @in_use: check if element is being used
+ * @addr: address of memory allocated
+ */
+struct dp_prealloc_context {
+	enum dp_ctxt_type ctxt_type;
+	uint32_t size;
+	bool in_use;
+	void *addr;
+};
+
+static struct dp_prealloc_context g_dp_context_allocs[] = {
+	{DP_PDEV_TYPE, (sizeof(struct dp_pdev)), false,  NULL}
+};
+
 static struct  dp_consistent_prealloc g_dp_consistent_allocs[] = {
 	/* 5 REO DST rings */
 	{REO_DST, (sizeof(struct reo_destination_ring)) * REO_DST_RING_SIZE, 0, NULL, NULL, 0, 0},
@@ -338,6 +356,7 @@ static struct dp_consistent_prealloc_unaligned
 void dp_prealloc_deinit(void)
 {
 	int i;
+	struct dp_prealloc_context *cp;
 	struct dp_consistent_prealloc *p;
 	struct dp_multi_page_prealloc *mp;
 	struct dp_consistent_prealloc_unaligned *up;
@@ -399,11 +418,23 @@ void dp_prealloc_deinit(void)
 			qdf_mem_zero(up, sizeof(*up));
 		}
 	}
+
+	for (i = 0; i < QDF_ARRAY_SIZE(g_dp_context_allocs); i++) {
+		cp = &g_dp_context_allocs[i];
+		if (qdf_unlikely(up->in_use))
+			dp_warn("i %d: context in use while free", i);
+
+		if (cp->addr) {
+			qdf_mem_free(cp->addr);
+			cp->addr = NULL;
+		}
+	}
 }
 
 QDF_STATUS dp_prealloc_init(void)
 {
 	int i;
+	struct dp_prealloc_context *cp;
 	struct dp_consistent_prealloc *p;
 	struct dp_multi_page_prealloc *mp;
 	struct dp_consistent_prealloc_unaligned *up;
@@ -414,6 +445,23 @@ QDF_STATUS dp_prealloc_init(void)
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	/*Context pre-alloc*/
+	for (i = 0; i < QDF_ARRAY_SIZE(g_dp_context_allocs); i++) {
+		cp = &g_dp_context_allocs[i];
+		cp->addr = qdf_mem_malloc(cp->size);
+
+		if (qdf_unlikely(!cp->addr)) {
+			dp_warn("i %d: unable to preallocate %d bytes memory!",
+				i, cp->size);
+			break;
+		}
+	}
+
+	if (i != QDF_ARRAY_SIZE(g_dp_context_allocs)) {
+		dp_err("unable to allocate context memory!");
+		goto deinit;
+	}
+
 	for (i = 0; i < QDF_ARRAY_SIZE(g_dp_consistent_allocs); i++) {
 		p = &g_dp_consistent_allocs[i];
 		p->in_use = 0;
@@ -495,6 +543,41 @@ deinit:
 	return QDF_STATUS_E_FAILURE;
 }
 
+void *dp_prealloc_get_context_memory(uint32_t ctxt_type)
+{
+	int i;
+	struct dp_prealloc_context *cp;
+
+	for (i = 0; i < QDF_ARRAY_SIZE(g_dp_context_allocs); i++) {
+		cp = &g_dp_context_allocs[i];
+
+		if ((ctxt_type == cp->ctxt_type) && !cp->in_use) {
+			cp->in_use = true;
+			return cp->addr;
+		}
+	}
+
+	return NULL;
+}
+
+QDF_STATUS dp_prealloc_put_context_memory(uint32_t ctxt_type, void *vaddr)
+{
+	int i;
+	struct dp_prealloc_context *cp;
+
+	for (i = 0; i < QDF_ARRAY_SIZE(g_dp_context_allocs); i++) {
+		cp = &g_dp_context_allocs[i];
+
+		if ((ctxt_type == cp->ctxt_type) && vaddr == cp->addr) {
+			qdf_mem_zero(cp->addr, cp->size);
+			cp->in_use = false;
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 void *dp_prealloc_get_coherent(uint32_t *size, void **base_vaddr_unaligned,
 			       qdf_dma_addr_t *paddr_unaligned,
 			       qdf_dma_addr_t *paddr_aligned,

+ 25 - 0
core/dp/txrx3.0/dp_txrx.h

@@ -476,6 +476,31 @@ QDF_STATUS dp_prealloc_init(void);
  */
 void dp_prealloc_deinit(void);
 
+/**
+ * dp_prealloc_get_context_memory() - gets pre-alloc DP context memory from
+ *				      global pool
+ * @ctxt_type: type of DP context
+ *
+ * This is done only as part of init happening in a single context. Hence
+ * no lock is used for protection
+ *
+ * Return: Address of context
+ */
+void *dp_prealloc_get_context_memory(uint32_t ctxt_type);
+
+/**
+ * dp_prealloc_put_context_memory() - puts back pre-alloc DP context memory to
+ *				      global pool
+ * @ctxt_type: type of DP context
+ * @vaddr: address of DP context
+ *
+ * This is done only as part of de-init happening in a single context. Hence
+ * no lock is used for protection
+ *
+ * Return: Failure if address not found
+ */
+QDF_STATUS dp_prealloc_put_context_memory(uint32_t ctxt_type, void *vaddr);
+
 /**
  * dp_prealloc_get_coherent() - gets pre-alloc DP memory
  * @size: size of memory needed