mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 10:51:27 +00:00
267 lines
8.3 KiB
Diff
267 lines
8.3 KiB
Diff
From 0fe4a7f57a44a0aaad6fb1d6861c9fb9597358a2 Mon Sep 17 00:00:00 2001
|
|
From: P Praneesh <ppranees@codeaurora.org>
|
|
Date: Tue, 15 Dec 2020 11:27:48 +0530
|
|
Subject: [PATCH] ath11k: optimizations in ath11k_dp_process_rx()
|
|
|
|
Incaludes below changes,
|
|
1. Increment total_msdu_reaped only when continuation is not set and update
|
|
drop flag correspondingly. This is to avoid additional access to ath11k_hal_srng_dst_num_free()
|
|
2. Avoid descriptor memcpy as the data is prefetched already
|
|
3. The Active Pdev and CAC check are done for each msdu in ath11k_dp_rx_process_received_packets
|
|
Rather, collect all msdu's in a per mac msdu list, and pass to the function.
|
|
4. Add branch predictors where required in the process rx()
|
|
5. Remove usage of quota variable since we add only max napi budget msdus to the list
|
|
6. Prefetch the initial descriptor part which is used by all the hw ops for msdu info collection.
|
|
|
|
About 3-4% improvement on single radio UDP UL on single core was seen.
|
|
More validation/confirmation on perf stats required.
|
|
|
|
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
|
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
|
---
|
|
drivers/net/wireless/ath/ath11k/dp_rx.c | 107 ++++++++++++++++----------------
|
|
1 file changed, 55 insertions(+), 52 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
@@ -2856,6 +2856,9 @@ static int ath11k_dp_rx_process_msdu(str
|
|
int ret;
|
|
u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;
|
|
|
|
+ /* Prefetch the full descriptor range before hdr status into cache */
|
|
+ prefetch_range(msdu->data, 256);
|
|
+
|
|
last_buf = ath11k_dp_rx_get_msdu_last_buf(msdu_list, msdu);
|
|
if (!last_buf) {
|
|
ath11k_warn(ab,
|
|
@@ -2920,10 +2923,8 @@ static int ath11k_dp_rx_process_msdu(str
|
|
}
|
|
|
|
ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status, fast_rx);
|
|
- if (*fast_rx) {
|
|
- ab->soc_stats.invalid_rbm++;
|
|
+ if (*fast_rx)
|
|
return 0;
|
|
- }
|
|
|
|
ath11k_dp_rx_h_ppdu(ar, rx_desc, rx_status);
|
|
|
|
@@ -2938,13 +2939,12 @@ free_out:
|
|
static void ath11k_dp_rx_process_received_packets(struct ath11k_base *ab,
|
|
struct napi_struct *napi,
|
|
struct sk_buff_head *msdu_list,
|
|
- int *quota, int ring_id)
|
|
+ int mac_id)
|
|
{
|
|
struct ath11k_skb_rxcb *rxcb;
|
|
struct sk_buff *msdu;
|
|
struct ath11k *ar;
|
|
struct ieee80211_rx_status rx_status = {0};
|
|
- u8 mac_id;
|
|
int ret;
|
|
bool fast_rx;
|
|
|
|
@@ -2953,26 +2953,28 @@ static void ath11k_dp_rx_process_receive
|
|
|
|
rcu_read_lock();
|
|
|
|
- while (*quota && (msdu = __skb_dequeue(msdu_list))) {
|
|
- rxcb = ATH11K_SKB_RXCB(msdu);
|
|
- mac_id = rxcb->mac_id;
|
|
- ar = ab->pdevs[mac_id].ar;
|
|
- if (!rcu_dereference(ab->pdevs_active[mac_id])) {
|
|
- dev_kfree_skb_any(msdu);
|
|
- continue;
|
|
- }
|
|
|
|
- if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) {
|
|
- dev_kfree_skb_any(msdu);
|
|
- continue;
|
|
- }
|
|
+ ar = ab->pdevs[mac_id].ar;
|
|
+ if (unlikely(!rcu_dereference(ab->pdevs_active[mac_id]))) {
|
|
+ __skb_queue_purge(msdu_list);
|
|
+ rcu_read_unlock();
|
|
+ return;
|
|
+ }
|
|
|
|
+ if (unlikely(test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags))) {
|
|
+ __skb_queue_purge(msdu_list);
|
|
+ rcu_read_unlock();
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ while ((msdu = __skb_dequeue(msdu_list))) {
|
|
+ rxcb = ATH11K_SKB_RXCB(msdu);
|
|
/* Enable fast rx by default, the value will cahnge based on peer cap
|
|
* and packet type */
|
|
fast_rx = true;
|
|
rxcb->napi = napi;
|
|
ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status, &fast_rx);
|
|
- if (ret) {
|
|
+ if (unlikely(ret)) {
|
|
ath11k_dbg(ab, ATH11K_DBG_DATA,
|
|
"Unable to process msdu %d", ret);
|
|
dev_kfree_skb_any(msdu);
|
|
@@ -2982,8 +2984,6 @@ static void ath11k_dp_rx_process_receive
|
|
/* msdu is already delivered directectly */
|
|
if (!fast_rx)
|
|
ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status);
|
|
-
|
|
- (*quota)--;
|
|
}
|
|
|
|
rcu_read_unlock();
|
|
@@ -2995,22 +2995,24 @@ int ath11k_dp_process_rx(struct ath11k_b
|
|
struct ath11k_dp *dp = &ab->dp;
|
|
struct dp_rxdma_ring *rx_ring;
|
|
int num_buffs_reaped[MAX_RADIOS] = {0};
|
|
- struct sk_buff_head msdu_list;
|
|
+ struct sk_buff_head msdu_list[MAX_RADIOS];
|
|
struct ath11k_skb_rxcb *rxcb;
|
|
int total_msdu_reaped = 0;
|
|
struct hal_srng *srng;
|
|
struct sk_buff *msdu;
|
|
struct ath11k_peer *peer = NULL;
|
|
struct ath11k_sta *arsta = NULL;
|
|
- int quota = budget;
|
|
bool done = false;
|
|
int buf_id, mac_id;
|
|
struct ath11k *ar;
|
|
- u32 *rx_desc;
|
|
+ struct hal_reo_dest_ring *desc;
|
|
+ enum hal_reo_dest_ring_push_reason push_reason;
|
|
+ u32 cookie;
|
|
int i;
|
|
|
|
- __skb_queue_head_init(&msdu_list);
|
|
|
|
+ for (i = 0; i < MAX_RADIOS; i++)
|
|
+ __skb_queue_head_init(&msdu_list[i]);
|
|
srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id];
|
|
|
|
spin_lock_bh(&srng->lock);
|
|
@@ -3018,13 +3020,9 @@ int ath11k_dp_process_rx(struct ath11k_b
|
|
ath11k_hal_srng_access_begin(ab, srng);
|
|
|
|
try_again:
|
|
- while ((rx_desc = ath11k_hal_srng_dst_get_next_entry(ab, srng))) {
|
|
- struct hal_reo_dest_ring desc = *(struct hal_reo_dest_ring *)rx_desc;
|
|
- enum hal_reo_dest_ring_push_reason push_reason;
|
|
- u32 cookie;
|
|
-
|
|
+ while (likely(desc = (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, srng))) {
|
|
cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
|
|
- desc.buf_addr_info.info1);
|
|
+ desc->buf_addr_info.info1);
|
|
buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,
|
|
cookie);
|
|
mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);
|
|
@@ -3033,7 +3031,7 @@ try_again:
|
|
rx_ring = &ar->dp.rx_refill_buf_ring;
|
|
spin_lock_bh(&rx_ring->idr_lock);
|
|
msdu = idr_find(&rx_ring->bufs_idr, buf_id);
|
|
- if (!msdu) {
|
|
+ if (unlikely(!msdu)) {
|
|
ath11k_warn(ab, "frame rx with invalid buf_id %d\n",
|
|
buf_id);
|
|
spin_unlock_bh(&rx_ring->idr_lock);
|
|
@@ -3049,29 +3047,28 @@ try_again:
|
|
DMA_FROM_DEVICE);
|
|
|
|
num_buffs_reaped[mac_id]++;
|
|
- total_msdu_reaped++;
|
|
|
|
push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,
|
|
- desc.info0);
|
|
- if (push_reason !=
|
|
- HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
|
|
+ desc->info0);
|
|
+ if (unlikely(push_reason !=
|
|
+ HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) {
|
|
dev_kfree_skb_any(msdu);
|
|
ab->soc_stats.hal_reo_error[dp->reo_dst_ring[ring_id].ring_id]++;
|
|
continue;
|
|
}
|
|
|
|
- rxcb->is_first_msdu = !!(desc.rx_msdu_info.info0 &
|
|
+ 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 &
|
|
+ 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 &
|
|
+ rxcb->is_continuation = !!(desc->rx_msdu_info.info0 &
|
|
RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
|
|
rxcb->peer_id = FIELD_GET(RX_MPDU_DESC_META_DATA_PEER_ID,
|
|
- desc.rx_mpdu_info.meta_data);
|
|
+ desc->rx_mpdu_info.meta_data);
|
|
rxcb->seq_no = FIELD_GET(RX_MPDU_DESC_INFO0_SEQ_NUM,
|
|
- desc.rx_mpdu_info.info0);
|
|
+ desc->rx_mpdu_info.info0);
|
|
rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM,
|
|
- desc.info0);
|
|
+ desc->info0);
|
|
|
|
if (ath11k_debugfs_is_extd_rx_stats_enabled(ar) && rxcb->peer_id) {
|
|
rcu_read_lock();
|
|
@@ -3087,12 +3084,17 @@ try_again:
|
|
}
|
|
|
|
rxcb->mac_id = mac_id;
|
|
- __skb_queue_tail(&msdu_list, msdu);
|
|
+ __skb_queue_tail(&msdu_list[mac_id], msdu);
|
|
|
|
- if (total_msdu_reaped >= quota && !rxcb->is_continuation) {
|
|
+ if (!rxcb->is_continuation) {
|
|
+ total_msdu_reaped++;
|
|
done = true;
|
|
- break;
|
|
+ } else {
|
|
+ done = false;
|
|
}
|
|
+
|
|
+ if (total_msdu_reaped >= budget)
|
|
+ break;
|
|
}
|
|
|
|
/* Hw might have updated the head pointer after we cached it.
|
|
@@ -3101,7 +3103,7 @@ try_again:
|
|
* head pointer so that we can reap complete MPDU in the current
|
|
* rx processing.
|
|
*/
|
|
- if (!done && ath11k_hal_srng_dst_num_valid(ab, srng, true)) {
|
|
+ if (unlikely(!done && ath11k_hal_srng_dst_num_valid(ab, srng, true))) {
|
|
ath11k_hal_srng_access_end(ab, srng);
|
|
goto try_again;
|
|
}
|
|
@@ -3110,13 +3112,14 @@ try_again:
|
|
|
|
spin_unlock_bh(&srng->lock);
|
|
|
|
- if (!total_msdu_reaped)
|
|
+ if (unlikely(!total_msdu_reaped))
|
|
goto exit;
|
|
|
|
for (i = 0; i < ab->num_radios; i++) {
|
|
if (!num_buffs_reaped[i])
|
|
continue;
|
|
|
|
+ ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list[i], i);
|
|
ar = ab->pdevs[i].ar;
|
|
rx_ring = &ar->dp.rx_refill_buf_ring;
|
|
|
|
@@ -3124,11 +3127,8 @@ try_again:
|
|
HAL_RX_BUF_RBM_SW3_BM);
|
|
}
|
|
|
|
- ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list,
|
|
- "a, ring_id);
|
|
-
|
|
exit:
|
|
- return budget - quota;
|
|
+ return total_msdu_reaped;
|
|
}
|
|
|
|
static void
|