iwlwifi: fix possible priv->mutex deadlock during suspend

This patch moves _cancel_deferred_work out of mutex protection and removes
unnecessary mutex in pci_suspend and pci_resume.

Cc: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Zhu Yi 2007-12-19 13:59:52 +08:00 committed by John W. Linville
parent 7d2e941b0b
commit b24d22b1d1
2 changed files with 10 additions and 26 deletions

View File

@ -6243,8 +6243,6 @@ static void __iwl_down(struct iwl_priv *priv)
/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
iwl_cancel_deferred_work(priv);
/* Wipe out the EXIT_PENDING status bit if we are not actually
* exiting the module */
if (!exit_pending)
@ -6319,6 +6317,8 @@ static void iwl_down(struct iwl_priv *priv)
mutex_lock(&priv->mutex);
__iwl_down(priv);
mutex_unlock(&priv->mutex);
iwl_cancel_deferred_work(priv);
}
#define MAX_HW_RESTARTS 5
@ -8577,10 +8577,9 @@ static void iwl_pci_remove(struct pci_dev *pdev)
IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
mutex_lock(&priv->mutex);
set_bit(STATUS_EXIT_PENDING, &priv->status);
__iwl_down(priv);
mutex_unlock(&priv->mutex);
iwl_down(priv);
/* Free MAC hash list for ADHOC */
for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) {
@ -8639,12 +8638,10 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct iwl_priv *priv = pci_get_drvdata(pdev);
mutex_lock(&priv->mutex);
set_bit(STATUS_IN_SUSPEND, &priv->status);
/* Take down the device; powers it off, etc. */
__iwl_down(priv);
iwl_down(priv);
if (priv->mac80211_registered)
ieee80211_stop_queues(priv->hw);
@ -8653,8 +8650,6 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
mutex_unlock(&priv->mutex);
return 0;
}
@ -8712,8 +8707,6 @@ static int iwl_pci_resume(struct pci_dev *pdev)
printk(KERN_INFO "Coming out of suspend...\n");
mutex_lock(&priv->mutex);
pci_set_power_state(pdev, PCI_D0);
err = pci_enable_device(pdev);
pci_restore_state(pdev);
@ -8727,7 +8720,6 @@ static int iwl_pci_resume(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x41, 0x00);
iwl_resume(priv);
mutex_unlock(&priv->mutex);
return 0;
}

View File

@ -6598,8 +6598,6 @@ static void __iwl_down(struct iwl_priv *priv)
/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
iwl_cancel_deferred_work(priv);
/* Wipe out the EXIT_PENDING status bit if we are not actually
* exiting the module */
if (!exit_pending)
@ -6674,6 +6672,8 @@ static void iwl_down(struct iwl_priv *priv)
mutex_lock(&priv->mutex);
__iwl_down(priv);
mutex_unlock(&priv->mutex);
iwl_cancel_deferred_work(priv);
}
#define MAX_HW_RESTARTS 5
@ -9171,10 +9171,9 @@ static void iwl_pci_remove(struct pci_dev *pdev)
IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
mutex_lock(&priv->mutex);
set_bit(STATUS_EXIT_PENDING, &priv->status);
__iwl_down(priv);
mutex_unlock(&priv->mutex);
iwl_down(priv);
/* Free MAC hash list for ADHOC */
for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) {
@ -9233,12 +9232,10 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct iwl_priv *priv = pci_get_drvdata(pdev);
mutex_lock(&priv->mutex);
set_bit(STATUS_IN_SUSPEND, &priv->status);
/* Take down the device; powers it off, etc. */
__iwl_down(priv);
iwl_down(priv);
if (priv->mac80211_registered)
ieee80211_stop_queues(priv->hw);
@ -9247,8 +9244,6 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
mutex_unlock(&priv->mutex);
return 0;
}
@ -9306,8 +9301,6 @@ static int iwl_pci_resume(struct pci_dev *pdev)
printk(KERN_INFO "Coming out of suspend...\n");
mutex_lock(&priv->mutex);
pci_set_power_state(pdev, PCI_D0);
err = pci_enable_device(pdev);
pci_restore_state(pdev);
@ -9321,7 +9314,6 @@ static int iwl_pci_resume(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x41, 0x00);
iwl_resume(priv);
mutex_unlock(&priv->mutex);
return 0;
}