Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9bfcd903 authored by Rakesh Pillai's avatar Rakesh Pillai Committed by snandini
Browse files

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
parent 37d318f8
Loading
Loading
Loading
Loading
+16 −5
Original line number Original line Diff line number Diff line
@@ -286,6 +286,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",
@@ -1675,21 +1676,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


@@ -2061,7 +2066,13 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, hal_ring_handle_t hal_ring_hdl,
			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_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);
+3 −1
Original line number Original line Diff line number Diff line
@@ -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 */
+5 −0
Original line number Original line Diff line number Diff line
@@ -5555,6 +5555,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);
@@ -6089,6 +6091,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,
+2 −0
Original line number Original line Diff line number Diff line
@@ -812,6 +812,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 */