qcacmn: Add Sanity checks during RX processing

- Check for rx_desc.magic before using a rx_desc retrieved from the reo
  destination ring via rx_buf_cookie (dp_rx_process). Add stats.
- Check if we end up re-using a rx_desc with rx_desc.in_use=1 in the
  replenish path (dp_rx_buffers_replenish).
- Drop RX packet and assert in case MSDU Done failures are seen in
  in the TLV during dp_rx_process. Add stats.
- Disable host2rxdma ring mask for MCL. MCL is not expected to be
  receiving these interrupts.

Change-Id: Iaa345d04b8d48814f88ed6e2237fc67696f6a20c
CRs-Fixed: 2382076
This commit is contained in:
Mohit Khanna
2019-01-25 10:46:00 -08:00
committed by nshrivas
parent 9e4bb950e4
commit 16cd1b2e8d
6 changed files with 76 additions and 41 deletions

View File

@@ -6859,10 +6859,14 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
soc->stats.rx.err.rx_invalid_peer.num); soc->stats.rx.err.rx_invalid_peer.num);
DP_PRINT_STATS("HAL Ring Access Fail = %d", DP_PRINT_STATS("HAL Ring Access Fail = %d",
soc->stats.rx.err.hal_ring_access_fail); soc->stats.rx.err.hal_ring_access_fail);
DP_PRINT_STATS("MSDU Done failures = %d",
soc->stats.rx.err.msdu_done_fail);
DP_PRINT_STATS("RX frags: %d", soc->stats.rx.rx_frags); DP_PRINT_STATS("RX frags: %d", soc->stats.rx.rx_frags);
DP_PRINT_STATS("RX frag wait: %d", soc->stats.rx.rx_frag_wait); DP_PRINT_STATS("RX frag wait: %d", soc->stats.rx.rx_frag_wait);
DP_PRINT_STATS("RX frag err: %d", soc->stats.rx.rx_frag_err); DP_PRINT_STATS("RX frag err: %d", soc->stats.rx.rx_frag_err);
DP_PRINT_STATS("RX HP out_of_sync: %d", soc->stats.rx.hp_oos); DP_PRINT_STATS("RX HP out_of_sync: %d", soc->stats.rx.hp_oos);
DP_PRINT_STATS("RX DESC invalid magic: %u",
soc->stats.rx.err.rx_desc_invalid_magic);
DP_PRINT_STATS("RX DUP DESC: %d", DP_PRINT_STATS("RX DUP DESC: %d",
soc->stats.rx.err.hal_reo_dest_dup); soc->stats.rx.err.hal_reo_dest_dup);
DP_PRINT_STATS("RX REL DUP DESC: %d", DP_PRINT_STATS("RX REL DUP DESC: %d",
@@ -6873,8 +6877,7 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
DP_RXDMA_ERR_LENGTH - index, DP_RXDMA_ERR_LENGTH - index,
" %d", soc->stats.rx.err.rxdma_error[i]); " %d", soc->stats.rx.err.rxdma_error[i]);
} }
DP_PRINT_STATS("RXDMA Error (0-31):%s", DP_PRINT_STATS("RXDMA Error (0-31):%s", rxdma_error);
rxdma_error);
index = 0; index = 0;
for (i = 0; i < HAL_REO_ERR_MAX; i++) { for (i = 0; i < HAL_REO_ERR_MAX; i++) {
@@ -6882,8 +6885,7 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
DP_REO_ERR_LENGTH - index, DP_REO_ERR_LENGTH - index,
" %d", soc->stats.rx.err.reo_error[i]); " %d", soc->stats.rx.err.reo_error[i]);
} }
DP_PRINT_STATS("REO Error(0-14):%s", DP_PRINT_STATS("REO Error(0-14):%s", reo_error);
reo_error);
} }
/** /**

View File

@@ -30,19 +30,6 @@
#include "dp_rx_mon.h" #include "dp_rx_mon.h"
#include "dp_ipa.h" #include "dp_ipa.h"
#ifdef RX_DESC_DEBUG_CHECK
static inline void dp_rx_desc_prep(struct dp_rx_desc *rx_desc, qdf_nbuf_t nbuf)
{
rx_desc->magic = DP_RX_DESC_MAGIC;
rx_desc->nbuf = nbuf;
}
#else
static inline void dp_rx_desc_prep(struct dp_rx_desc *rx_desc, qdf_nbuf_t nbuf)
{
rx_desc->nbuf = nbuf;
}
#endif
#ifdef CONFIG_WIN #ifdef CONFIG_WIN
static inline bool dp_rx_check_ap_bridge(struct dp_vdev *vdev) static inline bool dp_rx_check_ap_bridge(struct dp_vdev *vdev)
{ {
@@ -93,7 +80,7 @@ void dp_rx_dump_info_and_assert(struct dp_soc *soc, void *hal_ring,
dp_rx_desc_dump(rx_desc); dp_rx_desc_dump(rx_desc);
hal_srng_dump_ring_desc(hal_soc, hal_ring, ring_desc); hal_srng_dump_ring_desc(hal_soc, hal_ring, ring_desc);
hal_srng_dump_ring(hal_soc, hal_ring); hal_srng_dump_ring(hal_soc, hal_ring);
qdf_assert_always(rx_desc->in_use); qdf_assert_always(0);
} }
/* /*
@@ -238,6 +225,10 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
next = (*desc_list)->next; next = (*desc_list)->next;
dp_rx_desc_prep(&((*desc_list)->rx_desc), rx_netbuf); dp_rx_desc_prep(&((*desc_list)->rx_desc), rx_netbuf);
/* rx_desc.in_use should be zero at this time*/
qdf_assert_always((*desc_list)->rx_desc.in_use == 0);
(*desc_list)->rx_desc.in_use = 1; (*desc_list)->rx_desc.in_use = 1;
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",
@@ -1597,6 +1588,14 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring,
*/ */
if (qdf_unlikely(!rx_desc->in_use)) { if (qdf_unlikely(!rx_desc->in_use)) {
DP_STATS_INC(soc, rx.err.hal_reo_dest_dup, 1); DP_STATS_INC(soc, rx.err.hal_reo_dest_dup, 1);
dp_err("Reaping rx_desc not in use!");
dp_rx_dump_info_and_assert(soc, hal_ring,
ring_desc, rx_desc);
}
if (qdf_unlikely(!dp_rx_desc_check_magic(rx_desc))) {
dp_err("Invalid rx_desc cookie=%d", rx_buf_cookie);
DP_STATS_INC(soc, rx.err.rx_desc_invalid_magic, 1);
dp_rx_dump_info_and_assert(soc, hal_ring, dp_rx_dump_info_and_assert(soc, hal_ring,
ring_desc, rx_desc); ring_desc, rx_desc);
} }
@@ -1610,6 +1609,7 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring,
*/ */
qdf_nbuf_unmap_single(soc->osdev, rx_desc->nbuf, qdf_nbuf_unmap_single(soc->osdev, rx_desc->nbuf,
QDF_DMA_BIDIRECTIONAL); QDF_DMA_BIDIRECTIONAL);
rx_desc->unmapped = 1;
core_id = smp_processor_id(); core_id = smp_processor_id();
DP_STATS_INC(soc, rx.ring_packets[core_id][ring_id], 1); DP_STATS_INC(soc, rx.ring_packets[core_id][ring_id], 1);
@@ -1702,12 +1702,15 @@ done:
dp_rx_save_tid_ts(nbuf, tid, rx_pdev->delay_stats_flag); dp_rx_save_tid_ts(nbuf, tid, rx_pdev->delay_stats_flag);
tid_stats = &rx_pdev->stats.tid_stats.tid_rx_stats[tid]; tid_stats = &rx_pdev->stats.tid_stats.tid_rx_stats[tid];
if (qdf_unlikely(!hal_rx_attn_msdu_done_get(rx_tlv_hdr))) { if (qdf_unlikely(!hal_rx_attn_msdu_done_get(rx_tlv_hdr))) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, dp_err("MSDU DONE failure");
FL("MSDU DONE failure")); DP_STATS_INC(soc, rx.err.msdu_done_fail, 1);
hal_rx_dump_pkt_tlvs(hal_soc, rx_tlv_hdr, hal_rx_dump_pkt_tlvs(hal_soc, rx_tlv_hdr,
QDF_TRACE_LEVEL_INFO); QDF_TRACE_LEVEL_INFO);
tid_stats->fail_cnt[MSDU_DONE_FAILURE]++; tid_stats->fail_cnt[MSDU_DONE_FAILURE]++;
qdf_assert(0); qdf_nbuf_free(nbuf);
qdf_assert_always(0);
nbuf = next;
continue;
} }
tid_stats->msdu_cnt++; tid_stats->msdu_cnt++;

View File

@@ -56,6 +56,7 @@
#endif /* QCA_HOST2FW_RXBUF_RING */ #endif /* QCA_HOST2FW_RXBUF_RING */
#define RX_BUFFER_RESERVATION 0 #define RX_BUFFER_RESERVATION 0
#define RX_BUFFER_SIZE 2048
#define DP_PEER_METADATA_PEER_ID_MASK 0x0000ffff #define DP_PEER_METADATA_PEER_ID_MASK 0x0000ffff
#define DP_PEER_METADATA_PEER_ID_SHIFT 0 #define DP_PEER_METADATA_PEER_ID_SHIFT 0
@@ -394,7 +395,6 @@ void dp_rx_add_to_free_desc_list(union dp_rx_desc_list_elem_t **head,
new->nbuf = NULL; new->nbuf = NULL;
new->in_use = 0; new->in_use = 0;
new->unmapped = 0;
((union dp_rx_desc_list_elem_t *)new)->next = *head; ((union dp_rx_desc_list_elem_t *)new)->next = *head;
*head = (union dp_rx_desc_list_elem_t *)new; *head = (union dp_rx_desc_list_elem_t *)new;
@@ -991,4 +991,45 @@ void dp_rx_dump_info_and_assert(struct dp_soc *soc, void *hal_ring,
void *ring_desc, struct dp_rx_desc *rx_desc); void *ring_desc, struct dp_rx_desc *rx_desc);
void dp_rx_compute_delay(struct dp_vdev *vdev, qdf_nbuf_t nbuf); void dp_rx_compute_delay(struct dp_vdev *vdev, qdf_nbuf_t nbuf);
#ifdef RX_DESC_DEBUG_CHECK
/**
* dp_rx_desc_check_magic() - check the magic value in dp_rx_desc
* @rx_desc: rx descriptor pointer
*
* Return: true, if magic is correct, else false.
*/
static inline bool dp_rx_desc_check_magic(struct dp_rx_desc *rx_desc)
{
if (qdf_unlikely(rx_desc->magic != DP_RX_DESC_MAGIC))
return false;
rx_desc->magic = 0;
return true;
}
/**
* dp_rx_desc_prep() - prepare rx desc
* @rx_desc: rx descriptor pointer to be prepared
* @nbuf: nbuf to be associated with rx_desc
*
* Return: none
*/
static inline void dp_rx_desc_prep(struct dp_rx_desc *rx_desc, qdf_nbuf_t nbuf)
{
rx_desc->magic = DP_RX_DESC_MAGIC;
rx_desc->nbuf = nbuf;
}
#else
static inline bool dp_rx_desc_check_magic(struct dp_rx_desc *rx_desc)
{
return true;
}
static inline void dp_rx_desc_prep(struct dp_rx_desc *rx_desc, qdf_nbuf_t nbuf)
{
rx_desc->nbuf = nbuf;
}
#endif /* RX_DESC_DEBUG_CHECK */
#endif /* _DP_RX_H */ #endif /* _DP_RX_H */

View File

@@ -32,22 +32,6 @@
#include "dp_rx_defrag.h" #include "dp_rx_defrag.h"
#include <enet.h> /* LLC_SNAP_HDR_LEN */ #include <enet.h> /* LLC_SNAP_HDR_LEN */
#ifdef RX_DESC_DEBUG_CHECK
static inline bool dp_rx_desc_check_magic(struct dp_rx_desc *rx_desc)
{
if (qdf_unlikely(rx_desc->magic != DP_RX_DESC_MAGIC)) {
return false;
}
rx_desc->magic = 0;
return true;
}
#else
static inline bool dp_rx_desc_check_magic(struct dp_rx_desc *rx_desc)
{
return true;
}
#endif
/** /**
* dp_rx_mcast_echo_check() - check if the mcast pkt is a loop * dp_rx_mcast_echo_check() - check if the mcast pkt is a loop
* back on same vap or a different vap. * back on same vap or a different vap.

View File

@@ -609,8 +609,11 @@ struct dp_soc_stats {
uint32_t invalid_vdev; uint32_t invalid_vdev;
/* Invalid PDEV error count */ /* Invalid PDEV error count */
uint32_t invalid_pdev; uint32_t invalid_pdev;
/* Invalid sa_idx or da_idx*/ /* Invalid sa_idx or da_idx*/
uint32_t invalid_sa_da_idx; uint32_t invalid_sa_da_idx;
/* MSDU DONE failures */
uint32_t msdu_done_fail;
/* Invalid PEER Error count */ /* Invalid PEER Error count */
struct cdp_pkt_info rx_invalid_peer; struct cdp_pkt_info rx_invalid_peer;
/* Invalid PEER ID count */ /* Invalid PEER ID count */
@@ -619,6 +622,8 @@ struct dp_soc_stats {
uint32_t hal_ring_access_fail; uint32_t hal_ring_access_fail;
/* RX DMA error count */ /* RX DMA error count */
uint32_t rxdma_error[HAL_RXDMA_ERR_MAX]; uint32_t rxdma_error[HAL_RXDMA_ERR_MAX];
/* RX REO DEST Desc Invalid Magic count */
uint32_t rx_desc_invalid_magic;
/* REO Error count */ /* REO Error count */
uint32_t reo_error[HAL_REO_ERR_MAX]; uint32_t reo_error[HAL_REO_ERR_MAX];
/* HAL REO ERR Count */ /* HAL REO ERR Count */

View File

@@ -129,7 +129,7 @@ static const int rx_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = {
WLAN_CFG_RX_MON_RING_MASK_3}; WLAN_CFG_RX_MON_RING_MASK_3};
static const int host2rxdma_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { static const int host2rxdma_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = {
WLAN_CFG_HOST2RXDMA_RING_MASK_0, 0,
0, 0,
0, 0,
0, 0,