From 19acf9243c59c2a06db2362fbda8aada9543ce28 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Fri, 30 Apr 2021 15:02:25 +0530 Subject: [PATCH] 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 --- core/dp/txrx3.0/dp_fisa_rx.c | 50 ++++++++++++++++++++++++++++++++-- core/dp/txrx3.0/dp_rx_fst.c | 53 ++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/core/dp/txrx3.0/dp_fisa_rx.c b/core/dp/txrx3.0/dp_fisa_rx.c index 04d90cfa19ab..eed17a9f9ef0 100644 --- a/core/dp/txrx3.0/dp_fisa_rx.c +++ b/core/dp/txrx3.0/dp_fisa_rx.c @@ -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); diff --git a/core/dp/txrx3.0/dp_rx_fst.c b/core/dp/txrx3.0/dp_rx_fst.c index c46a0c077180..023729a53bf1 100644 --- a/core/dp/txrx3.0/dp_rx_fst.c +++ b/core/dp/txrx3.0/dp_rx_fst.c @@ -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 @@ timer_init_fail: 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);