Search Linux Wireless

[PATCH 05/10] ath11k: optimize RX path latency

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: John Crispin <john@xxxxxxxxxxx>

This patch drops ath11k_hal_rx_parse_dst_ring_desc(). This function was
creating a huge amount of load, which lead to a signifcant latency delay
when processing data in the RX path.

Pegging the processing on a specific core and running perf --top we get
the following output when running HE80 at a fixed bandwidth of 1gbit.

with patch
    19.19%  [ath11k]       [k] ath11k_dp_process_rx
     5.02%  [ath11k]       [k] ath11k_dp_rx_tid_del_func
     4.39%  [kernel]       [k] v7_dma_inv_range
     4.15%  [kernel]       [k] __slab_alloc.constprop.1
     4.03%  [kernel]       [k] dev_gro_receive
     3.86%  [kernel]       [k] tcp_gro_receive
     3.07%  [ip_tables]    [k] ipt_do_table
     2.96%  [kernel]       [k] dma_cache_maint_page

without patch
    21.64%  [ath11k]       [k] ath11k_hal_rx_parse_dst_ring_desc
    10.80%  [ath11k]       [k] ath11k_dp_process_rx
     3.77%  [kernel]       [k] v7_dma_inv_range
     3.48%  [kernel]       [k] dev_gro_receive
     3.32%  [ath11k]       [k] ath11k_dp_rx_tid_del_func
     3.17%  [mac80211]     [k] ieee80211_rx_napi
     2.70%  [kernel]       [k] dma_cache_maint_page
     2.65%  [mac80211]     [k] ieee80211_sta_ps_transition

When removing the the bandwidth limit and rerunning the test we see an
overall throughput improvement of 3-400mbit when running 4x4 HE80.

Signed-off-by: Shashidhar Lakkavalli <slakkavalli@xxxxxxxxx>
Signed-off-by: John Crispin <john@xxxxxxxxxxx>
Signed-off-by: Kalle Valo <kvalo@xxxxxxxxxxxxxx>
---
 drivers/net/wireless/ath/ath11k/dp_rx.c  | 47 ++++++++++++++++--------------
 drivers/net/wireless/ath/ath11k/hal_rx.c | 49 +++-----------------------------
 drivers/net/wireless/ath/ath11k/hal_rx.h | 28 +-----------------
 3 files changed, 31 insertions(+), 93 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 396658be6f26..321a2bb657e8 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -2124,7 +2124,6 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int mac_id,
 	struct ieee80211_rx_status *rx_status = &dp->rx_status;
 	struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
 	struct hal_srng *srng;
-	struct hal_rx_meta_info meta_info;
 	struct sk_buff *msdu;
 	struct sk_buff_head msdu_list;
 	struct sk_buff_head amsdu_list;
@@ -2160,11 +2159,14 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int mac_id,
 
 try_again:
 	while ((rx_desc = ath11k_hal_srng_dst_get_next_entry(ab, srng))) {
-		memset(&meta_info, 0, sizeof(meta_info));
-		ath11k_hal_rx_parse_dst_ring_desc(ab, rx_desc, &meta_info);
+		struct hal_reo_dest_ring *desc = (struct hal_reo_dest_ring *)rx_desc;
+		enum hal_reo_dest_ring_push_reason push_reason;
+		u32 cookie;
 
+		cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
+				   desc->buf_addr_info.info1);
 		buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,
-				   meta_info.msdu_meta.cookie);
+				   cookie);
 		spin_lock_bh(&rx_ring->idr_lock);
 		msdu = idr_find(&rx_ring->bufs_idr, buf_id);
 		if (!msdu) {
@@ -2184,7 +2186,9 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int mac_id,
 
 		num_buffs_reaped++;
 
-		if (meta_info.push_reason !=
+		push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,
+					desc->info0);
+		if (push_reason !=
 		    HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
 			/* TODO: Check if the msdu can be sent up for processing */
 			dev_kfree_skb_any(msdu);
@@ -2192,9 +2196,12 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int mac_id,
 			continue;
 		}
 
-		rxcb->is_first_msdu = meta_info.msdu_meta.first;
-		rxcb->is_last_msdu = meta_info.msdu_meta.last;
-		rxcb->is_continuation = meta_info.msdu_meta.continuation;
+		rxcb->is_first_msdu = !!(desc->rx_msdu_info.info0 &
+					 RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);
+		rxcb->is_last_msdu = !!(desc->rx_msdu_info.info0 &
+					RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
+		rxcb->is_continuation = !!(desc->rx_msdu_info.info0 &
+					   RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
 		rxcb->mac_id = mac_id;
 		__skb_queue_tail(&msdu_list, msdu);
 
@@ -2770,12 +2777,11 @@ ath11k_dp_process_rx_err_buf(struct ath11k *ar, struct napi_struct *napi,
 int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi,
 			     int budget)
 {
-	struct hal_rx_msdu_meta meta[HAL_NUM_RX_MSDUS_PER_LINK_DESC];
+	u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC];
 	struct dp_link_desc_bank *link_desc_banks;
 	enum hal_rx_buf_return_buf_manager rbm;
 	int tot_n_bufs_reaped, quota, ret, i;
 	int n_bufs_reaped[MAX_RADIOS] = {0};
-	struct hal_rx_meta_info meta_info;
 	struct dp_rxdma_ring *rx_ring;
 	struct dp_srng *reo_except;
 	u32 desc_bank, num_msdus;
@@ -2803,6 +2809,8 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi,
 
 	while (budget &&
 	       (desc = ath11k_hal_srng_dst_get_next_entry(ab, srng))) {
+		struct hal_reo_dest_ring *reo_desc = (struct hal_reo_dest_ring *)desc;
+
 		ab->soc_stats.err_ring_pkts++;
 		ret = ath11k_hal_desc_reo_parse_err(ab, desc, &paddr,
 						    &desc_bank);
@@ -2813,7 +2821,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi,
 		}
 		link_desc_va = link_desc_banks[desc_bank].vaddr +
 			       (paddr - link_desc_banks[desc_bank].paddr);
-		ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, meta,
+		ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies,
 						 &rbm);
 		if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST &&
 		    rbm != HAL_RX_BUF_RBM_SW3_BM) {
@@ -2824,10 +2832,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi,
 			continue;
 		}
 
-		memset(&meta_info, 0, sizeof(meta_info));
-		ath11k_hal_rx_parse_dst_ring_desc(ab, desc, &meta_info);
-
-		is_frag = meta_info.mpdu_meta.frag;
+		is_frag = !!(reo_desc->rx_mpdu_info.info0 & RX_MPDU_DESC_INFO0_FRAG_FLAG);
 
 		/* Return the link desc back to wbm idle list */
 		ath11k_dp_rx_link_desc_return(ab, desc,
@@ -2835,10 +2840,10 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi,
 
 		for (i = 0; i < num_msdus; i++) {
 			buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,
-					   meta[i].cookie);
+					   msdu_cookies[i]);
 
 			mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID,
-					   meta[i].cookie);
+					   msdu_cookies[i]);
 
 			ar = ab->pdevs[mac_id].ar;
 
@@ -3192,7 +3197,7 @@ int ath11k_dp_process_rxdma_err(struct ath11k_base *ab, int mac_id, int budget)
 	struct dp_rxdma_ring *rx_ring = &ar->dp.rx_refill_buf_ring;
 	struct dp_link_desc_bank *link_desc_banks = ab->dp.link_desc_banks;
 	struct hal_srng *srng;
-	struct hal_rx_msdu_meta meta[HAL_NUM_RX_MSDUS_PER_LINK_DESC];
+	u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC];
 	enum hal_rx_buf_return_buf_manager rbm;
 	enum hal_reo_entr_rxdma_ecode rxdma_err_code;
 	struct ath11k_skb_rxcb *rxcb;
@@ -3226,12 +3231,12 @@ int ath11k_dp_process_rxdma_err(struct ath11k_base *ab, int mac_id, int budget)
 
 		link_desc_va = link_desc_banks[desc_bank].vaddr +
 			       (paddr - link_desc_banks[desc_bank].paddr);
-		ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, meta,
-						 &rbm);
+		ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus,
+						 msdu_cookies, &rbm);
 
 		for (i = 0; i < num_msdus; i++) {
 			buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,
-					   meta[i].cookie);
+					   msdu_cookies[i]);
 
 			spin_lock_bh(&rx_ring->idr_lock);
 			skb = idr_find(&rx_ring->bufs_idr, buf_id);
diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c
index 2de4b388db20..6168a4eb0c0b 100644
--- a/drivers/net/wireless/ath/ath11k/hal_rx.c
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
@@ -290,7 +290,7 @@ void ath11k_hal_rx_buf_addr_info_get(void *desc, dma_addr_t *paddr,
 }
 
 void ath11k_hal_rx_msdu_link_info_get(void *link_desc, u32 *num_msdus,
-				      struct hal_rx_msdu_meta *meta,
+				      u32 *msdu_cookies,
 				      enum hal_rx_buf_return_buf_manager *rbm)
 {
 	struct hal_rx_msdu_link *link = (struct hal_rx_msdu_link *)link_desc;
@@ -311,17 +311,9 @@ void ath11k_hal_rx_msdu_link_info_get(void *link_desc, u32 *num_msdus,
 			*num_msdus = i;
 			break;
 		}
-		meta->msdu_len = FIELD_GET(RX_MSDU_DESC_INFO0_MSDU_LENGTH,
-					   msdu->rx_msdu_info.info0);
-		meta->first = !!(msdu->rx_msdu_info.info0 &
-				 RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);
-		meta->last = !!(msdu->rx_msdu_info.info0 &
-				RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
-		meta->continuation = !!(msdu->rx_msdu_info.info0 &
-					RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
-		meta->cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
-					 msdu->buf_addr_info.info1);
-		meta++;
+		*msdu_cookies = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
+					  msdu->buf_addr_info.info1);
+		msdu_cookies++;
 	}
 }
 
@@ -356,39 +348,6 @@ int ath11k_hal_desc_reo_parse_err(struct ath11k_base *ab, u32 *rx_desc,
 	return 0;
 }
 
-void ath11k_hal_rx_parse_dst_ring_desc(struct ath11k_base *ab, u32 *rx_desc,
-				       struct hal_rx_meta_info *meta_info)
-{
-	struct hal_reo_dest_ring *desc = (struct hal_reo_dest_ring *)rx_desc;
-	struct rx_mpdu_desc *mpdu = &desc->rx_mpdu_info;
-	struct rx_msdu_desc *msdu = &desc->rx_msdu_info;
-	struct hal_rx_mpdu_meta *meta_mpdu = &meta_info->mpdu_meta;
-	struct hal_rx_msdu_meta *meta_msdu = &meta_info->msdu_meta;
-
-	meta_info->push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,
-					   desc->info0);
-
-	meta_mpdu->msdu_cnt = FIELD_GET(RX_MPDU_DESC_INFO0_MSDU_COUNT,
-					mpdu->info0);
-	meta_mpdu->seq_num = FIELD_GET(RX_MPDU_DESC_INFO0_SEQ_NUM, mpdu->info0);
-	meta_mpdu->frag = !!(mpdu->info0 & RX_MPDU_DESC_INFO0_FRAG_FLAG);
-	meta_mpdu->retry = !!(mpdu->info0 & RX_MPDU_DESC_INFO0_MPDU_RETRY);
-	meta_mpdu->ampdu = !!(mpdu->info0 & RX_MPDU_DESC_INFO0_AMPDU_FLAG);
-	meta_mpdu->raw = !!(mpdu->info0 & RX_MPDU_DESC_INFO0_RAW_MPDU);
-	meta_mpdu->peer_meta = mpdu->meta_data;
-
-	meta_msdu->cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
-				      desc->buf_addr_info.info1);
-	meta_msdu->msdu_len = FIELD_GET(RX_MSDU_DESC_INFO0_MSDU_LENGTH,
-					msdu->info0);
-	meta_msdu->first =
-		!!(msdu->info0 & RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);
-	meta_msdu->last =
-		!!(msdu->info0 & RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
-	meta_msdu->continuation =
-		!!(msdu->info0 & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
-}
-
 int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc,
 				  struct hal_rx_wbm_rel_info *rel_info)
 {
diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.h b/drivers/net/wireless/ath/ath11k/hal_rx.h
index 96555e4f4ef3..2271bf56183b 100644
--- a/drivers/net/wireless/ath/ath11k/hal_rx.h
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.h
@@ -6,30 +6,6 @@
 #ifndef ATH11K_HAL_RX_H
 #define ATH11K_HAL_RX_H
 
-struct hal_rx_mpdu_meta {
-	u32 peer_meta;
-	u16 msdu_cnt;
-	u16 seq_num;
-	bool frag;
-	bool retry;
-	bool ampdu;
-	bool raw;
-};
-
-struct hal_rx_msdu_meta {
-	u32 cookie;
-	u32 msdu_len;
-	bool first;
-	bool last;
-	bool continuation;
-};
-
-struct hal_rx_meta_info {
-	enum hal_reo_dest_ring_push_reason push_reason;
-	struct hal_rx_mpdu_meta mpdu_meta;
-	struct hal_rx_msdu_meta msdu_meta;
-};
-
 struct hal_rx_wbm_rel_info {
 	u32 cookie;
 	enum hal_wbm_rel_src_module err_rel_src;
@@ -320,7 +296,7 @@ void ath11k_hal_reo_update_rx_reo_queue_status(struct ath11k_base *ab,
 					       struct hal_reo_status *status);
 int ath11k_hal_reo_process_status(u8 *reo_desc, u8 *status);
 void ath11k_hal_rx_msdu_link_info_get(void *link_desc, u32 *num_msdus,
-				      struct hal_rx_msdu_meta *meta,
+				      u32 *msdu_cookies,
 				      enum hal_rx_buf_return_buf_manager *rbm);
 void ath11k_hal_rx_msdu_link_desc_set(struct ath11k_base *ab, void *desc,
 				      void *link_desc,
@@ -331,8 +307,6 @@ void ath11k_hal_rx_buf_addr_info_get(void *desc, dma_addr_t *paddr,
 				     u32 *cookie, u8 *rbm);
 int ath11k_hal_desc_reo_parse_err(struct ath11k_base *ab, u32 *rx_desc,
 				  dma_addr_t *paddr, u32 *desc_bank);
-void ath11k_hal_rx_parse_dst_ring_desc(struct ath11k_base *ab, u32 *rx_desc,
-				       struct hal_rx_meta_info *meta_info);
 int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc,
 				  struct hal_rx_wbm_rel_info *rel_info);
 void ath11k_hal_rx_reo_ent_paddr_get(struct ath11k_base *ab, void *desc,
-- 
2.7.4




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux