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

Commit 3f136b59 authored by Rakesh Pillai's avatar Rakesh Pillai
Browse files

qcacmn: use dynamic memory allocation for rx ring history

Currently the rx ring history uses global memory.
Use dynamic memory allocation for rx ring history
to reduce the global memory usage.

Also do the sanity check for rx error path, if
its a fragmented packet.

Change-Id: Ia92bb5bf5a60c7e9c3a8f841e114aed36004260d
CRs-Fixed: 2771555
parent 56847667
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -2108,6 +2108,24 @@ void dp_set_max_page_size(struct qdf_mem_multi_page_t *pages,
}
#endif /* MAX_ALLOC_PAGE_SIZE */

/**
 * dp_history_get_next_index() - get the next entry to record an entry
 *				 in the history.
 * @curr_idx: Current index where the last entry is written.
 * @max_entries: Max number of entries in the history
 *
 * This function assumes that the max number os entries is a power of 2.
 *
 * Returns: The index where the next entry is to be written.
 */
static inline uint32_t dp_history_get_next_index(qdf_atomic_t *curr_idx,
						 uint32_t max_entries)
{
	uint32_t idx = qdf_atomic_inc_return(curr_idx);

	return idx & (max_entries - 1);
}

#ifdef DP_MEM_PRE_ALLOC
/**
 * dp_desc_multi_pages_mem_alloc() - alloc memory over multiple pages
+62 −28
Original line number Diff line number Diff line
@@ -94,12 +94,6 @@ cdp_dump_flow_pool_info(struct cdp_soc_t *soc)
#define SET_PEER_REF_CNT_ONE(_peer)
#endif

#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY
struct dp_rx_history dp_rx_ring_hist[MAX_REO_DEST_RINGS];
struct dp_rx_reinject_history dp_rx_reinject_ring_hist;
struct dp_rx_err_history dp_rx_err_ring_hist;
#endif

/*
 * The max size of cdp_peer_stats_param_t is limited to 16 bytes.
 * If the buffer size is exceeding this size limit,
@@ -3762,6 +3756,66 @@ static QDF_STATUS dp_htt_ppdu_stats_attach(struct dp_pdev *pdev)
	return QDF_STATUS_SUCCESS;
}

#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY
/**
 * dp_soc_rx_history_attach() - Attach the ring history record buffers
 * @soc: DP soc structure
 *
 * This function allocates the memory for recording the rx ring, rx error
 * ring and the reinject ring entries. There is no error returned in case
 * of allocation failure since the record function checks if the history is
 * initialized or not. We do not want to fail the driver load in case of
 * failure to allocate memory for debug history.
 *
 * Returns: None
 */
static void dp_soc_rx_history_attach(struct dp_soc *soc)
{
	int i;
	uint32_t rx_ring_hist_size;
	uint32_t rx_err_ring_hist_size;
	uint32_t rx_reinject_hist_size;

	rx_ring_hist_size = sizeof(*soc->rx_ring_history[i]);
	rx_err_ring_hist_size = sizeof(*soc->rx_err_ring_history);
	rx_reinject_hist_size = sizeof(*soc->rx_reinject_ring_history);

	for (i = 0; i < MAX_REO_DEST_RINGS; i++) {
		soc->rx_ring_history[i] = qdf_mem_malloc(rx_ring_hist_size);
		if (soc->rx_ring_history[i])
			qdf_atomic_init(&soc->rx_ring_history[i]->index);
	}

	soc->rx_err_ring_history = qdf_mem_malloc(rx_err_ring_hist_size);
	if (soc->rx_err_ring_history)
		qdf_atomic_init(&soc->rx_err_ring_history->index);

	soc->rx_reinject_ring_history = qdf_mem_malloc(rx_reinject_hist_size);
	if (soc->rx_reinject_ring_history)
		qdf_atomic_init(&soc->rx_reinject_ring_history->index);
}

static void dp_soc_rx_history_detach(struct dp_soc *soc)
{
	int i;

	for (i = 0; i < MAX_REO_DEST_RINGS; i++)
		qdf_mem_free(soc->rx_ring_history[i]);

	qdf_mem_free(soc->rx_err_ring_history);
	qdf_mem_free(soc->rx_reinject_ring_history);
}

#else
static inline void dp_soc_rx_history_attach(struct dp_soc *soc)
{
}

static inline void dp_soc_rx_history_detach(struct dp_soc *soc)
{
}
#endif

/*
* dp_pdev_attach_wifi3() - attach txrx pdev
* @txrx_soc: Datapath SOC handle
@@ -4738,6 +4792,7 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc)
	soc->dp_soc_reinit = 0;

	wlan_cfg_soc_detach(soc->wlan_cfg_ctx);
	dp_soc_rx_history_detach(soc);

	qdf_minidump_remove(soc);
	qdf_mem_free(soc);
@@ -10961,28 +11016,6 @@ static void dp_process_wow_ack_rsp(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
	}
}

#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY
static void dp_soc_rx_history_attach(struct dp_soc *soc)
{
	int i;

	for (i = 0; i < MAX_REO_DEST_RINGS; i++) {
		soc->rx_ring_history[i] = &dp_rx_ring_hist[i];
		qdf_atomic_init(&soc->rx_ring_history[i]->index);
	}

	soc->rx_err_ring_history = &dp_rx_err_ring_hist;
	soc->rx_reinject_ring_history = &dp_rx_reinject_ring_hist;

	qdf_atomic_init(&soc->rx_err_ring_history->index);
	qdf_atomic_init(&soc->rx_reinject_ring_history->index);
}
#else
static inline void dp_soc_rx_history_attach(struct dp_soc *soc)
{
}
#endif

/**
 * dp_process_target_suspend_req() - process target suspend request
 * @soc_hdl: datapath soc handle
@@ -11220,6 +11253,7 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
fail2:
	htt_soc_detach(htt_soc);
fail1:
	dp_soc_rx_history_detach(soc);
	qdf_mem_free(soc);
fail0:
	return NULL;
+19 −3
Original line number Diff line number Diff line
@@ -1902,18 +1902,33 @@ bool dp_rx_is_raw_frame_dropped(qdf_nbuf_t nbuf)
#endif

#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY
/**
 * dp_rx_ring_record_entry() - Record an entry into the rx ring history.
 * @soc: Datapath soc structure
 * @ring_num: REO ring number
 * @ring_desc: REO ring descriptor
 *
 * Returns: None
 */
static inline void
dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num, hal_ring_desc_t ring_desc)
dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num,
			hal_ring_desc_t ring_desc)
{
	struct dp_buf_info_record *record;
	uint8_t rbm;
	struct hal_buf_info hbi;
	uint32_t idx;

	if (qdf_unlikely(!&soc->rx_ring_history[ring_num]))
		return;

	hal_rx_reo_buf_paddr_get(ring_desc, &hbi);
	rbm = hal_rx_ret_buf_manager_get(ring_desc);

	idx = dp_history_get_next_index(&soc->rx_ring_history[ring_num]->index, DP_RX_HIST_MAX);
	idx = dp_history_get_next_index(&soc->rx_ring_history[ring_num]->index,
					DP_RX_HIST_MAX);

	/* No NULL check needed for record since its an array */
	record = &soc->rx_ring_history[ring_num]->entry[idx];

	record->timestamp = qdf_get_log_timestamp();
@@ -1923,7 +1938,8 @@ dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num, hal_ring_desc_t ri
}
#else
static inline void
dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num, hal_ring_desc_t ring_desc)
dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num,
			hal_ring_desc_t ring_desc)
{
}
#endif
+7 −0
Original line number Diff line number Diff line
@@ -755,6 +755,13 @@ void dp_rx_desc_update_dbg_info(struct dp_rx_desc *rx_desc,
}
#else

static inline
bool dp_rx_desc_paddr_sanity_check(struct dp_rx_desc *rx_desc,
				   uint64_t ring_paddr)
{
	return true;
}

static inline
void dp_rx_desc_alloc_dbg_info(struct dp_rx_desc *rx_desc)
{
+15 −0
Original line number Diff line number Diff line
@@ -1145,7 +1145,17 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer,
	return QDF_STATUS_SUCCESS;
}
#else

#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY
/**
 * dp_rx_reinject_ring_record_entry() - Record reinject ring history
 * @soc: Datapath soc structure
 * @paddr: paddr of the buffer reinjected to SW2REO ring
 * @sw_cookie: SW cookie of the buffer reinjected to SW2REO ring
 * @rbm: Return buffer manager of the buffer reinjected to SW2REO ring
 *
 * Returns: None
 */
static inline void
dp_rx_reinject_ring_record_entry(struct dp_soc *soc, uint64_t paddr,
				 uint32_t sw_cookie, uint8_t rbm)
@@ -1153,8 +1163,13 @@ dp_rx_reinject_ring_record_entry(struct dp_soc *soc, uint64_t paddr,
	struct dp_buf_info_record *record;
	uint32_t idx;

	if (qdf_unlikely(!soc->rx_reinject_ring_history))
		return;

	idx = dp_history_get_next_index(&soc->rx_reinject_ring_history->index,
					DP_RX_REINJECT_HIST_MAX);

	/* No NULL check needed for record since its an array */
	record = &soc->rx_reinject_ring_history->entry[idx];

	record->timestamp = qdf_get_log_timestamp();
Loading