Skip to content

Commit

Permalink
iwlwifi: fix possible priv->mutex deadlock during suspend
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Zhu Yi authored and John W. Linville committed Dec 20, 2007
1 parent 7d2e941 commit b24d22b
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 26 deletions.
18 changes: 5 additions & 13 deletions drivers/net/wireless/iwlwifi/iwl3945-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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++) {
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down
18 changes: 5 additions & 13 deletions drivers/net/wireless/iwlwifi/iwl4965-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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++) {
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down

0 comments on commit b24d22b

Please sign in to comment.