qcacmn: skip processing duplicate descriptor in dp_rx_err_mpdu_pop

If there's a HW duplicate rx descriptor from hardware,
it'll cause a NULL pointer issue in
__dma_inv_range in dp_rxdma_err_process.
In this case, skip procssing it as a workaround.

CRs-Fixed: 2398327
Change-Id: I5639e5fc9a3a06e6762448ec7cb2ea58d9ae8160
This commit is contained in:
nwzhao
2019-01-31 11:43:17 -08:00
committed by nshrivas
parent f1313ba77e
commit ea2ffbb331
4 changed files with 46 additions and 1 deletions

View File

@@ -7039,6 +7039,9 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
DP_PRINT_STATS("RX REL DUP DESC: %d",
soc->stats.rx.err.hal_wbm_rel_dup);
DP_PRINT_STATS("RXDMA ERR DUP DESC: %d",
soc->stats.rx.err.hal_rxdma_err_dup);
for (i = 0; i < HAL_RXDMA_ERR_MAX; i++) {
index += qdf_snprint(&rxdma_error[index],
DP_RXDMA_ERR_LENGTH - index,

View File

@@ -1553,6 +1553,26 @@ done:
return rx_bufs_used; /* Assume no scale factor for now */
}
/**
* dup_desc_dbg() - dump and assert if duplicate rx desc found
*
* @soc: core DP main context
* @rxdma_dst_ring_desc: void pointer to monitor link descriptor buf addr info
* @rx_desc: void pointer to rx descriptor
*
* Return: void
*/
static void dup_desc_dbg(struct dp_soc *soc,
void *rxdma_dst_ring_desc,
void *rx_desc)
{
DP_STATS_INC(soc, rx.err.hal_rxdma_err_dup, 1);
dp_rx_dump_info_and_assert(soc,
soc->rx_rel_ring.hal_srng,
rxdma_dst_ring_desc,
rx_desc);
}
/**
* dp_rx_err_mpdu_pop() - extract the MSDU's from link descs
*
@@ -1585,6 +1605,7 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
uint8_t rxdma_error_code = 0;
uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
struct dp_pdev *pdev = dp_get_pdev_for_mac_id(soc, mac_id);
void *ring_desc;
msdu = 0;
@@ -1629,6 +1650,25 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
msdu_list.sw_cookie[i]);
qdf_assert_always(rx_desc);
msdu = rx_desc->nbuf;
/*
* this is a unlikely scenario
* where the host is reaping
* a descriptor which
* it already reaped just a while ago
* but is yet to replenish
* it back to HW.
* In this case host will dump
* the last 128 descriptors
* including the software descriptor
* rx_desc and assert.
*/
ring_desc = rxdma_dst_ring_desc;
if (qdf_unlikely(!rx_desc->in_use)) {
dup_desc_dbg(soc,
ring_desc,
rx_desc);
continue;
}
qdf_nbuf_unmap_single(soc->osdev, msdu,
QDF_DMA_FROM_DEVICE);

View File

@@ -711,6 +711,8 @@ struct dp_soc_stats {
uint32_t hal_reo_dest_dup;
/* HAL WBM RELEASE Duplicate count */
uint32_t hal_wbm_rel_dup;
/* HAL RXDMA error Duplicate count */
uint32_t hal_rxdma_err_dup;
} err;
/* packet count per core - per ring */

View File

@@ -1438,7 +1438,7 @@ static inline void hal_srng_dump_ring(struct hal_soc *hal, void *hal_ring)
desc = &srng->ring_base_vaddr[tp - srng->entry_size];
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_FATAL,
QDF_TRACE_LEVEL_DEBUG,
desc, (srng->entry_size << 2));
tp -= srng->entry_size;