qcacld-3.0: Call close_adapter from close_all_adapters
hdd_close_all_adapters() does not call hdd_close_adapter(), which has lead to a divergence between the logic contained within. Update hdd_close_all_adapters() and hdd_close_adapter() to leverage shared logic to bring them back in sync, and prevent them from diverging again in the future. Change-Id: Ic2fe0908a48927a6fc403ca0f4c21275659908b3 CRs-Fixed: 2326433
This commit is contained in:
@@ -2119,10 +2119,28 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx,
|
|||||||
const char *name, tSirMacAddr macAddr,
|
const char *name, tSirMacAddr macAddr,
|
||||||
unsigned char name_assign_type,
|
unsigned char name_assign_type,
|
||||||
bool rtnl_held);
|
bool rtnl_held);
|
||||||
QDF_STATUS hdd_close_adapter(struct hdd_context *hdd_ctx,
|
|
||||||
struct hdd_adapter *adapter,
|
/**
|
||||||
bool rtnl_held);
|
* hdd_close_adapter() - remove and free @adapter from the adapter list
|
||||||
QDF_STATUS hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held);
|
* @hdd_ctx: The Hdd context containing the adapter list
|
||||||
|
* @adapter: the adapter to remove and free
|
||||||
|
* @rtnl_held: if the caller is already holding the RTNL lock
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
void hdd_close_adapter(struct hdd_context *hdd_ctx,
|
||||||
|
struct hdd_adapter *adapter,
|
||||||
|
bool rtnl_held);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hdd_close_all_adapters() - remove and free all adapters from the adapter list
|
||||||
|
* @hdd_ctx: The Hdd context containing the adapter list
|
||||||
|
* @rtnl_held: if the caller is already holding the RTNL lock
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held);
|
||||||
|
|
||||||
QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx);
|
QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx);
|
||||||
void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held);
|
void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held);
|
||||||
QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx);
|
QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx);
|
||||||
|
@@ -5121,72 +5121,50 @@ err_free_netdev:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDF_STATUS hdd_close_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter,
|
static void __hdd_close_adapter(struct hdd_context *hdd_ctx,
|
||||||
bool rtnl_held)
|
struct hdd_adapter *adapter,
|
||||||
|
bool rtnl_held)
|
||||||
|
{
|
||||||
|
qdf_list_destroy(&adapter->blocked_scan_request_q);
|
||||||
|
qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock);
|
||||||
|
policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
|
||||||
|
|
||||||
|
hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
|
||||||
|
|
||||||
|
if (hdd_ctx->current_intf_count != 0)
|
||||||
|
hdd_ctx->current_intf_count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hdd_close_adapter(struct hdd_context *hdd_ctx,
|
||||||
|
struct hdd_adapter *adapter,
|
||||||
|
bool rtnl_held)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Here we are stopping global bus_bw timer & work per adapter.
|
* Stop the global bus bandwidth timer while touching the adapter list
|
||||||
*
|
* to avoid bad memory access by the timer handler.
|
||||||
* The reason is to fix one race condition between
|
|
||||||
* bus bandwidth work and cleaning up an adapter.
|
|
||||||
* Under some conditions, it is possible for the bus bandwidth
|
|
||||||
* work to access a particularly destroyed adapter, leading to
|
|
||||||
* use-after-free.
|
|
||||||
*/
|
*/
|
||||||
hdd_bus_bw_compute_timer_stop(hdd_ctx);
|
hdd_bus_bw_compute_timer_stop(hdd_ctx);
|
||||||
|
|
||||||
qdf_list_destroy(&adapter->blocked_scan_request_q);
|
|
||||||
qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock);
|
|
||||||
|
|
||||||
/* cleanup adapter */
|
|
||||||
policy_mgr_clear_concurrency_mode(hdd_ctx->psoc,
|
|
||||||
adapter->device_mode);
|
|
||||||
hdd_remove_adapter(hdd_ctx, adapter);
|
hdd_remove_adapter(hdd_ctx, adapter);
|
||||||
hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
|
__hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
|
||||||
|
|
||||||
/* conditionally restart the bw timer */
|
/* conditionally restart the bw timer */
|
||||||
hdd_bus_bw_compute_timer_try_start(hdd_ctx);
|
hdd_bus_bw_compute_timer_try_start(hdd_ctx);
|
||||||
|
|
||||||
/* Adapter removed. Decrement vdev count */
|
|
||||||
if (hdd_ctx->current_intf_count != 0)
|
|
||||||
hdd_ctx->current_intf_count--;
|
|
||||||
|
|
||||||
/* Fw will take care incase of concurrency */
|
|
||||||
return QDF_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
|
||||||
* hdd_close_all_adapters - Close all open adapters
|
|
||||||
* @hdd_ctx: Hdd context
|
|
||||||
* rtnl_held: True if RTNL lock held
|
|
||||||
*
|
|
||||||
* Close all open adapters.
|
|
||||||
*
|
|
||||||
* Return: QDF status code
|
|
||||||
*/
|
|
||||||
QDF_STATUS hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
|
|
||||||
{
|
{
|
||||||
struct hdd_adapter *adapter;
|
struct hdd_adapter *adapter;
|
||||||
QDF_STATUS status;
|
|
||||||
|
|
||||||
hdd_enter();
|
hdd_enter();
|
||||||
|
|
||||||
do {
|
while (QDF_IS_STATUS_SUCCESS(hdd_remove_front_adapter(hdd_ctx,
|
||||||
status = hdd_remove_front_adapter(hdd_ctx, &adapter);
|
&adapter))) {
|
||||||
if (QDF_IS_STATUS_SUCCESS(status)) {
|
wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
|
||||||
wlan_hdd_release_intf_addr(hdd_ctx,
|
__hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
|
||||||
adapter->mac_addr.bytes);
|
}
|
||||||
hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
|
|
||||||
|
|
||||||
/* Adapter removed. Decrement vdev count */
|
|
||||||
if (hdd_ctx->current_intf_count != 0)
|
|
||||||
hdd_ctx->current_intf_count--;
|
|
||||||
}
|
|
||||||
} while (QDF_IS_STATUS_SUCCESS(status));
|
|
||||||
|
|
||||||
hdd_exit();
|
hdd_exit();
|
||||||
|
|
||||||
return QDF_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlan_hdd_reset_prob_rspies(struct hdd_adapter *adapter)
|
void wlan_hdd_reset_prob_rspies(struct hdd_adapter *adapter)
|
||||||
|
Reference in New Issue
Block a user