diff options
| author | Poddar, Siddarth <siddpodd@codeaurora.org> | 2016-11-29 20:17:01 +0530 |
|---|---|---|
| committer | Poddar, Siddarth <siddpodd@codeaurora.org> | 2016-12-15 13:47:42 +0530 |
| commit | 05be806f92f5a61a5c2148beedc32be803c15c5d (patch) | |
| tree | bb65b8750f5afdd2a84cf60afaf7df64437a7b05 | |
| parent | 248083094673a70f18b5931a7a3d9381000d9aa5 (diff) | |
qcacld-3.0: Reduce the threshold of drop in the intra-bss forwarding path
In case of intra-bss forwarding, tx-path consumes all the tx descriptors
and pause netif queues. As a result, there would be some left for stack
triggered packets such as ARP packets which leads to ref STA disconnection.
To avoid this, reserved a pool of descriptors(OL_TX_NON_FWD_RESERVE = 100)
for high priority packets such as ARP/EAPOL etc. and drop the packets
to be forwarded in host itself.
CRs-Fixed: 1095203
Change-Id: I7d473118ef3d986f79aa5b7a47286235d7adcab4
| -rw-r--r-- | core/dp/txrx/ol_rx_fwd.c | 16 | ||||
| -rw-r--r-- | core/dp/txrx/ol_txrx.c | 27 | ||||
| -rw-r--r-- | core/dp/txrx/ol_txrx.h | 29 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_ipa.c | 9 |
4 files changed, 81 insertions, 0 deletions
diff --git a/core/dp/txrx/ol_rx_fwd.c b/core/dp/txrx/ol_rx_fwd.c index 31ca346de900..ccc74542ebb8 100644 --- a/core/dp/txrx/ol_rx_fwd.c +++ b/core/dp/txrx/ol_rx_fwd.c @@ -202,6 +202,21 @@ ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev, qdf_nbuf_set_tid(msdu, QDF_NBUF_TX_EXT_TID_INVALID); } + + if (!ol_txrx_fwd_desc_thresh_check(vdev)) { + /* Drop the packet*/ + htt_rx_msdu_desc_free(pdev->htt_pdev, msdu); + qdf_net_buf_debug_release_skb(msdu); + TXRX_STATS_MSDU_LIST_INCR( + pdev, tx.dropped.host_reject, msdu); + /* add NULL terminator */ + qdf_nbuf_set_next(msdu, NULL); + qdf_nbuf_tx_free(msdu, + QDF_NBUF_PKT_ERROR); + msdu = msdu_list; + continue; + } + /* * This MSDU needs to be forwarded to the tx path. * Check whether it also needs to be sent to the OS @@ -219,6 +234,7 @@ ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev, pub.rx.intra_bss_fwd.packets_fwd, 1); } else { qdf_nbuf_t copy; + copy = qdf_nbuf_copy(msdu); if (copy) { ol_rx_fwd_to_tx(tx_vdev, copy); diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 5ada5f9cadba..39932e11e423 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -4881,6 +4881,33 @@ ol_txrx_dump_pkt(qdf_nbuf_t nbuf, uint32_t nbuf_paddr, int len) qdf_nbuf_data(nbuf), len, true); } +#ifdef QCA_LL_TX_FLOW_CONTROL_V2 +bool +ol_txrx_fwd_desc_thresh_check(struct ol_txrx_vdev_t *vdev) +{ + struct ol_tx_flow_pool_t *pool; + bool enough_desc_flag; + + if (!vdev) + return true; + + pool = vdev->pool; + + qdf_spin_lock_bh(&pool->flow_pool_lock); + enough_desc_flag = (pool->avail_desc < (pool->stop_th + + OL_TX_NON_FWD_RESERVE)) + ? false : true; + qdf_spin_unlock_bh(&pool->flow_pool_lock); + return enough_desc_flag; +} +#else +bool ol_txrx_fwd_desc_thresh_check(struct ol_txrx_vdev_t *vdev) +{ + return true; +} +#endif + + /** * ol_txrx_get_vdev_from_vdev_id() - get vdev from vdev_id * @vdev_id: vdev_id diff --git a/core/dp/txrx/ol_txrx.h b/core/dp/txrx/ol_txrx.h index c38e4905c522..d7982c3b629f 100644 --- a/core/dp/txrx/ol_txrx.h +++ b/core/dp/txrx/ol_txrx.h @@ -32,6 +32,14 @@ #include <cdp_txrx_cmn.h> /* ol_txrx_vdev_t, etc. */ #include "cds_sched.h" +/* + * Pool of tx descriptors reserved for + * high-priority traffic, such as ARP/EAPOL etc + * only for forwarding path. + */ +#define OL_TX_NON_FWD_RESERVE 100 + + void ol_txrx_peer_unref_delete(struct ol_txrx_peer_t *peer); /** @@ -139,6 +147,27 @@ ol_txrx_update_last_real_peer( void ol_txrx_dump_pkt(qdf_nbuf_t nbuf, uint32_t nbuf_paddr, int len); +/** + * ol_txrx_fwd_desc_thresh_check() - check to forward packet to tx path + * @vdev: which virtual device the frames were addressed to + * + * This API is to check whether enough descriptors are available or not + * to forward packet to tx path. If not enough descriptors left, + * start dropping tx-path packets. + * Do not pause netif queues as still a pool of descriptors is reserved + * for high-priority traffic such as EAPOL/ARP etc. + * In case of intra-bss forwarding, it could be possible that tx-path can + * consume all the tx descriptors and pause netif queues. Due to this, + * there would be some left for stack triggered packets such as ARP packets + * which could lead to disconnection of device. To avoid this, reserved + * a pool of descriptors for high-priority packets, i.e., reduce the + * threshold of drop in the intra-bss forwarding path. + * + * Return: true ; forward the packet, i.e., below threshold + * false; not enough descriptors, drop the packet + */ +bool ol_txrx_fwd_desc_thresh_check(struct ol_txrx_vdev_t *vdev); + ol_txrx_vdev_handle ol_txrx_get_vdev_from_vdev_id(uint8_t vdev_id); void htt_pkt_log_init(struct ol_txrx_pdev_t *handle, void *scn); diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c index bb6ce4bb4e43..477a30b32ad3 100644 --- a/core/hdd/src/wlan_hdd_ipa.c +++ b/core/hdd/src/wlan_hdd_ipa.c @@ -49,6 +49,7 @@ #include <linux/ip.h> #include <wlan_hdd_softap_tx_rx.h> #include <ol_txrx_osif_api.h> +#include <ol_txrx.h> #include <cdp_txrx_peer_ops.h> #include "cds_sched.h" @@ -3131,6 +3132,14 @@ static enum hdd_ipa_forward_type hdd_ipa_intrabss_forward( int ret = HDD_IPA_FORWARD_PKT_NONE; if ((desc & FW_RX_DESC_FORWARD_M)) { + if (!ol_txrx_fwd_desc_thresh_check( + ol_txrx_get_vdev_from_vdev_id(adapter->sessionId))) { + /* Drop the packet*/ + hdd_ipa->stats.num_tx_fwd_err++; + kfree_skb(skb); + ret = HDD_IPA_FORWARD_PKT_DISCARD; + return ret; + } HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, "Forward packet to Tx (fw_desc=%d)", desc); hdd_ipa->ipa_tx_forward++; |
