Jelajahi Sumber

qcacmn: qref debug memory tracker

add multiple history array to keep track of mem allocation and
deallocation for qref table.

Change-Id: I9fa97fbe5a5c36509cbb5a458851a152200318a5
CRs-Fixed: 3475981
Ruben Columbus 2 tahun lalu
induk
melakukan
d8334769f4

+ 42 - 0
dp/wifi3.0/dp_main.c

@@ -170,6 +170,7 @@ QDF_COMPILE_TIME_ASSERT(wlan_cfg_num_int_ctxs,
 			WLAN_CFG_INT_NUM_CONTEXTS_MAX >=
 			WLAN_CFG_INT_NUM_CONTEXTS);
 
+static void dp_soc_unset_qref_debug_list(struct dp_soc *soc);
 static QDF_STATUS dp_sysfs_deinitialize_stats(struct dp_soc *soc_hdl);
 static QDF_STATUS dp_sysfs_initialize_stats(struct dp_soc *soc_hdl);
 
@@ -2993,6 +2994,7 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc)
 
 	dp_runtime_deinit();
 
+	dp_soc_unset_qref_debug_list(soc);
 	dp_sysfs_deinitialize_stats(soc);
 	dp_soc_swlm_detach(soc);
 	dp_soc_tx_desc_sw_pools_free(soc);
@@ -12062,6 +12064,7 @@ static void dp_soc_txrx_ops_attach(struct dp_soc *soc)
 #if defined(QCA_WIFI_QCA8074) || defined(QCA_WIFI_QCA6018) || \
 	defined(QCA_WIFI_QCA5018) || defined(QCA_WIFI_QCA9574) || \
 	defined(QCA_WIFI_QCA5332)
+
 /**
  * dp_soc_attach_wifi3() - Attach txrx SOC
  * @ctrl_psoc: Opaque SOC handle from control plane
@@ -12091,6 +12094,44 @@ static inline void dp_soc_set_def_pdev(struct dp_soc *soc)
 	}
 }
 
+static void dp_soc_unset_qref_debug_list(struct dp_soc *soc)
+{
+	uint32_t max_list_size = soc->wlan_cfg_ctx->qref_control_size;
+
+	if (max_list_size == 0)
+		return;
+
+	qdf_mem_free(soc->list_shared_qaddr_del);
+	qdf_mem_free(soc->reo_write_list);
+	qdf_mem_free(soc->list_qdesc_addr_free);
+	qdf_mem_free(soc->list_qdesc_addr_alloc);
+}
+
+static void dp_soc_set_qref_debug_list(struct dp_soc *soc)
+{
+	uint32_t max_list_size = soc->wlan_cfg_ctx->qref_control_size;
+
+	if (max_list_size == 0)
+		return;
+
+	soc->list_shared_qaddr_del =
+			(struct test_qaddr_del *)
+				qdf_mem_malloc(sizeof(struct test_qaddr_del) *
+					       max_list_size);
+	soc->reo_write_list =
+			(struct test_qaddr_del *)
+				qdf_mem_malloc(sizeof(struct test_qaddr_del) *
+					       max_list_size);
+	soc->list_qdesc_addr_free =
+			(struct test_mem_free *)
+				qdf_mem_malloc(sizeof(struct test_mem_free) *
+					       max_list_size);
+	soc->list_qdesc_addr_alloc =
+			(struct test_mem_free *)
+				qdf_mem_malloc(sizeof(struct test_mem_free) *
+					       max_list_size);
+}
+
 static uint32_t
 dp_get_link_desc_id_start(uint16_t arch_id)
 {
@@ -12250,6 +12291,7 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
 	dp_soc_swlm_attach(soc);
 	dp_soc_set_interrupt_mode(soc);
 	dp_soc_set_def_pdev(soc);
+	dp_soc_set_qref_debug_list(soc);
 
 	dp_info("Mem stats: DMA = %u HEAP = %u SKB = %u",
 		qdf_dma_mem_stats_read(),

+ 26 - 1
dp/wifi3.0/dp_peer.c

@@ -2488,6 +2488,9 @@ void dp_peer_rx_reo_shared_qaddr_delete(struct dp_soc *soc,
 {
 	uint8_t tid;
 	uint16_t peer_id;
+	uint32_t max_list_size;
+
+	max_list_size = soc->wlan_cfg_ctx->qref_control_size;
 
 	peer_id = peer->peer_id;
 
@@ -2495,10 +2498,30 @@ void dp_peer_rx_reo_shared_qaddr_delete(struct dp_soc *soc,
 		return;
 	if (IS_MLO_DP_LINK_PEER(peer))
 		return;
+
+	if (max_list_size) {
+		unsigned long curr_ts = qdf_get_system_timestamp();
+		struct dp_peer *primary_peer = peer;
+		uint16_t chip_id = 0xFFFF;
+		uint32_t qref_index;
+
+		qref_index = soc->shared_qaddr_del_idx;
+
+		soc->list_shared_qaddr_del[qref_index].peer_id =
+							  primary_peer->peer_id;
+		soc->list_shared_qaddr_del[qref_index].ts_qaddr_del = curr_ts;
+		soc->list_shared_qaddr_del[qref_index].chip_id = chip_id;
+		soc->shared_qaddr_del_idx++;
+
+		if (soc->shared_qaddr_del_idx == max_list_size)
+			soc->shared_qaddr_del_idx = 0;
+	}
+
 	if (hal_reo_shared_qaddr_is_enable(soc->hal_soc)) {
-		for (tid = 0; tid < DP_MAX_TIDS; tid++)
+		for (tid = 0; tid < DP_MAX_TIDS; tid++) {
 			hal_reo_shared_qaddr_write(soc->hal_soc,
 						   peer_id, tid, 0);
+		}
 	}
 }
 #endif
@@ -2838,10 +2861,12 @@ dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id,
 			if (hal_reo_shared_qaddr_is_enable(soc->hal_soc) &&
 			    peer->rx_tid[0].hw_qdesc_vaddr_unaligned &&
 			    !IS_MLO_DP_LINK_PEER(peer)) {
+				add_entry_write_list(soc, peer, 0);
 				hal_reo_shared_qaddr_write(soc->hal_soc,
 							   peer_id,
 							   0,
 							   peer->rx_tid[0].hw_qdesc_paddr);
+				add_entry_write_list(soc, peer, DP_NON_QOS_TID);
 				hal_reo_shared_qaddr_write(soc->hal_soc,
 							   peer_id,
 							   DP_NON_QOS_TID,

+ 78 - 0
dp/wifi3.0/dp_peer.h

@@ -48,6 +48,84 @@
 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_INFO_HIGH, QDF_MODULE_ID_DP_PEER, ## params)
 #define dp_peer_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_DP_PEER, params)
 
+void check_free_list_for_invalid_flush(struct dp_soc *soc);
+
+static inline
+void add_entry_alloc_list(struct dp_soc *soc, struct dp_rx_tid *rx_tid,
+			  struct dp_peer *peer, void *hw_qdesc_vaddr)
+{
+	uint32_t max_list_size;
+	unsigned long curr_ts = qdf_get_system_timestamp();
+	uint32_t qref_index = soc->free_addr_list_idx;
+
+	max_list_size = soc->wlan_cfg_ctx->qref_control_size;
+
+	if (max_list_size == 0)
+		return;
+
+	soc->list_qdesc_addr_alloc[qref_index].hw_qdesc_paddr =
+							 rx_tid->hw_qdesc_paddr;
+	soc->list_qdesc_addr_alloc[qref_index].ts_qdesc_mem_hdl = curr_ts;
+	soc->list_qdesc_addr_alloc[qref_index].hw_qdesc_vaddr_align =
+								 hw_qdesc_vaddr;
+	soc->list_qdesc_addr_alloc[qref_index].hw_qdesc_vaddr_unalign =
+					       rx_tid->hw_qdesc_vaddr_unaligned;
+	soc->list_qdesc_addr_alloc[qref_index].peer_id = peer->peer_id;
+	soc->list_qdesc_addr_alloc[qref_index].tid = rx_tid->tid;
+	soc->alloc_addr_list_idx++;
+
+	if (soc->alloc_addr_list_idx == max_list_size)
+		soc->alloc_addr_list_idx = 0;
+}
+
+static inline
+void add_entry_free_list(struct dp_soc *soc, struct dp_rx_tid *rx_tid)
+{
+	uint32_t max_list_size;
+	unsigned long curr_ts = qdf_get_system_timestamp();
+	uint32_t qref_index = soc->free_addr_list_idx;
+
+	max_list_size = soc->wlan_cfg_ctx->qref_control_size;
+
+	if (max_list_size == 0)
+		return;
+
+	soc->list_qdesc_addr_free[qref_index].ts_qdesc_mem_hdl = curr_ts;
+	soc->list_qdesc_addr_free[qref_index].hw_qdesc_paddr =
+							 rx_tid->hw_qdesc_paddr;
+	soc->list_qdesc_addr_free[qref_index].hw_qdesc_vaddr_align =
+						 rx_tid->hw_qdesc_vaddr_aligned;
+	soc->list_qdesc_addr_free[qref_index].hw_qdesc_vaddr_unalign =
+					       rx_tid->hw_qdesc_vaddr_unaligned;
+	soc->free_addr_list_idx++;
+
+	if (soc->free_addr_list_idx == max_list_size)
+		soc->free_addr_list_idx = 0;
+}
+
+static inline
+void add_entry_write_list(struct dp_soc *soc, struct dp_peer *peer,
+			  uint32_t tid)
+{
+	uint32_t max_list_size;
+	unsigned long curr_ts = qdf_get_system_timestamp();
+
+	max_list_size = soc->wlan_cfg_ctx->qref_control_size;
+
+	if (max_list_size == 0)
+		return;
+
+	soc->reo_write_list[soc->write_paddr_list_idx].ts_qaddr_del = curr_ts;
+	soc->reo_write_list[soc->write_paddr_list_idx].peer_id = peer->peer_id;
+	soc->reo_write_list[soc->write_paddr_list_idx].paddr =
+					       peer->rx_tid[tid].hw_qdesc_paddr;
+	soc->reo_write_list[soc->write_paddr_list_idx].tid = tid;
+	soc->write_paddr_list_idx++;
+
+	if (soc->write_paddr_list_idx == max_list_size)
+		soc->write_paddr_list_idx = 0;
+}
+
 #ifdef REO_QDESC_HISTORY
 enum reo_qdesc_event_type {
 	REO_QDESC_UPDATE_CB = 0,

+ 33 - 0
dp/wifi3.0/dp_rx_tid.c

@@ -484,6 +484,33 @@ static void dp_reo_desc_defer_free(struct dp_soc *soc)
 }
 #endif /* !WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY */
 
+void check_free_list_for_invalid_flush(struct dp_soc *soc)
+{
+	uint32_t i;
+	uint32_t *addr_deref_val;
+	unsigned long curr_ts = qdf_get_system_timestamp();
+	uint32_t max_list_size;
+
+	max_list_size = soc->wlan_cfg_ctx->qref_control_size;
+
+	if (max_list_size == 0)
+		return;
+
+	for (i = 0; i < soc->free_addr_list_idx; i++) {
+		addr_deref_val = (uint32_t *)
+			    soc->list_qdesc_addr_free[i].hw_qdesc_vaddr_unalign;
+
+		if (*addr_deref_val == 0xDDBEEF84 ||
+		    *addr_deref_val == 0xADBEEF84 ||
+		    *addr_deref_val == 0xBDBEEF84 ||
+		    *addr_deref_val == 0xCDBEEF84) {
+			if (soc->list_qdesc_addr_free[i].ts_hw_flush_back == 0)
+				soc->list_qdesc_addr_free[i].ts_hw_flush_back =
+									curr_ts;
+		}
+	}
+}
+
 /**
  * dp_reo_desc_free() - Callback free reo descriptor memory after
  * HW cache flush
@@ -519,12 +546,16 @@ static void dp_reo_desc_free(struct dp_soc *soc, void *cb_ctxt,
 		goto out;
 
 	DP_RX_REO_QDESC_FREE_EVT(freedesc);
+	add_entry_free_list(soc, rx_tid);
 
 	hal_reo_shared_qaddr_cache_clear(soc->hal_soc);
 	qdf_mem_unmap_nbytes_single(soc->osdev,
 				    rx_tid->hw_qdesc_paddr,
 				    QDF_DMA_BIDIRECTIONAL,
 				    rx_tid->hw_qdesc_alloc_size);
+	check_free_list_for_invalid_flush(soc);
+
+	*(uint32_t *)rx_tid->hw_qdesc_vaddr_unaligned = 0;
 	qdf_mem_free(rx_tid->hw_qdesc_vaddr_unaligned);
 out:
 	qdf_mem_free(freedesc);
@@ -673,6 +704,8 @@ try_desc_alloc:
 		QDF_DMA_BIDIRECTIONAL, rx_tid->hw_qdesc_alloc_size,
 		&(rx_tid->hw_qdesc_paddr));
 
+	add_entry_alloc_list(soc, rx_tid, peer, hw_qdesc_vaddr);
+
 	if (dp_reo_desc_addr_chk(rx_tid->hw_qdesc_paddr) !=
 			QDF_STATUS_SUCCESS) {
 		if (alloc_tries++ < 10) {

+ 27 - 0
dp/wifi3.0/dp_types.h

@@ -2556,6 +2556,25 @@ struct sysfs_stats_config {
 };
 #endif
 
+struct test_mem_free {
+	unsigned long ts_qdesc_mem_hdl;
+	qdf_dma_addr_t hw_qdesc_paddr;
+	void *hw_qdesc_vaddr_align;
+	void *hw_qdesc_vaddr_unalign;
+	uint32_t peer_id;
+	uint32_t tid;
+	uint8_t chip_id;
+	unsigned long ts_hw_flush_back;
+};
+
+struct test_qaddr_del {
+	unsigned long ts_qaddr_del;
+	uint32_t peer_id;
+	uint32_t paddr;
+	uint32_t tid;
+	uint8_t chip_id;
+};
+
 /* SOC level structure for data path */
 struct dp_soc {
 	/**
@@ -3112,6 +3131,14 @@ struct dp_soc {
 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
 	uint8_t mld_mode_ap;
 #endif
+	struct test_qaddr_del *list_shared_qaddr_del;
+	struct test_qaddr_del *reo_write_list;
+	struct test_mem_free *list_qdesc_addr_free;
+	struct test_mem_free *list_qdesc_addr_alloc;
+	uint64_t free_addr_list_idx;
+	uint64_t alloc_addr_list_idx;
+	uint64_t shared_qaddr_del_idx;
+	uint64_t write_paddr_list_idx;
 };
 
 #ifdef IPA_OFFLOAD

+ 13 - 0
wlan_cfg/cfg_dp.h

@@ -100,6 +100,8 @@
 
 #define WLAN_CFG_TIME_CONTROL_BP 3000
 
+#define WLAN_CFG_QREF_CONTROL_SIZE 0
+
 #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1)
 #define WLAN_CFG_PER_PDEV_RX_RING 0
 #define WLAN_CFG_PER_PDEV_LMAC_RING 0
@@ -178,6 +180,9 @@
 #define WLAN_CFG_TIME_CONTROL_BP_MIN 3000
 #define WLAN_CFG_TIME_CONTROL_BP_MAX 1800000
 
+#define WLAN_CFG_QREF_CONTROL_SIZE_MIN 0
+#define WLAN_CFG_QREF_CONTROL_SIZE_MAX 4000
+
 #define WLAN_CFG_TX_COMP_RING_SIZE_MIN 512
 #define WLAN_CFG_TX_COMP_RING_SIZE_MAX 0x80000
 
@@ -760,6 +765,13 @@
 		WLAN_CFG_TIME_CONTROL_BP,\
 		CFG_VALUE_OR_DEFAULT, "DP time control back pressure")
 
+#define CFG_DP_QREF_CONTROL_SIZE \
+		CFG_INI_UINT("dp_qref_control_size", \
+		WLAN_CFG_QREF_CONTROL_SIZE_MIN,\
+		WLAN_CFG_QREF_CONTROL_SIZE_MAX,\
+		WLAN_CFG_QREF_CONTROL_SIZE,\
+		CFG_VALUE_OR_DEFAULT, "DP array size for qref debug")
+
 #ifdef CONFIG_SAWF_STATS
 #define CFG_DP_SAWF_STATS \
 		CFG_INI_UINT("dp_sawf_stats", \
@@ -1985,6 +1997,7 @@
 		CFG(CFG_DP_NSS_COMP_RING_SIZE) \
 		CFG(CFG_DP_PDEV_LMAC_RING) \
 		CFG(CFG_DP_TIME_CONTROL_BP) \
+		CFG(CFG_DP_QREF_CONTROL_SIZE) \
 		CFG(CFG_DP_BASE_HW_MAC_ID) \
 		CFG(CFG_DP_RX_HASH) \
 		CFG(CFG_DP_RX_RR) \

+ 7 - 0
wlan_cfg/wlan_cfg.c

@@ -4081,6 +4081,8 @@ wlan_cfg_soc_attach(struct cdp_ctrl_objmgr_psoc *psoc)
 
 	wlan_cfg_ctx->tx_ring_size = cfg_get(psoc, CFG_DP_TX_RING_SIZE);
 	wlan_cfg_ctx->time_control_bp = cfg_get(psoc, CFG_DP_TIME_CONTROL_BP);
+	wlan_cfg_ctx->qref_control_size =
+					cfg_get(psoc, CFG_DP_QREF_CONTROL_SIZE);
 	wlan_cfg_ctx->tx_comp_ring_size = cfg_get(psoc,
 						  CFG_DP_TX_COMPL_RING_SIZE);
 
@@ -4693,6 +4695,11 @@ int wlan_cfg_time_control_bp(struct wlan_cfg_dp_soc_ctxt *cfg)
 	return cfg->time_control_bp;
 }
 
+int wlan_cfg_qref_control_size(struct wlan_cfg_dp_soc_ctxt *cfg)
+{
+	return cfg->qref_control_size;
+}
+
 int wlan_cfg_tx_comp_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg)
 {
 	return cfg->tx_comp_ring_size;

+ 10 - 0
wlan_cfg/wlan_cfg.h

@@ -176,6 +176,7 @@ struct wlan_srng_cfg {
  * @int_timer_threshold_mon:
  * @tx_ring_size:
  * @time_control_bp:
+ * @qref_control_size: list size for memory history arrays
  * @tx_comp_ring_size:
  * @tx_comp_ring_size_nss:
  * @int_rx_mon_ring_mask: Bitmap of Rx monitor ring interrupts mapped to each
@@ -376,6 +377,7 @@ struct wlan_cfg_dp_soc_ctxt {
 	int int_timer_threshold_mon;
 	int tx_ring_size;
 	int time_control_bp;
+	int qref_control_size;
 	int tx_comp_ring_size;
 	int tx_comp_ring_size_nss;
 	uint8_t int_tx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
@@ -1580,6 +1582,14 @@ void wlan_cfg_set_tx_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg,
  */
 int wlan_cfg_time_control_bp(struct wlan_cfg_dp_soc_ctxt *cfg);
 
+/**
+ * wlan_cfg_qref_control_size - Get debug array size
+ * @cfg: soc configuration context
+ *
+ * Return: array size
+ */
+int wlan_cfg_qref_control_size(struct wlan_cfg_dp_soc_ctxt *cfg);
+
 /**
  * wlan_cfg_tx_comp_ring_size - Get Tx completion ring size (WBM Ring)
  * @cfg: soc configuration context