qcacld-3.0: Avoid access of deleted peer during RX thread close

During SSR case in wlan_hdd_stop_modules(), ol_txrx_pdev_pre_detach()
cleanup the peer forcibly. Later RX Thread is getting closed as part
of cds_sched_close(). So chances of accessing deleted peer is there.

Shutdown RX thread before doing ol_txrx_pdev_pre_detach() to avoid
the chances of accessing deleted peer.

Change-Id: Iae27262396d8245eeb7a9b39cb678fad14815260
CRs-Fixed: 2349994
此提交包含在:
Alok Kumar
2018-10-11 12:40:42 +05:30
提交者 nshrivas
父節點 57ed3b03e3
當前提交 ac74177daa
共有 3 個檔案被更改,包括 65 行新增17 行删除

查看文件

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2012-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
@@ -260,6 +260,15 @@ void cds_drop_rxpkt_by_staid(p_cds_sched_context pSchedContext, uint16_t staId);
void cds_indicate_rxpkt(p_cds_sched_context pSchedContext,
struct cds_ol_rx_pkt *pkt);
/**
* cds_close_rx_thread() - close the Rx thread
*
* This api closes the Rx thread:
*
* Return: qdf status
*/
QDF_STATUS cds_close_rx_thread(void);
/*---------------------------------------------------------------------------
\brief cds_alloc_ol_rx_pkt() - API to return next available cds message
The \a cds_alloc_ol_rx_pkt() returns next available cds message buffer
@@ -331,6 +340,19 @@ void cds_indicate_rxpkt(p_cds_sched_context pSchedContext,
{
}
/**
* cds_close_rx_thread() - close the Rx thread
*
* This api closes the Rx thread:
*
* Return: qdf status
*/
static inline
QDF_STATUS cds_close_rx_thread(void)
{
return QDF_STATUS_SUCCESS;
}
/**
* cds_alloc_ol_rx_pkt() - API to return next available cds message
* @pSchedContext: pointer to CDS Sched Context

查看文件

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2012-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
@@ -1052,6 +1052,7 @@ QDF_STATUS cds_post_disable(void)
struct hif_opaque_softc *hif_ctx;
struct cdp_pdev *txrx_pdev;
struct scheduler_ctx *sched_ctx;
QDF_STATUS qdf_status;
wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
if (!wma_handle) {
@@ -1096,6 +1097,12 @@ QDF_STATUS cds_post_disable(void)
htc_stop(gp_cds_context->htc_ctx);
}
qdf_status = cds_close_rx_thread();
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
cds_err("Failed to close RX thread!");
return QDF_STATUS_E_INVAL;
}
cdp_pdev_pre_detach(cds_get_context(QDF_MODULE_ID_SOC),
(struct cdp_pdev *)txrx_pdev, 1);

查看文件

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2014-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
@@ -608,6 +608,38 @@ cds_indicate_rxpkt(p_cds_sched_context pSchedContext,
wake_up_interruptible(&pSchedContext->ol_rx_wait_queue);
}
/**
* cds_close_rx_thread() - close the Rx thread
*
* This api closes the Rx thread:
*
* Return: qdf status
*/
QDF_STATUS cds_close_rx_thread(void)
{
cds_debug("invoked");
if (!gp_cds_sched_context) {
cds_err("gp_cds_sched_context == NULL");
return QDF_STATUS_E_FAILURE;
}
if (!gp_cds_sched_context->ol_rx_thread)
return QDF_STATUS_SUCCESS;
/* Shut down Tlshim Rx thread */
set_bit(RX_SHUTDOWN_EVENT, &gp_cds_sched_context->ol_rx_event_flag);
set_bit(RX_POST_EVENT, &gp_cds_sched_context->ol_rx_event_flag);
wake_up_interruptible(&gp_cds_sched_context->ol_rx_wait_queue);
wait_for_completion(&gp_cds_sched_context->ol_rx_shutdown);
gp_cds_sched_context->ol_rx_thread = NULL;
cds_drop_rxpkt_by_staid(gp_cds_sched_context, WLAN_MAX_STA_COUNT);
cds_free_ol_rx_pkt_freeq(gp_cds_sched_context);
qdf_cpuhp_unregister(&gp_cds_sched_context->cpuhp_event_handle);
return QDF_STATUS_SUCCESS;
} /* cds_close_rx_thread */
/**
* cds_drop_rxpkt_by_staid() - api to drop pending rx packets for a sta
* @pSchedContext: Pointer to the global CDS Sched Context
@@ -791,20 +823,7 @@ QDF_STATUS cds_sched_close(void)
return QDF_STATUS_E_FAILURE;
}
#ifdef QCA_CONFIG_SMP
if (!gp_cds_sched_context->ol_rx_thread)
return QDF_STATUS_SUCCESS;
/* Shut down Tlshim Rx thread */
set_bit(RX_SHUTDOWN_EVENT, &gp_cds_sched_context->ol_rx_event_flag);
set_bit(RX_POST_EVENT, &gp_cds_sched_context->ol_rx_event_flag);
wake_up_interruptible(&gp_cds_sched_context->ol_rx_wait_queue);
wait_for_completion(&gp_cds_sched_context->ol_rx_shutdown);
gp_cds_sched_context->ol_rx_thread = NULL;
cds_drop_rxpkt_by_staid(gp_cds_sched_context, WLAN_MAX_STA_COUNT);
cds_free_ol_rx_pkt_freeq(gp_cds_sched_context);
qdf_cpuhp_unregister(&gp_cds_sched_context->cpuhp_event_handle);
#endif
cds_close_rx_thread();
gp_cds_sched_context = NULL;
return QDF_STATUS_SUCCESS;
} /* cds_sched_close() */