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
Este commit está contenido en:

cometido por
qcabuildsw

padre
9dada4165c
commit
bb226bc822
@@ -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.
|
||||
*
|
||||
@@ -1443,6 +1443,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);
|
||||
@@ -1453,17 +1454,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 */
|
||||
|
@@ -549,6 +549,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;
|
||||
@@ -565,8 +566,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);
|
||||
}
|
||||
|
||||
@@ -775,6 +777,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) {
|
||||
@@ -792,8 +795,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)) {
|
||||
|
@@ -2502,6 +2502,7 @@ static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle,
|
||||
uint8_t vdev_id = 0;
|
||||
QDF_STATUS ret;
|
||||
struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_txrx_rx_ops;
|
||||
tp_wma_packetdump_cb packetdump_cb;
|
||||
|
||||
if (wma_handle == NULL) {
|
||||
WMA_LOGE("%s: wma handle is NULL", __func__);
|
||||
@@ -2530,9 +2531,10 @@ static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle,
|
||||
qdf_nbuf_unmap_single(wma_handle->qdf_dev, buf,
|
||||
QDF_DMA_TO_DEVICE);
|
||||
|
||||
if (wma_handle->wma_mgmt_tx_packetdump_cb)
|
||||
wma_handle->wma_mgmt_tx_packetdump_cb(buf,
|
||||
QDF_STATUS_SUCCESS, vdev_id, TX_MGMT_PKT);
|
||||
packetdump_cb = wma_handle->wma_mgmt_tx_packetdump_cb;
|
||||
if (packetdump_cb)
|
||||
packetdump_cb(buf, QDF_STATUS_SUCCESS,
|
||||
vdev_id, TX_MGMT_PKT);
|
||||
|
||||
if (!mgmt_txrx_rx_ops->mgmt_tx_completion_handler) {
|
||||
WMA_LOGE("%s: tx completion callback to mgmt txrx layer is NULL",
|
||||
@@ -3180,6 +3182,7 @@ int wma_form_rx_packet(qdf_nbuf_t buf,
|
||||
int status;
|
||||
tp_wma_handle wma_handle = (tp_wma_handle)
|
||||
cds_get_context(QDF_MODULE_ID_WMA);
|
||||
tp_wma_packetdump_cb packetdump_cb;
|
||||
|
||||
if (!wma_handle) {
|
||||
WMA_LOGE(FL("wma handle is NULL"));
|
||||
@@ -3294,12 +3297,12 @@ int wma_form_rx_packet(qdf_nbuf_t buf,
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Referencia en una nueva incidencia
Block a user