summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimanshu Agarwal <himanaga@codeaurora.org>2017-01-18 20:45:01 +0530
committerqcabuildsw <qcabuildsw@localhost>2017-01-20 20:37:16 -0800
commitdc7854568fde7a222994afc08214a2f12a0a5b0b (patch)
treea3bee1c6b569d539ef3b409d3a79c09d6c52cf0d
parentb255f02525bff9ecf94829a3d57ec76a6bcb326c (diff)
qcacld-3.0: Use local variable to avoid race condition in packetdump
Race condiiton is observed as deregistration of 32 tx/rx packetdump feature and packetdump callback call is happening at the same time causing NULL pointer dereference. Use local variable to store packetdump callback to avoid this race condition. Change-Id: Id4246d85e3816c0a3b8d0d0c1ef21e5ff053b608 CRs-Fixed: 1112126
-rw-r--r--core/dp/txrx/ol_rx.c21
-rw-r--r--core/dp/txrx/ol_tx_send.c14
-rw-r--r--core/wma/src/wma_mgmt.c19
3 files changed, 31 insertions, 23 deletions
diff --git a/core/dp/txrx/ol_rx.c b/core/dp/txrx/ol_rx.c
index 4a29fe4f501a..9e0b4f37b819 100644
--- a/core/dp/txrx/ol_rx.c
+++ b/core/dp/txrx/ol_rx.c
@@ -1451,6 +1451,7 @@ void ol_rx_pkt_dump_call(
v_CONTEXT_t vos_context;
ol_txrx_pdev_handle pdev;
struct ol_txrx_peer_t *peer = NULL;
+ tp_ol_packetdump_cb packetdump_cb;
vos_context = cds_get_global_context();
pdev = cds_get_context(QDF_MODULE_ID_TXRX);
@@ -1461,17 +1462,17 @@ void ol_rx_pkt_dump_call(
return;
}
- if (pdev->ol_rx_packetdump_cb) {
- peer = ol_txrx_peer_find_by_id(pdev, peer_id);
- if (!peer) {
- TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
- "%s: peer with peer id %d is NULL", __func__,
- peer_id);
- return;
- }
- pdev->ol_rx_packetdump_cb(msdu, status, peer->vdev->vdev_id,
- RX_DATA_PKT);
+ peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+ if (!peer) {
+ TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
+ "%s: peer with peer id %d is NULL", __func__,
+ peer_id);
+ return;
}
+
+ packetdump_cb = pdev->ol_rx_packetdump_cb;
+ if (packetdump_cb)
+ packetdump_cb(msdu, status, peer->vdev->vdev_id, RX_DATA_PKT);
}
/* the msdu_list passed here must be NULL terminated */
diff --git a/core/dp/txrx/ol_tx_send.c b/core/dp/txrx/ol_tx_send.c
index 5da7b534cb05..628a9afc9a2c 100644
--- a/core/dp/txrx/ol_tx_send.c
+++ b/core/dp/txrx/ol_tx_send.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -539,6 +539,7 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
struct ol_tx_desc_t *tx_desc;
uint32_t byte_cnt = 0;
qdf_nbuf_t netbuf;
+ tp_ol_packetdump_cb packetdump_cb;
union ol_tx_desc_list_elem_t *lcl_freelist = NULL;
union ol_tx_desc_list_elem_t *tx_desc_last = NULL;
@@ -555,8 +556,9 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
QDF_NBUF_UPDATE_TX_PKT_COUNT(netbuf, QDF_NBUF_TX_PKT_FREE);
if (tx_desc->pkt_type != OL_TX_FRM_TSO) {
- if (pdev->ol_tx_packetdump_cb)
- pdev->ol_tx_packetdump_cb(netbuf, status,
+ packetdump_cb = pdev->ol_tx_packetdump_cb;
+ if (packetdump_cb)
+ packetdump_cb(netbuf, status,
tx_desc->vdev->vdev_id, TX_DATA_PKT);
}
@@ -765,6 +767,7 @@ ol_tx_single_completion_handler(ol_txrx_pdev_handle pdev,
{
struct ol_tx_desc_t *tx_desc;
qdf_nbuf_t netbuf;
+ tp_ol_packetdump_cb packetdump_cb;
tx_desc = ol_tx_desc_find_check(pdev, tx_desc_id);
if (tx_desc == NULL) {
@@ -782,8 +785,9 @@ ol_tx_single_completion_handler(ol_txrx_pdev_handle pdev,
/* Do one shot statistics */
TXRX_STATS_UPDATE_TX_STATS(pdev, status, 1, qdf_nbuf_len(netbuf));
- if (pdev->ol_tx_packetdump_cb)
- pdev->ol_tx_packetdump_cb(netbuf, status,
+ packetdump_cb = pdev->ol_tx_packetdump_cb;
+ if (packetdump_cb)
+ packetdump_cb(netbuf, status,
tx_desc->vdev->vdev_id, TX_MGMT_PKT);
if (OL_TX_DESC_NO_REFS(tx_desc)) {
diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c
index 05c141ca5ba4..3a92298b1973 100644
--- a/core/wma/src/wma_mgmt.c
+++ b/core/wma/src/wma_mgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -2483,6 +2483,7 @@ static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle,
{
struct wmi_desc_t *wmi_desc;
ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+ tp_wma_packetdump_cb packetdump_cb;
if (pdev == NULL) {
WMA_LOGE("%s: NULL pdev pointer", __func__);
@@ -2503,9 +2504,10 @@ static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle,
qdf_nbuf_unmap_single(pdev->osdev, wmi_desc->nbuf,
QDF_DMA_TO_DEVICE);
- if (wma_handle->wma_mgmt_tx_packetdump_cb)
- wma_handle->wma_mgmt_tx_packetdump_cb(wmi_desc->nbuf,
- QDF_STATUS_SUCCESS, wmi_desc->vdev_id, TX_MGMT_PKT);
+ packetdump_cb = wma_handle->wma_mgmt_tx_packetdump_cb;
+ if (packetdump_cb)
+ packetdump_cb(wmi_desc->nbuf, QDF_STATUS_SUCCESS,
+ wmi_desc->vdev_id, TX_MGMT_PKT);
if (wmi_desc->tx_cmpl_cb)
wmi_desc->tx_cmpl_cb(wma_handle->mac_context,
@@ -3166,6 +3168,7 @@ static int wma_mgmt_rx_process(void *handle, uint8_t *data,
struct ieee80211_frame *wh;
uint8_t mgt_type, mgt_subtype;
int status;
+ tp_wma_packetdump_cb packetdump_cb;
if (!wma_handle) {
WMA_LOGE("%s: Failed to get WMA context", __func__);
@@ -3330,12 +3333,12 @@ static int wma_mgmt_rx_process(void *handle, uint8_t *data,
return -EINVAL;
}
+ packetdump_cb = wma_handle->wma_mgmt_rx_packetdump_cb;
if ((mgt_type == IEEE80211_FC0_TYPE_MGT &&
mgt_subtype != IEEE80211_FC0_SUBTYPE_BEACON) &&
- wma_handle->wma_mgmt_rx_packetdump_cb)
- wma_handle->wma_mgmt_rx_packetdump_cb(rx_pkt->pkt_buf,
- QDF_STATUS_SUCCESS, rx_pkt->pkt_meta.sessionId,
- RX_MGMT_PKT);
+ packetdump_cb)
+ packetdump_cb(rx_pkt->pkt_buf, QDF_STATUS_SUCCESS,
+ rx_pkt->pkt_meta.sessionId, RX_MGMT_PKT);
wma_handle->mgmt_rx(wma_handle, rx_pkt);
return 0;