wifi: iwlwifi: call napi_synchronize() before freeing rx/tx queues
When rx/tx queues are being freed, on a different CPU there could be still rx flow running. Call napi_synchronize() to prevent such a race. Signed-off-by: Gregory Greenman <gregory.greenman@intel.com> Co-developed-by: Benjamin Berg <benjamin.berg@intel.com> Signed-off-by: Benjamin Berg <benjamin.berg@intel.com> Link: https://lore.kernel.org/r/20230416154301.5171ee44dcc1.Iff18718540da412e084e7d8266447d40730600ed@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
f8f9c31129
commit
5af2bb3168
@ -497,6 +497,7 @@ int iwl_pcie_rx_stop(struct iwl_trans *trans);
|
||||
void iwl_pcie_rx_free(struct iwl_trans *trans);
|
||||
void iwl_pcie_free_rbs_pool(struct iwl_trans *trans);
|
||||
void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq);
|
||||
void iwl_pcie_rx_napi_sync(struct iwl_trans *trans);
|
||||
void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority,
|
||||
struct iwl_rxq *rxq);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2003-2014, 2018-2022 Intel Corporation
|
||||
* Copyright (C) 2003-2014, 2018-2023 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
@ -1053,6 +1053,22 @@ static int iwl_pcie_napi_poll_msix(struct napi_struct *napi, int budget)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iwl_pcie_rx_napi_sync(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int i;
|
||||
|
||||
if (unlikely(!trans_pcie->rxq))
|
||||
return;
|
||||
|
||||
for (i = 0; i < trans->num_rx_queues; i++) {
|
||||
struct iwl_rxq *rxq = &trans_pcie->rxq[i];
|
||||
|
||||
if (rxq && rxq->napi.poll)
|
||||
napi_synchronize(&rxq->napi);
|
||||
}
|
||||
}
|
||||
|
||||
static int _iwl_pcie_rx_init(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
@ -156,6 +156,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
|
||||
if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
|
||||
IWL_DEBUG_INFO(trans,
|
||||
"DEVICE_ENABLED bit was set and is now cleared\n");
|
||||
iwl_pcie_rx_napi_sync(trans);
|
||||
iwl_txq_gen2_tx_free(trans);
|
||||
iwl_pcie_rx_stop(trans);
|
||||
}
|
||||
|
@ -1260,6 +1260,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans)
|
||||
if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
|
||||
IWL_DEBUG_INFO(trans,
|
||||
"DEVICE_ENABLED bit was set and is now cleared\n");
|
||||
iwl_pcie_rx_napi_sync(trans);
|
||||
iwl_pcie_tx_stop(trans);
|
||||
iwl_pcie_rx_stop(trans);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user