From 6409e4a8c5b67ded526da3ea8acba8f9d6acc85d Mon Sep 17 00:00:00 2001 From: Jinwei Chen Date: Thu, 7 May 2020 14:35:41 +0800 Subject: [PATCH] qcacld-3.0: add FISA flush when vdev detach In some case, FISA flush for one FISA entry is missed which lead to some RX frames stay at FISA entry forever, this will cause skb leak. Do FISA flush per vdev when vdev detach to avoid skb leak. Change-Id: Ie6bdf885c740a99b089290257ea6936d5804d142 CRs-Fixed: 2679221 --- core/dp/txrx3.0/dp_fisa_rx.c | 67 +++++++++++++++++++++++++---------- core/dp/txrx3.0/dp_fisa_rx.h | 14 ++++++-- core/hdd/inc/wlan_hdd_tx_rx.h | 22 ++++++++++-- core/hdd/src/wlan_hdd_assoc.c | 2 +- core/hdd/src/wlan_hdd_tx_rx.c | 12 +++++-- 5 files changed, 90 insertions(+), 27 deletions(-) diff --git a/core/dp/txrx3.0/dp_fisa_rx.c b/core/dp/txrx3.0/dp_fisa_rx.c index 81ccf2485fde..79324457911f 100644 --- a/core/dp/txrx3.0/dp_fisa_rx.c +++ b/core/dp/txrx3.0/dp_fisa_rx.c @@ -1104,13 +1104,30 @@ QDF_STATUS dp_rx_dump_fisa_stats(struct dp_soc *soc) } /** - * dp_rx_fisa_flush() - Flush function to end of context flushing of aggregates - * @soc: core txrx main context - * @napi_id: REO number to flush the flow Rxed on the REO + * dp_rx_fisa_flush_flow_wrap() - flush fisa flow by invoking + * dp_rx_fisa_flush_flow() + * @sw_ft: fisa flow for which aggregates to be flushed * - * Return: Success on flushing the flows for the REO + * Return: None. */ -QDF_STATUS dp_rx_fisa_flush(struct dp_soc *soc, int napi_id) +static void dp_rx_fisa_flush_flow_wrap(struct dp_fisa_rx_sw_ft *sw_ft) +{ + /* Save the ip_len and checksum as hardware assist is + * always based on his start of aggregation + */ + sw_ft->napi_flush_cumulative_l4_checksum = + sw_ft->cumulative_l4_checksum; + sw_ft->napi_flush_cumulative_ip_length = + sw_ft->hal_cumultive_ip_len; + dp_fisa_debug("napi_flush_cumulative_ip_length 0x%x", + sw_ft->napi_flush_cumulative_ip_length); + + dp_rx_fisa_flush_flow(sw_ft->vdev, + sw_ft); + sw_ft->cur_aggr = 0; +} + +QDF_STATUS dp_rx_fisa_flush_by_ctx_id(struct dp_soc *soc, int napi_id) { struct dp_rx_fst *fisa_hdl = soc->rx_fst; struct dp_fisa_rx_sw_ft *sw_ft_entry = @@ -1123,19 +1140,33 @@ QDF_STATUS dp_rx_fisa_flush(struct dp_soc *soc, int napi_id) sw_ft_entry[i].is_populated) { dp_fisa_debug("flushing %d %pK napi_id %d", i, &sw_ft_entry[i], napi_id); - /* Save the ip_len and checksum as hardware assist is - * always based on his start of aggregation - */ - sw_ft_entry[i].napi_flush_cumulative_l4_checksum = - sw_ft_entry[i].cumulative_l4_checksum; - sw_ft_entry[i].napi_flush_cumulative_ip_length = - sw_ft_entry[i].hal_cumultive_ip_len; - dp_fisa_debug("napi_flush_cumulative_ip_length 0x%x", - sw_ft_entry[i].napi_flush_cumulative_ip_length); - - dp_rx_fisa_flush_flow(sw_ft_entry[i].vdev, - &sw_ft_entry[i]); - sw_ft_entry[i].cur_aggr = 0; + dp_rx_fisa_flush_flow_wrap(&sw_ft_entry[i]); + } + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS dp_rx_fisa_flush_by_vdev_id(struct dp_soc *soc, uint8_t vdev_id) +{ + struct dp_rx_fst *fisa_hdl = soc->rx_fst; + struct dp_fisa_rx_sw_ft *sw_ft_entry = + (struct dp_fisa_rx_sw_ft *)fisa_hdl->base; + int ft_size = fisa_hdl->max_entries; + int i; + struct dp_vdev *vdev; + + vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); + if (qdf_unlikely(!vdev)) { + dp_err("null vdev by vdev_id %d", vdev_id); + return QDF_STATUS_E_FAILURE; + } + + for (i = 0; i < ft_size; i++) { + if (vdev == sw_ft_entry[i].vdev) { + dp_fisa_debug("flushing %d %pk vdev %pK", i, + &sw_ft_entry[i], vdev); + dp_rx_fisa_flush_flow_wrap(&sw_ft_entry[i]); } } diff --git a/core/dp/txrx3.0/dp_fisa_rx.h b/core/dp/txrx3.0/dp_fisa_rx.h index 2c61f6c1a6b9..83e28b36dabf 100644 --- a/core/dp/txrx3.0/dp_fisa_rx.h +++ b/core/dp/txrx3.0/dp_fisa_rx.h @@ -46,15 +46,23 @@ QDF_STATUS dp_fisa_rx(struct dp_soc *dp_fisa_rx_hdl, struct dp_vdev *vdev, qdf_nbuf_t nbuf_list); /** - * dp_rx_fisa_flush() - FISA Rx flush function to flush aggregation at end of - * NAPI + * dp_rx_fisa_flush_by_ctx_id() - FISA Rx flush function to flush + * aggregation at end of NAPI * @soc: core txrx main context * @napi_id: Flows which are rxed on the NAPI ID to be flushed * * Return: QDF_STATUS */ -QDF_STATUS dp_rx_fisa_flush(struct dp_soc *soc, int napi_id); +QDF_STATUS dp_rx_fisa_flush_by_ctx_id(struct dp_soc *soc, int napi_id); +/** + * dp_rx_fisa_flush_by_vdev_id() - Flush fisa aggregates per vdev id + * @soc: core txrx main context + * @vdev_id: vdev ID + * + * Return: Success on flushing the flows for the vdev + */ +QDF_STATUS dp_rx_fisa_flush_by_vdev_id(struct dp_soc *soc, uint8_t vdev_id); #else static QDF_STATUS dp_rx_dump_fisa_stats(struct dp_soc *soc) { diff --git a/core/hdd/inc/wlan_hdd_tx_rx.h b/core/hdd/inc/wlan_hdd_tx_rx.h index 545c2e2280ea..2f98422203db 100644 --- a/core/hdd/inc/wlan_hdd_tx_rx.h +++ b/core/hdd/inc/wlan_hdd_tx_rx.h @@ -127,13 +127,29 @@ QDF_STATUS hdd_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rxBuf); QDF_STATUS hdd_rx_fisa_cbk(void *dp_soc, void *dp_vdev, qdf_nbuf_t rxbuf_list); /** - * hdd_rx_fisa_flush() - Flush function to end of context flushing of aggregates + * hdd_rx_fisa_flush_by_ctx_id() - Flush function to end of context + * flushing of aggregates * @soc: core txrx main context - * @napi_id: REO number to flush the flow Rxed on the REO + * @ring_num: REO number to flush the flow Rxed on the REO * * Return: Success on flushing the flows for the REO */ -QDF_STATUS hdd_rx_fisa_flush(void *dp_soc, int ring_num); +QDF_STATUS hdd_rx_fisa_flush_by_ctx_id(void *dp_soc, int ring_num); + +/** + * hdd_rx_fisa_flush_by_vdev_id() - Flush fisa aggregates per vdev id + * @soc: core txrx main context + * @vdev_id: vdev ID + * + * Return: Success on flushing the flows for the vdev + */ +QDF_STATUS hdd_rx_fisa_flush_by_vdev_id(void *dp_soc, uint8_t vdev_id); +#else +static inline QDF_STATUS hdd_rx_fisa_flush_by_vdev_id(void *dp_soc, + uint8_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} #endif /** diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 8080ea78d760..46ed09885082 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -2151,7 +2151,7 @@ static inline void hdd_rx_register_fisa_ops(struct ol_txrx_ops *txrx_ops) { txrx_ops->rx.osif_fisa_rx = hdd_rx_fisa_cbk; - txrx_ops->rx.osif_fisa_flush = hdd_rx_fisa_flush; + txrx_ops->rx.osif_fisa_flush = hdd_rx_fisa_flush_by_ctx_id; } #else static inline void diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index 49126e684ed8..a8704a2a9ff7 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -2062,6 +2062,9 @@ QDF_STATUS hdd_rx_flush_packet_cbk(void *adapter_context, uint8_t vdev_id) return QDF_STATUS_E_FAILURE; } + /* do fisa flush for this vdev */ + hdd_rx_fisa_flush_by_vdev_id(soc, vdev_id); + if (hdd_ctx->enable_dp_rx_threads) dp_txrx_flush_pkts_by_vdev_id(soc, vdev_id); @@ -2077,9 +2080,14 @@ QDF_STATUS hdd_rx_fisa_cbk(void *dp_soc, void *dp_vdev, qdf_nbuf_t nbuf_list) nbuf_list); } -QDF_STATUS hdd_rx_fisa_flush(void *dp_soc, int ring_num) +QDF_STATUS hdd_rx_fisa_flush_by_ctx_id(void *dp_soc, int ring_num) { - return dp_rx_fisa_flush((struct dp_soc *)dp_soc, ring_num); + return dp_rx_fisa_flush_by_ctx_id((struct dp_soc *)dp_soc, ring_num); +} + +QDF_STATUS hdd_rx_fisa_flush_by_vdev_id(void *dp_soc, uint8_t vdev_id) +{ + return dp_rx_fisa_flush_by_vdev_id((struct dp_soc *)dp_soc, vdev_id); } #endif