qcacmn: Handle the nbuf sanity failure gracefully

Th nbuf sanity can fail in case when HW posts the
same buffer twice. This case can be handled gracefully
by just skipping the processing of the corresponding rx
descriptor.

Change-Id: I471bb9f364a51937e85249996e427f15872bda97
CRs-Fixed: 2738558
This commit is contained in:
Rakesh Pillai
2020-07-23 00:13:13 +05:30
committed by snandini
parent e344f80463
commit d7a0b3f14c
4 changed files with 28 additions and 8 deletions

View File

@@ -287,6 +287,7 @@ QDF_STATUS __dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
qdf_assert_always((*desc_list)->rx_desc.in_use == 0); qdf_assert_always((*desc_list)->rx_desc.in_use == 0);
(*desc_list)->rx_desc.in_use = 1; (*desc_list)->rx_desc.in_use = 1;
(*desc_list)->rx_desc.in_err_state = 0;
dp_rx_desc_update_dbg_info(&(*desc_list)->rx_desc, dp_rx_desc_update_dbg_info(&(*desc_list)->rx_desc,
func_name, RX_DESC_REPLENISHED); func_name, RX_DESC_REPLENISHED);
dp_verbose_debug("rx_netbuf=%pK, buf=%pK, paddr=0x%llx, cookie=%d", dp_verbose_debug("rx_netbuf=%pK, buf=%pK, paddr=0x%llx, cookie=%d",
@@ -1721,21 +1722,25 @@ int dp_wds_rx_policy_check(uint8_t *rx_tlv_hdr,
* Return: NONE * Return: NONE
*/ */
static inline static inline
void dp_rx_desc_nbuf_sanity_check(hal_ring_desc_t ring_desc, QDF_STATUS dp_rx_desc_nbuf_sanity_check(hal_ring_desc_t ring_desc,
struct dp_rx_desc *rx_desc) struct dp_rx_desc *rx_desc)
{ {
struct hal_buf_info hbi; struct hal_buf_info hbi;
hal_rx_reo_buf_paddr_get(ring_desc, &hbi); hal_rx_reo_buf_paddr_get(ring_desc, &hbi);
/* Sanity check for possible buffer paddr corruption */ /* Sanity check for possible buffer paddr corruption */
qdf_assert_always((&hbi)->paddr == if ((&hbi)->paddr ==
qdf_nbuf_get_frag_paddr(rx_desc->nbuf, 0)); qdf_nbuf_get_frag_paddr(rx_desc->nbuf, 0))
return QDF_STATUS_SUCCESS;
return QDF_STATUS_E_FAILURE;
} }
#else #else
static inline static inline
void dp_rx_desc_nbuf_sanity_check(hal_ring_desc_t ring_desc, QDF_STATUS dp_rx_desc_nbuf_sanity_check(hal_ring_desc_t ring_desc,
struct dp_rx_desc *rx_desc) struct dp_rx_desc *rx_desc)
{ {
return QDF_STATUS_SUCCESS;
} }
#endif #endif
@@ -2120,7 +2125,13 @@ more_data:
continue; continue;
} }
dp_rx_desc_nbuf_sanity_check(ring_desc, rx_desc); status = dp_rx_desc_nbuf_sanity_check(ring_desc, rx_desc);
if (qdf_unlikely(QDF_IS_STATUS_ERROR(status))) {
DP_STATS_INC(soc, rx.err.nbuf_sanity_fail, 1);
rx_desc->in_err_state = 1;
hal_srng_dst_get_next(hal_soc, hal_ring_hdl);
continue;
}
if (qdf_unlikely(!dp_rx_desc_check_magic(rx_desc))) { if (qdf_unlikely(!dp_rx_desc_check_magic(rx_desc))) {
dp_err("Invalid rx_desc cookie=%d", rx_buf_cookie); dp_err("Invalid rx_desc cookie=%d", rx_buf_cookie);

View File

@@ -108,6 +108,7 @@ struct dp_rx_desc_dbg_info {
* @in_use rx_desc is in use * @in_use rx_desc is in use
* @unmapped used to mark rx_desc an unmapped if the corresponding * @unmapped used to mark rx_desc an unmapped if the corresponding
* nbuf is already unmapped * nbuf is already unmapped
* @in_err_state : Nbuf sanity failed for this descriptor.
*/ */
struct dp_rx_desc { struct dp_rx_desc {
qdf_nbuf_t nbuf; qdf_nbuf_t nbuf;
@@ -119,7 +120,8 @@ struct dp_rx_desc {
struct dp_rx_desc_dbg_info *dbg_info; struct dp_rx_desc_dbg_info *dbg_info;
#endif #endif
uint8_t in_use:1, uint8_t in_use:1,
unmapped:1; unmapped:1,
in_err_state:1;
}; };
/* RX Descriptor Multi Page memory alloc related */ /* RX Descriptor Multi Page memory alloc related */

View File

@@ -6055,6 +6055,8 @@ void dp_txrx_path_stats(struct dp_soc *soc)
soc->stats.rx.err.raw_frm_drop); soc->stats.rx.err.raw_frm_drop);
DP_PRINT_STATS("Rx stale link desc cookie: %d", DP_PRINT_STATS("Rx stale link desc cookie: %d",
pdev->soc->stats.rx.err.invalid_link_cookie); pdev->soc->stats.rx.err.invalid_link_cookie);
DP_PRINT_STATS("Rx nbuf sanity fails: %d",
pdev->soc->stats.rx.err.nbuf_sanity_fail);
DP_PRINT_STATS("Reo Statistics"); DP_PRINT_STATS("Reo Statistics");
DP_PRINT_STATS("near_full: %u ", soc->stats.rx.near_full); DP_PRINT_STATS("near_full: %u ", soc->stats.rx.near_full);
@@ -6617,6 +6619,9 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
DP_PRINT_STATS("Rx stale link desc cookie: %d", DP_PRINT_STATS("Rx stale link desc cookie: %d",
soc->stats.rx.err.invalid_link_cookie); soc->stats.rx.err.invalid_link_cookie);
DP_PRINT_STATS("Rx nbuf sanity fail: %d",
soc->stats.rx.err.nbuf_sanity_fail);
for (i = 0; i < HAL_RXDMA_ERR_MAX; i++) { for (i = 0; i < HAL_RXDMA_ERR_MAX; i++) {
index += qdf_snprint(&rxdma_error[index], index += qdf_snprint(&rxdma_error[index],
DP_RXDMA_ERR_LENGTH - index, DP_RXDMA_ERR_LENGTH - index,

View File

@@ -857,6 +857,8 @@ struct dp_soc_stats {
uint32_t raw_frm_drop; uint32_t raw_frm_drop;
/* Stale link desc cookie count*/ /* Stale link desc cookie count*/
uint32_t invalid_link_cookie; uint32_t invalid_link_cookie;
/* Nbuf sanity failure */
uint32_t nbuf_sanity_fail;
} err; } err;
/* packet count per core - per ring */ /* packet count per core - per ring */