From ed6dfb270200fdc137efd270f3df42d066e89c8b Mon Sep 17 00:00:00 2001 From: Vulupala Shashank Reddy Date: Thu, 21 Oct 2021 11:50:04 +0530 Subject: [PATCH] qcacld-3.0: Add ref count for global vdev used in packet capture Currently the global vdev gp_pkt_capture_vdev used in packet capture does not have ref count. Add ref count for global vdev used in packet capture component. Change-Id: I1cc619b31c81a77af0842ce219cfcc96060626a0 CRs-Fixed: 3049225 --- .../core/src/wlan_pkt_capture_data_txrx.c | 72 +++++++++++++------ .../core/src/wlan_pkt_capture_main.c | 47 +++++++++--- .../core/src/wlan_pkt_capture_mgmt_txrx.c | 45 ++++++++---- 3 files changed, 119 insertions(+), 45 deletions(-) diff --git a/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c b/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c index 0b04f510d79f..ad3e232b86ff 100644 --- a/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c +++ b/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. 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 @@ -854,7 +855,7 @@ pkt_capture_rx_data_cb( { struct pkt_capture_vdev_priv *vdev_priv; qdf_nbuf_t buf_list = (qdf_nbuf_t)nbuf_list; - struct wlan_objmgr_vdev *vdev = context; + struct wlan_objmgr_vdev *vdev; htt_pdev_handle pdev = ppdev; struct pkt_capture_cb_context *cb_ctx; qdf_nbuf_t msdu, next_buf; @@ -865,14 +866,19 @@ pkt_capture_rx_data_cb( static uint8_t preamble_type; static uint32_t vht_sig_a_1; static uint32_t vht_sig_a_2; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + vdev = pkt_capture_get_vdev(); + status = pkt_capture_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(status)) + goto free_buf; vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (qdf_unlikely(!vdev)) - goto free_buf; - cb_ctx = vdev_priv->cb_ctx; - if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) + if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) { + pkt_capture_vdev_put_ref(vdev); goto free_buf; + } msdu = buf_list; while (msdu) { @@ -947,6 +953,7 @@ pkt_capture_rx_data_cb( msdu = next_buf; } + pkt_capture_vdev_put_ref(vdev); return; free_buf: @@ -977,7 +984,7 @@ pkt_capture_rx_data_cb( { struct pkt_capture_vdev_priv *vdev_priv; qdf_nbuf_t buf_list = (qdf_nbuf_t)nbuf_list; - struct wlan_objmgr_vdev *vdev = context; + struct wlan_objmgr_vdev *vdev; struct pkt_capture_cb_context *cb_ctx; qdf_nbuf_t msdu, next_buf; uint8_t drop_count; @@ -987,14 +994,19 @@ pkt_capture_rx_data_cb( struct dp_soc *soc = psoc; hal_soc_handle_t hal_soc; struct hal_rx_msdu_metadata msdu_metadata; + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + vdev = pkt_capture_get_vdev(); + ret = pkt_capture_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(ret)) + goto free_buf; vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (qdf_unlikely(!vdev)) - goto free_buf; - cb_ctx = vdev_priv->cb_ctx; - if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) + if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) { + pkt_capture_vdev_put_ref(vdev); goto free_buf; + } hal_soc = soc->hal_soc; msdu = buf_list; @@ -1018,7 +1030,7 @@ pkt_capture_rx_data_cb( */ /* need to update this to fill rx_status*/ - pkt_capture_rx_mon_get_rx_status(context, psoc, + pkt_capture_rx_mon_get_rx_status(vdev, psoc, rx_tlv_hdr, &rx_status); rx_status.tx_status = status; rx_status.tx_retry_cnt = tx_retry_cnt; @@ -1049,6 +1061,7 @@ pkt_capture_rx_data_cb( msdu = next_buf; } + pkt_capture_vdev_put_ref(vdev); return; free_buf: @@ -1081,7 +1094,7 @@ pkt_capture_tx_data_cb( { qdf_nbuf_t msdu, next_buf; struct pkt_capture_vdev_priv *vdev_priv; - struct wlan_objmgr_vdev *vdev = context; + struct wlan_objmgr_vdev *vdev; htt_pdev_handle pdev = ppdev; struct pkt_capture_cb_context *cb_ctx; uint8_t drop_count; @@ -1096,18 +1109,23 @@ pkt_capture_tx_data_cb( uint32_t headroom; uint16_t seq_no, fc_ctrl; struct mon_rx_status tx_status = {0}; + QDF_STATUS status = QDF_STATUS_SUCCESS; uint8_t localbuf[sizeof(struct ieee80211_qosframe_htc_addr4) + sizeof(struct llc_snap_hdr_t)]; const uint8_t ethernet_II_llc_snap_header_prefix[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (qdf_unlikely(!vdev)) + vdev = pkt_capture_get_vdev(); + status = pkt_capture_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(status)) goto free_buf; + vdev_priv = pkt_capture_vdev_get_priv(vdev); cb_ctx = vdev_priv->cb_ctx; - if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) + if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) { + pkt_capture_vdev_put_ref(vdev); goto free_buf; + } msdu = nbuf_list; while (msdu) { @@ -1224,6 +1242,7 @@ pkt_capture_tx_data_cb( pkt_capture_mon(cb_ctx, msdu, vdev, 0); msdu = next_buf; } + pkt_capture_vdev_put_ref(vdev); return; free_buf: @@ -1273,7 +1292,7 @@ pkt_capture_tx_data_cb( { qdf_nbuf_t msdu, next_buf; struct pkt_capture_vdev_priv *vdev_priv; - struct wlan_objmgr_vdev *vdev = context; + struct wlan_objmgr_vdev *vdev; struct pkt_capture_cb_context *cb_ctx; uint8_t drop_count; struct pkt_capture_tx_hdr_elem_t *ptr_pktcapture_hdr = NULL; @@ -1288,19 +1307,24 @@ pkt_capture_tx_data_cb( uint32_t headroom; uint16_t seq_no, fc_ctrl; struct mon_rx_status tx_status = {0}; + QDF_STATUS ret = QDF_STATUS_SUCCESS; uint8_t localbuf[sizeof(struct ieee80211_qosframe_htc_addr4) + sizeof(struct llc_snap_hdr_t)]; const uint8_t ethernet_II_llc_snap_header_prefix[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; struct qdf_mac_addr bss_peer_mac_address; - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (qdf_unlikely(!vdev)) + vdev = pkt_capture_get_vdev(); + ret = pkt_capture_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(ret)) goto free_buf; + vdev_priv = pkt_capture_vdev_get_priv(vdev); cb_ctx = vdev_priv->cb_ctx; - if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) + if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) { + pkt_capture_vdev_put_ref(vdev); goto free_buf; + } msdu = nbuf_list; while (msdu) { @@ -1401,7 +1425,7 @@ pkt_capture_tx_data_cb( } pkt_capture_update_tx_status( - context, + vdev, &tx_status, &pktcapture_hdr); /* @@ -1413,6 +1437,7 @@ pkt_capture_tx_data_cb( pkt_capture_mon(cb_ctx, msdu, vdev, 0); msdu = next_buf; } + pkt_capture_vdev_put_ref(vdev); return; free_buf: @@ -1432,10 +1457,12 @@ void pkt_capture_datapkt_process( struct pkt_capture_mon_pkt *pkt; pkt_capture_mon_thread_cb callback = NULL; struct wlan_objmgr_vdev *vdev; + QDF_STATUS ret = QDF_STATUS_SUCCESS; status = pkt_capture_txrx_status_map(status); vdev = pkt_capture_get_vdev(); - if (!vdev) + ret = pkt_capture_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(ret)) goto drop_rx_buf; pkt = pkt_capture_alloc_mon_pkt(vdev); @@ -1455,7 +1482,7 @@ void pkt_capture_datapkt_process( } pkt->callback = callback; - pkt->context = (void *)vdev; + pkt->context = NULL; pkt->pdev = (void *)pdev; pkt->monpkt = (void *)mon_buf_list; pkt->vdev_id = vdev_id; @@ -1465,6 +1492,7 @@ void pkt_capture_datapkt_process( qdf_mem_copy(pkt->bssid, bssid, QDF_MAC_ADDR_SIZE); pkt->tx_retry_cnt = tx_retry_cnt; pkt_capture_indicate_monpkt(vdev, pkt); + pkt_capture_vdev_put_ref(vdev); return; drop_rx_buf: diff --git a/components/pkt_capture/core/src/wlan_pkt_capture_main.c b/components/pkt_capture/core/src/wlan_pkt_capture_main.c index d19dba8a2940..7fe763810545 100644 --- a/components/pkt_capture/core/src/wlan_pkt_capture_main.c +++ b/components/pkt_capture/core/src/wlan_pkt_capture_main.c @@ -143,9 +143,11 @@ pkt_capture_get_pktcap_mode_v2() enum pkt_capture_mode mode = PACKET_CAPTURE_MODE_DISABLE; struct pkt_capture_vdev_priv *vdev_priv; struct wlan_objmgr_vdev *vdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; vdev = pkt_capture_get_vdev(); - if (!vdev) + status = pkt_capture_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(status)) return PACKET_CAPTURE_MODE_DISABLE; vdev_priv = pkt_capture_vdev_get_priv(vdev); @@ -154,6 +156,7 @@ pkt_capture_get_pktcap_mode_v2() else mode = vdev_priv->cfg_params.pkt_capture_mode; + pkt_capture_vdev_put_ref(vdev); return mode; } @@ -208,14 +211,18 @@ pkt_capture_process_ppdu_stats(void *log_data) struct pkt_capture_ppdu_stats_q_node *q_node; htt_ppdu_stats_for_smu_tlv *smu; uint32_t stats_len; + QDF_STATUS status = QDF_STATUS_SUCCESS; vdev = pkt_capture_get_vdev(); - if (qdf_unlikely(!vdev)) + status = pkt_capture_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(status)) return; vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (qdf_unlikely(!vdev_priv)) + if (qdf_unlikely(!vdev_priv)) { + pkt_capture_vdev_put_ref(vdev); return; + } smu = (htt_ppdu_stats_for_smu_tlv *)log_data; vdev_priv->tx_nss = smu->nss; @@ -229,6 +236,7 @@ pkt_capture_process_ppdu_stats(void *log_data) */ if (smu->win_size > 8) { qdf_spin_unlock(&vdev_priv->lock_q); + pkt_capture_vdev_put_ref(vdev); pkt_capture_err("win size %d > 8 not supported\n", smu->win_size); return; @@ -240,6 +248,7 @@ pkt_capture_process_ppdu_stats(void *log_data) q_node = qdf_mem_malloc(sizeof(*q_node) + stats_len); if (q_node == NULL) { qdf_spin_unlock(&vdev_priv->lock_q); + pkt_capture_vdev_put_ref(vdev); pkt_capture_err("stats node and buf allocation fail\n"); return; } @@ -250,6 +259,7 @@ pkt_capture_process_ppdu_stats(void *log_data) &q_node->node); } qdf_spin_unlock(&vdev_priv->lock_q); + pkt_capture_vdev_put_ref(vdev); } static void @@ -477,14 +487,17 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data, struct pkt_capture_vdev_priv *vdev_priv; struct pkt_capture_frame_filter *frame_filter; uint16_t vdev_id = 0; + QDF_STATUS ret = QDF_STATUS_SUCCESS; vdev = pkt_capture_get_vdev(); - if (!vdev) + ret = pkt_capture_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(ret)) return; vdev_priv = pkt_capture_vdev_get_priv(vdev); if (!vdev_priv) { pkt_capture_err("vdev priv is NULL"); + pkt_capture_vdev_put_ref(vdev); return; } @@ -495,8 +508,10 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data, { struct dp_tx_desc_s *desc = log_data; - if (!frame_filter->data_tx_frame_filter) + if (!frame_filter->data_tx_frame_filter) { + pkt_capture_vdev_put_ref(vdev); return; + } if (frame_filter->data_tx_frame_filter & PKT_CAPTURE_DATA_FRAME_TYPE_ALL) { @@ -507,7 +522,6 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data, pkt_capture_process_tx_data(soc, log_data, vdev_id, status); } - break; } @@ -522,6 +536,8 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data, */ if (status == RX_OFFLOAD_PKT) qdf_nbuf_free(nbuf); + + pkt_capture_vdev_put_ref(vdev); return; } @@ -552,6 +568,8 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data, */ if (status == RX_OFFLOAD_PKT) qdf_nbuf_free(nbuf); + + pkt_capture_vdev_put_ref(vdev); return; } @@ -579,8 +597,10 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data, qdf_nbuf_t buf = log_data + sizeof(struct htt_tx_offload_deliver_ind_hdr_t); - if (!frame_filter->data_tx_frame_filter) + if (!frame_filter->data_tx_frame_filter) { + pkt_capture_vdev_put_ref(vdev); return; + } offload_deliver_msg = (struct htt_tx_offload_deliver_ind_hdr_t *)log_data; @@ -616,6 +636,7 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data, default: break; } + pkt_capture_vdev_put_ref(vdev); } #else @@ -655,23 +676,29 @@ bool pkt_capture_is_tx_mgmt_enable(struct wlan_objmgr_pdev *pdev) { struct pkt_capture_vdev_priv *vdev_priv; struct wlan_objmgr_vdev *vdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; vdev = pkt_capture_get_vdev(); - if (!vdev) { - pkt_capture_err("vdev is NULL"); + status = pkt_capture_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(status)) { + pkt_capture_err("failed to get vdev ref"); return false; } vdev_priv = pkt_capture_vdev_get_priv(vdev); if (!vdev_priv) { pkt_capture_err("vdev_priv is NULL"); + pkt_capture_vdev_put_ref(vdev); return false; } if (!(vdev_priv->frame_filter.mgmt_tx_frame_filter & - PKT_CAPTURE_MGMT_FRAME_TYPE_ALL)) + PKT_CAPTURE_MGMT_FRAME_TYPE_ALL)) { + pkt_capture_vdev_put_ref(vdev); return false; + } + pkt_capture_vdev_put_ref(vdev); return true; } diff --git a/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c b/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c index 28f13cb7338d..719b75519c18 100644 --- a/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c +++ b/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, 2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. 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 @@ -335,6 +336,7 @@ void pkt_capture_mgmt_tx(struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev; qdf_nbuf_t wbuf; int nbuf_len; + QDF_STATUS status = QDF_STATUS_SUCCESS; if (!pdev) { pkt_capture_err("pdev is NULL"); @@ -342,25 +344,28 @@ void pkt_capture_mgmt_tx(struct wlan_objmgr_pdev *pdev, } vdev = pkt_capture_get_vdev(); - if (!vdev) { - pkt_capture_err("vdev is NULL"); + status = pkt_capture_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(status)) { + pkt_capture_err("failed to get vdev ref"); return; } vdev_priv = pkt_capture_vdev_get_priv(vdev); if (!vdev_priv) { pkt_capture_err("packet capture vdev priv is NULL"); + pkt_capture_vdev_put_ref(vdev); return; } + pkt_capture_vdev_put_ref(vdev); if (pfc->type == IEEE80211_FC0_TYPE_MGT && !(vdev_priv->frame_filter.mgmt_tx_frame_filter & PKT_CAPTURE_MGMT_FRAME_TYPE_ALL)) - return; + goto exit; if (pfc->type == IEEE80211_FC0_TYPE_CTL && !vdev_priv->frame_filter.ctrl_tx_frame_filter) - return; + goto exit; nbuf_len = qdf_nbuf_len(nbuf); wbuf = qdf_nbuf_alloc(NULL, roundup(nbuf_len + RESERVE_BYTES, 4), @@ -368,7 +373,7 @@ void pkt_capture_mgmt_tx(struct wlan_objmgr_pdev *pdev, if (!wbuf) { pkt_capture_err("Failed to allocate wbuf for mgmt len(%u)", nbuf_len); - return; + goto exit; } qdf_nbuf_put_tail(wbuf, nbuf_len); @@ -396,6 +401,8 @@ void pkt_capture_mgmt_tx(struct wlan_objmgr_pdev *pdev, if (QDF_STATUS_SUCCESS != pkt_capture_process_mgmt_tx_data(pdev, ¶ms, wbuf, 0xFF)) qdf_nbuf_free(wbuf); +exit: + pkt_capture_vdev_put_ref(vdev); } void @@ -409,6 +416,7 @@ pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev, tpSirMacFrameCtl pfc; qdf_nbuf_t wbuf, nbuf; int nbuf_len; + QDF_STATUS ret = QDF_STATUS_SUCCESS; if (!pdev) { pkt_capture_err("pdev is NULL"); @@ -416,29 +424,32 @@ pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev, } vdev = pkt_capture_get_vdev(); - if (!vdev) { - pkt_capture_err("vdev is NULL"); + ret = pkt_capture_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(ret)) { + pkt_capture_err("failed to get vdev ref"); return; } vdev_priv = pkt_capture_vdev_get_priv(vdev); if (!vdev_priv) { pkt_capture_err("packet capture vdev priv is NULL"); + pkt_capture_vdev_put_ref(vdev); return; } nbuf = mgmt_txrx_get_nbuf(pdev, desc_id); if (!nbuf) - return; + goto exit; + pfc = (tpSirMacFrameCtl)(qdf_nbuf_data(nbuf)); if (pfc->type == IEEE80211_FC0_TYPE_MGT && !(vdev_priv->frame_filter.mgmt_tx_frame_filter & PKT_CAPTURE_MGMT_FRAME_TYPE_ALL)) - return; + goto exit; if (pfc->type == IEEE80211_FC0_TYPE_CTL && !vdev_priv->frame_filter.ctrl_tx_frame_filter) - return; + goto exit; nbuf_len = qdf_nbuf_len(nbuf); wbuf = qdf_nbuf_alloc(NULL, roundup(nbuf_len + RESERVE_BYTES, 4), @@ -446,7 +457,7 @@ pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev, if (!wbuf) { pkt_capture_err("Failed to allocate wbuf for mgmt len(%u)", nbuf_len); - return; + goto exit; } qdf_nbuf_put_tail(wbuf, nbuf_len); @@ -457,6 +468,9 @@ pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev, pdev, params, wbuf, pkt_capture_mgmt_status_map(status))) qdf_nbuf_free(wbuf); + +exit: + pkt_capture_vdev_put_ref(vdev); } /** @@ -526,10 +540,12 @@ pkt_capture_mgmt_rx_data_cb(struct wlan_objmgr_psoc *psoc, int buf_len; struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_pdev *pdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; vdev = pkt_capture_get_vdev(); - if (!vdev) { - pkt_capture_err("vdev is NULL"); + status = pkt_capture_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(status)) { + pkt_capture_err("failed to get vdev ref"); qdf_nbuf_free(wbuf); return QDF_STATUS_E_FAILURE; } @@ -537,6 +553,7 @@ pkt_capture_mgmt_rx_data_cb(struct wlan_objmgr_psoc *psoc, vdev_priv = pkt_capture_vdev_get_priv(vdev); if (!vdev_priv) { pkt_capture_err("packet capture vdev priv is NULL"); + pkt_capture_vdev_put_ref(vdev); qdf_nbuf_free(wbuf); return QDF_STATUS_E_FAILURE; } @@ -582,6 +599,7 @@ pkt_capture_mgmt_rx_data_cb(struct wlan_objmgr_psoc *psoc, wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf); pdev = wlan_vdev_get_pdev(vdev); + pkt_capture_vdev_put_ref(vdev); if ((pfc->type == IEEE80211_FC0_TYPE_MGT) && (pfc->subType == SIR_MAC_MGMT_DISASSOC || @@ -627,6 +645,7 @@ pkt_capture_mgmt_rx_data_cb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; exit: + pkt_capture_vdev_put_ref(vdev); qdf_nbuf_free(wbuf); return QDF_STATUS_SUCCESS; }