From 449a268392aeb4da8a136ec4582c4472ab14965e Mon Sep 17 00:00:00 2001 From: phadiman Date: Wed, 20 Feb 2019 14:00:00 +0530 Subject: [PATCH] qcacmn: Reuse Rx Descriptor Pool Array wifi up/down will cause soc stop and soc start which will allocate rx desc pool array memory for each wifi up This creates memory fragmentation issue hence reuse Rx descriptor pool array across wifi up/down and free only nbufs CRs-Fixed: 2394666 Change-Id: Ic897c733dfba3d8829e2f2f51099cd615b8a7ea2 --- dp/wifi3.0/dp_main.c | 5 ++++ dp/wifi3.0/dp_rx.c | 5 +++- dp/wifi3.0/dp_rx.h | 3 +++ dp/wifi3.0/dp_rx_desc.c | 47 ++++++++++++++++++++++++++++------- dp/wifi3.0/dp_rx_mon_dest.c | 8 ++++-- dp/wifi3.0/dp_rx_mon_status.c | 8 ++++-- 6 files changed, 62 insertions(+), 14 deletions(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 9cb2e23cc2..920c7af33b 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -3677,6 +3677,11 @@ static void dp_pdev_deinit(struct cdp_pdev *txrx_pdev, int force) */ static void dp_pdev_deinit_wifi3(struct cdp_pdev *txrx_pdev, int force) { + struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev; + struct dp_soc *soc = pdev->soc; + + soc->dp_soc_reinit = TRUE; + dp_pdev_deinit(txrx_pdev, force); } diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 5fb2919165..8fec9c2c11 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -1892,7 +1892,10 @@ dp_rx_pdev_detach(struct dp_pdev *pdev) rx_desc_pool = &soc->rx_desc_buf[pdev_id]; if (rx_desc_pool->pool_size != 0) { - dp_rx_desc_pool_free(soc, pdev_id, rx_desc_pool); + if (!dp_is_soc_reinit(soc)) + dp_rx_desc_pool_free(soc, pdev_id, rx_desc_pool); + else + dp_rx_desc_nbuf_pool_free(soc, rx_desc_pool); } return; diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index e34552024a..8eeec3e57e 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -364,6 +364,9 @@ void dp_rx_desc_pool_free(struct dp_soc *soc, uint32_t pool_id, struct rx_desc_pool *rx_desc_pool); +void dp_rx_desc_nbuf_pool_free(struct dp_soc *soc, + struct rx_desc_pool *rx_desc_pool); + void dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list, struct dp_peer *peer); diff --git a/dp/wifi3.0/dp_rx_desc.c b/dp/wifi3.0/dp_rx_desc.c index b9e6e623bb..67e41a94b1 100644 --- a/dp/wifi3.0/dp_rx_desc.c +++ b/dp/wifi3.0/dp_rx_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,15 +35,17 @@ QDF_STATUS dp_rx_desc_pool_alloc(struct dp_soc *soc, uint32_t pool_id, { uint32_t i; - rx_desc_pool->array = - qdf_mem_malloc(pool_size * - sizeof(union dp_rx_desc_list_elem_t)); + if (!dp_is_soc_reinit(soc)) { + rx_desc_pool->array = + qdf_mem_malloc(pool_size * + sizeof(union dp_rx_desc_list_elem_t)); - if (!(rx_desc_pool->array)) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, - "%s: RX Desc Pool[%d] allocation failed", - __func__, pool_id); - return QDF_STATUS_E_NOMEM; + if (!(rx_desc_pool->array)) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s: RX Desc Pool[%d] allocation failed", + __func__, pool_id); + return QDF_STATUS_E_NOMEM; + } } /* Initialize the lock */ @@ -96,6 +98,33 @@ void dp_rx_desc_pool_free(struct dp_soc *soc, uint32_t pool_id, qdf_spinlock_destroy(&rx_desc_pool->lock); } +/* + * dp_rx_desc_pool_free_nbuf() - free the sw rx desc nbufs called during + * de-initialization of wifi module. + * + * @soc: core txrx main context + * @pool_id: pool_id which is one of 3 mac_ids + * @rx_desc_pool: rx descriptor pool pointer + */ +void dp_rx_desc_nbuf_pool_free(struct dp_soc *soc, + struct rx_desc_pool *rx_desc_pool) +{ + int i; + + qdf_spin_lock_bh(&rx_desc_pool->lock); + for (i = 0; i < rx_desc_pool->pool_size; i++) { + if (rx_desc_pool->array[i].rx_desc.in_use) { + if (!(rx_desc_pool->array[i].rx_desc.unmapped)) + qdf_nbuf_unmap_single(soc->osdev, + rx_desc_pool->array[i].rx_desc.nbuf, + QDF_DMA_BIDIRECTIONAL); + qdf_nbuf_free(rx_desc_pool->array[i].rx_desc.nbuf); + } + } + qdf_spin_unlock_bh(&rx_desc_pool->lock); + qdf_spinlock_destroy(&rx_desc_pool->lock); +} + /* * dp_rx_get_free_desc_list() - provide a list of descriptors from * the free rx desc pool. diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index 3a7dfc08d5..c8ab3e74be 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -1179,8 +1179,12 @@ dp_rx_pdev_mon_buf_detach(struct dp_pdev *pdev, int mac_id) struct rx_desc_pool *rx_desc_pool; rx_desc_pool = &soc->rx_desc_mon[mac_id]; - if (rx_desc_pool->pool_size != 0) - dp_rx_desc_pool_free(soc, mac_id, rx_desc_pool); + if (rx_desc_pool->pool_size != 0) { + if (!dp_is_soc_reinit(soc)) + dp_rx_desc_pool_free(soc, mac_id, rx_desc_pool); + else + dp_rx_desc_nbuf_pool_free(soc, rx_desc_pool); + } return QDF_STATUS_SUCCESS; } diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index 657a611fcf..b9b3e1ce09 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -832,8 +832,12 @@ dp_rx_pdev_mon_status_detach(struct dp_pdev *pdev, int mac_id) struct rx_desc_pool *rx_desc_pool; rx_desc_pool = &soc->rx_desc_status[mac_id]; - if (rx_desc_pool->pool_size != 0) - dp_rx_desc_pool_free(soc, mac_id, rx_desc_pool); + if (rx_desc_pool->pool_size != 0) { + if (!dp_is_soc_reinit(soc)) + dp_rx_desc_pool_free(soc, mac_id, rx_desc_pool); + else + dp_rx_desc_nbuf_pool_free(soc, rx_desc_pool); + } return QDF_STATUS_SUCCESS; }