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

Commit 7a82f506 authored by Yeshwanth Sriram Guntuka's avatar Yeshwanth Sriram Guntuka Committed by Gerrit - the friendly Code Review server
Browse files

qcacld-3.0: Allocate memory for fisa pkt history separately

Fisa packet history is around 6KB for each sw fisa
flow entry and this is part of the dp_fisa_rx_sw_ft
structure. The total size of the SW FT as a result is
around 830KB and the higher order memory allocation via
kzalloc for this could fail in low/fragmented memory
scenarios.

Fix is to allocate memory for FISA pkt history separately
and attach it to the SW FT entry.

Change-Id: I7296d7269c1b86ec38ea1668e8a0893335bbdb6f
CRs-Fixed: 2934487
parent 979bb157
Loading
Loading
Loading
Loading
+47 −3
Original line number Diff line number Diff line
@@ -117,11 +117,11 @@ void dp_fisa_record_pkt(struct dp_fisa_rx_sw_ft *fisa_flow, qdf_nbuf_t nbuf,
	uint32_t index;
	struct fisa_pkt_hist_elem *hist_elem;

	if (!rx_tlv_hdr || !fisa_flow)
	if (!rx_tlv_hdr || !fisa_flow || !fisa_flow->pkt_hist)
		return;

	index = fisa_flow->pkt_hist.idx++ % FISA_FLOW_MAX_AGGR_COUNT;
	hist_elem = &fisa_flow->pkt_hist.hist_elem[index];
	index = fisa_flow->pkt_hist->idx++ % FISA_FLOW_MAX_AGGR_COUNT;
	hist_elem = &fisa_flow->pkt_hist->hist_elem[index];

	hist_elem->ts = qdf_get_log_timestamp();
	qdf_mem_copy(&hist_elem->tlvs, rx_tlv_hdr, sizeof(hist_elem->tlvs));
@@ -647,6 +647,46 @@ static bool is_flow_idx_valid(bool flow_invalid, bool flow_timeout)
		return false;
}

#ifdef WLAN_SUPPORT_RX_FISA_HIST
/**
 * dp_rx_fisa_get_pkt_hist() - Get ptr to pkt history from rx sw ft entry
 * @ft_entry: sw ft entry
 *
 * Return: ptr to pkt history
 */
static inline struct fisa_pkt_hist *
dp_rx_fisa_get_pkt_hist(struct dp_fisa_rx_sw_ft *ft_entry)
{
	return ft_entry->pkt_hist;
}

/**
 * dp_rx_fisa_set_pkt_hist() - Set rx sw ft entry pkt history
 * @ft_entry: sw ft entry
 * @pkt_hist: pkt history ptr
 *
 * Return: None
 */
static inline void
dp_rx_fisa_set_pkt_hist(struct dp_fisa_rx_sw_ft *ft_entry,
			struct fisa_pkt_hist *pkt_hist)
{
	ft_entry->pkt_hist = pkt_hist;
}
#else
static inline struct fisa_pkt_hist *
dp_rx_fisa_get_pkt_hist(struct dp_fisa_rx_sw_ft *ft_entry)
{
	return NULL;
}

static inline void
dp_rx_fisa_set_pkt_hist(struct dp_fisa_rx_sw_ft *ft_entry,
			struct fisa_pkt_hist *pkt_hist)
{
}
#endif

/**
 * dp_fisa_rx_delete_flow() - Delete a flow from SW and HW FST, currently
 * only applicable when FST is in CMEM
@@ -663,6 +703,7 @@ dp_fisa_rx_delete_flow(struct dp_rx_fst *fisa_hdl,
{
	struct dp_fisa_rx_sw_ft *sw_ft_entry;
	u8 reo_id;
	struct fisa_pkt_hist *pkt_hist;

	sw_ft_entry = &(((struct dp_fisa_rx_sw_ft *)
				fisa_hdl->base)[hashed_flow_idx]);
@@ -673,8 +714,11 @@ dp_fisa_rx_delete_flow(struct dp_rx_fst *fisa_hdl,
	/* Flush the flow before deletion */
	dp_rx_fisa_flush_flow_wrap(sw_ft_entry);

	pkt_hist = dp_rx_fisa_get_pkt_hist(sw_ft_entry);

	memset(sw_ft_entry, 0, sizeof(*sw_ft_entry));

	dp_rx_fisa_set_pkt_hist(sw_ft_entry, pkt_hist);
	dp_rx_fisa_update_sw_ft_entry(sw_ft_entry, elem->flow_idx, elem->vdev,
				      fisa_hdl->soc_hdl, hashed_flow_idx);

+53 −0
Original line number Diff line number Diff line
@@ -198,6 +198,55 @@ static QDF_STATUS dp_rx_fst_cmem_init(struct dp_rx_fst *fst)
	return QDF_STATUS_SUCCESS;
}

#ifdef WLAN_SUPPORT_RX_FISA_HIST
/**
 * dp_rx_sw_fst_hist_attach() - Initialize the pkt history per
 *  sw ft entry
 * @fst: pointer to rx fst info
 *
 * Return: None
 */
static void
dp_rx_sw_fst_hist_attach(struct dp_rx_fst *fst)
{
	struct dp_fisa_rx_sw_ft *ft_entry;
	int i;

	ft_entry = (struct dp_fisa_rx_sw_ft *)fst->base;
	for (i = 0; i < fst->max_entries; i++)
		ft_entry[i].pkt_hist = qdf_mem_malloc(
						 sizeof(*ft_entry[i].pkt_hist));
}

/**
 * dp_rx_sw_fst_hist_detach() - De-initialize the pkt history per
 *  sw ft entry
 * @fst: pointer to rx fst info
 *
 * Return: None
 */
static void
dp_rx_sw_fst_hist_detach(struct dp_rx_fst *fst)
{
	struct dp_fisa_rx_sw_ft *ft_entry;
	int i;

	ft_entry = (struct dp_fisa_rx_sw_ft *)fst->base;
	for (i = 0; i < fst->max_entries; i++)
		qdf_mem_free(ft_entry[i].pkt_hist);
}
#else
static inline void
dp_rx_sw_fst_hist_attach(struct dp_rx_fst *fst)
{
}

static inline void
dp_rx_sw_fst_hist_detach(struct dp_rx_fst *fst)
{
}
#endif

/**
 * dp_rx_fst_attach() - Initialize Rx FST and setup necessary parameters
 * @soc: SoC handle
@@ -259,6 +308,8 @@ QDF_STATUS dp_rx_fst_attach(struct dp_soc *soc, struct dp_pdev *pdev)
	for (i = 0; i < fst->max_entries; i++)
		ft_entry[i].napi_id = INVALID_NAPI;

	dp_rx_sw_fst_hist_attach(fst);

	fst->hal_rx_fst = hal_rx_fst_attach(soc->osdev,
					    &fst->hal_rx_fst_base_paddr,
					    fst->max_entries,
@@ -300,6 +351,7 @@ QDF_STATUS dp_rx_fst_attach(struct dp_soc *soc, struct dp_pdev *pdev)
	qdf_spinlock_destroy(&fst->dp_rx_fst_lock);
	hal_rx_fst_detach(fst->hal_rx_fst, soc->osdev);
out1:
	dp_rx_sw_fst_hist_detach(fst);
	dp_context_free_mem(soc, DP_FISA_RX_FT_TYPE, fst->base);
out2:
	qdf_mem_free(fst);
@@ -395,6 +447,7 @@ void dp_rx_fst_detach(struct dp_soc *soc, struct dp_pdev *pdev)
		else
			hal_rx_fst_detach(dp_fst->hal_rx_fst, soc->osdev);

		dp_rx_sw_fst_hist_detach(dp_fst);
		dp_context_free_mem(soc, DP_FISA_RX_FT_TYPE, dp_fst->base);
		qdf_spinlock_destroy(&dp_fst->dp_rx_fst_lock);
		qdf_mem_free(dp_fst);