From e0baa4436a80711678565bf8135e91abe2b39c2c Mon Sep 17 00:00:00 2001 From: Pramod Simha Date: Tue, 27 Jun 2017 15:21:39 -0700 Subject: [PATCH] qcacmn: Add misc list to hold HTT msgs Add a misc list which stores HTT msgs & later frees them during rmmod. This is required to prevent memory leaks during rmmod. Change-Id: Iecc04ec38cfa1b459064da74dffa5bfeffdba956 CRs-Fixed: 2068058 --- dp/wifi3.0/dp_htt.c | 108 ++++++++++++++++++++++++++++++++++++++++++-- dp/wifi3.0/dp_htt.h | 4 ++ 2 files changed, 108 insertions(+), 4 deletions(-) diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index e37adc641917..c956dfee691a 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -35,6 +35,13 @@ ((msg_bytes) + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING) #define DP_EXT_MSG_LENGTH 2048 +#define DP_HTT_SEND_HTC_PKT(soc, pkt) \ +do { \ + if (htc_send_pkt(soc->htc_soc, &pkt->htc_pkt) == \ + QDF_STATUS_SUCCESS) \ + htt_htc_misc_pkt_list_add(soc, pkt); \ +} while (0) + /* * htt_htc_pkt_alloc() - Allocate HTC packet buffer * @htt_soc: HTT SOC handle @@ -91,6 +98,97 @@ htt_htc_pkt_pool_free(struct htt_soc *soc) soc->htt_htc_pkt_freelist = NULL; } +/* + * htt_htc_misc_pkt_list_trim() - trim misc list + * @htt_soc: HTT SOC handle + * @level: max no. of pkts in list + */ +static void +htt_htc_misc_pkt_list_trim(struct htt_soc *soc, int level) +{ + struct dp_htt_htc_pkt_union *pkt, *next, *prev = NULL; + int i = 0; + qdf_nbuf_t netbuf; + + HTT_TX_MUTEX_ACQUIRE(&soc->htt_tx_mutex); + pkt = soc->htt_htc_pkt_misclist; + while (pkt) { + next = pkt->u.next; + /* trim the out grown list*/ + if (++i > level) { + netbuf = + (qdf_nbuf_t)(pkt->u.pkt.htc_pkt.pNetBufContext); + qdf_nbuf_unmap(soc->osdev, netbuf, QDF_DMA_TO_DEVICE); + qdf_nbuf_free(netbuf); + qdf_mem_free(pkt); + pkt = NULL; + if (prev) + prev->u.next = NULL; + } + prev = pkt; + pkt = next; + } + HTT_TX_MUTEX_RELEASE(&soc->htt_tx_mutex); +} + +/* + * htt_htc_misc_pkt_list_add() - Add pkt to misc list + * @htt_soc: HTT SOC handle + * @dp_htt_htc_pkt: pkt to be added to list + */ +static void +htt_htc_misc_pkt_list_add(struct htt_soc *soc, struct dp_htt_htc_pkt *pkt) +{ + struct dp_htt_htc_pkt_union *u_pkt = + (struct dp_htt_htc_pkt_union *)pkt; + int misclist_trim_level = htc_get_tx_queue_depth(soc->htc_soc, + pkt->htc_pkt.Endpoint) + + DP_HTT_HTC_PKT_MISCLIST_SIZE; + + HTT_TX_MUTEX_ACQUIRE(&soc->htt_tx_mutex); + if (soc->htt_htc_pkt_misclist) { + u_pkt->u.next = soc->htt_htc_pkt_misclist; + soc->htt_htc_pkt_misclist = u_pkt; + } else { + soc->htt_htc_pkt_misclist = u_pkt; + } + HTT_TX_MUTEX_RELEASE(&soc->htt_tx_mutex); + + /* only ce pipe size + tx_queue_depth could possibly be in use + * free older packets in the misclist + */ + htt_htc_misc_pkt_list_trim(soc, misclist_trim_level); +} + +/* + * htt_htc_misc_pkt_pool_free() - free pkts in misc list + * @htt_soc: HTT SOC handle + */ +static void +htt_htc_misc_pkt_pool_free(struct htt_soc *soc) +{ + struct dp_htt_htc_pkt_union *pkt, *next; + qdf_nbuf_t netbuf; + + pkt = soc->htt_htc_pkt_misclist; + + while (pkt) { + next = pkt->u.next; + netbuf = (qdf_nbuf_t) (pkt->u.pkt.htc_pkt.pNetBufContext); + qdf_nbuf_unmap(soc->osdev, netbuf, QDF_DMA_TO_DEVICE); + + soc->stats.htc_pkt_free++; + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s: Pkt free count %d\n", + __func__, soc->stats.htc_pkt_free); + + qdf_nbuf_free(netbuf); + qdf_mem_free(pkt); + pkt = next; + } + soc->htt_htc_pkt_misclist = NULL; +} + /* * htt_t2h_mac_addr_deswizzle() - Swap MAC addr bytes if FW endianess differ * @tgt_mac_addr: Target MAC @@ -225,7 +323,7 @@ static int htt_h2t_ver_req_msg(struct htt_soc *soc) 1); /* tag - not relevant here */ SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); - htc_send_pkt(soc->htc_soc, &pkt->htc_pkt); + DP_HTT_SEND_HTC_PKT(soc, pkt); return 0; } @@ -480,7 +578,7 @@ int htt_srng_setup(void *htt_soc, int mac_id, void *hal_srng, 1); /* tag - not relevant here */ SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, htt_msg); - htc_send_pkt(soc->htc_soc, &pkt->htc_pkt); + DP_HTT_SEND_HTC_PKT(soc, pkt); return QDF_STATUS_SUCCESS; @@ -916,7 +1014,7 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, 1); /* tag - not relevant here */ SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, htt_msg); - htc_send_pkt(soc->htc_soc, &pkt->htc_pkt); + DP_HTT_SEND_HTC_PKT(soc, pkt); return QDF_STATUS_SUCCESS; fail1: @@ -1458,6 +1556,7 @@ htt_soc_detach(void *htt_soc) { struct htt_soc *soc = (struct htt_soc *)htt_soc; + htt_htc_misc_pkt_pool_free(soc); htt_htc_pkt_pool_free(soc); HTT_TX_MUTEX_DESTROY(&soc->htt_tx_mutex); qdf_mem_free(soc); @@ -1558,5 +1657,6 @@ QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev, 1); /* tag - not relevant here */ SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); - return htc_send_pkt(soc->htc_soc, &pkt->htc_pkt); + DP_HTT_SEND_HTC_PKT(soc, pkt); + return 0; } diff --git a/dp/wifi3.0/dp_htt.h b/dp/wifi3.0/dp_htt.h index ce6b61e4bbe3..9b2f5740a445 100644 --- a/dp/wifi3.0/dp_htt.h +++ b/dp/wifi3.0/dp_htt.h @@ -44,6 +44,8 @@ #define HTT_MAC_ADDR_LEN 6 #endif +#define DP_HTT_HTC_PKT_MISCLIST_SIZE 256 + struct dp_htt_htc_pkt { void *soc_ctxt; qdf_dma_addr_t nbuf_paddr; @@ -65,6 +67,7 @@ struct htt_soc { qdf_device_t osdev; HTC_ENDPOINT_ID htc_endpoint; struct dp_htt_htc_pkt_union *htt_htc_pkt_freelist; + struct dp_htt_htc_pkt_union *htt_htc_pkt_misclist; struct { u_int8_t major; u_int8_t minor; @@ -76,6 +79,7 @@ struct htt_soc { struct { int htc_err_cnt; + int htc_pkt_free; } stats; HTT_TX_MUTEX_TYPE htt_tx_mutex;