提交 b24d22b1 编写于 作者: Z Zhu Yi 提交者: John W. Linville

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: NZhu Yi <yi.zhu@intel.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 7d2e941b
...@@ -6243,8 +6243,6 @@ static void __iwl_down(struct iwl_priv *priv) ...@@ -6243,8 +6243,6 @@ static void __iwl_down(struct iwl_priv *priv)
/* Unblock any waiting calls */ /* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue); 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 /* Wipe out the EXIT_PENDING status bit if we are not actually
* exiting the module */ * exiting the module */
if (!exit_pending) if (!exit_pending)
...@@ -6319,6 +6317,8 @@ static void iwl_down(struct iwl_priv *priv) ...@@ -6319,6 +6317,8 @@ static void iwl_down(struct iwl_priv *priv)
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
__iwl_down(priv); __iwl_down(priv);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
iwl_cancel_deferred_work(priv);
} }
#define MAX_HW_RESTARTS 5 #define MAX_HW_RESTARTS 5
...@@ -8577,10 +8577,9 @@ static void iwl_pci_remove(struct pci_dev *pdev) ...@@ -8577,10 +8577,9 @@ static void iwl_pci_remove(struct pci_dev *pdev)
IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n"); IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
mutex_lock(&priv->mutex);
set_bit(STATUS_EXIT_PENDING, &priv->status); set_bit(STATUS_EXIT_PENDING, &priv->status);
__iwl_down(priv);
mutex_unlock(&priv->mutex); iwl_down(priv);
/* Free MAC hash list for ADHOC */ /* Free MAC hash list for ADHOC */
for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) { 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) ...@@ -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); struct iwl_priv *priv = pci_get_drvdata(pdev);
mutex_lock(&priv->mutex);
set_bit(STATUS_IN_SUSPEND, &priv->status); set_bit(STATUS_IN_SUSPEND, &priv->status);
/* Take down the device; powers it off, etc. */ /* Take down the device; powers it off, etc. */
__iwl_down(priv); iwl_down(priv);
if (priv->mac80211_registered) if (priv->mac80211_registered)
ieee80211_stop_queues(priv->hw); ieee80211_stop_queues(priv->hw);
...@@ -8653,8 +8650,6 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -8653,8 +8650,6 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot); pci_set_power_state(pdev, PCI_D3hot);
mutex_unlock(&priv->mutex);
return 0; return 0;
} }
...@@ -8712,8 +8707,6 @@ static int iwl_pci_resume(struct pci_dev *pdev) ...@@ -8712,8 +8707,6 @@ static int iwl_pci_resume(struct pci_dev *pdev)
printk(KERN_INFO "Coming out of suspend...\n"); printk(KERN_INFO "Coming out of suspend...\n");
mutex_lock(&priv->mutex);
pci_set_power_state(pdev, PCI_D0); pci_set_power_state(pdev, PCI_D0);
err = pci_enable_device(pdev); err = pci_enable_device(pdev);
pci_restore_state(pdev); pci_restore_state(pdev);
...@@ -8727,7 +8720,6 @@ static int iwl_pci_resume(struct pci_dev *pdev) ...@@ -8727,7 +8720,6 @@ static int iwl_pci_resume(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x41, 0x00); pci_write_config_byte(pdev, 0x41, 0x00);
iwl_resume(priv); iwl_resume(priv);
mutex_unlock(&priv->mutex);
return 0; return 0;
} }
......
...@@ -6598,8 +6598,6 @@ static void __iwl_down(struct iwl_priv *priv) ...@@ -6598,8 +6598,6 @@ static void __iwl_down(struct iwl_priv *priv)
/* Unblock any waiting calls */ /* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue); 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 /* Wipe out the EXIT_PENDING status bit if we are not actually
* exiting the module */ * exiting the module */
if (!exit_pending) if (!exit_pending)
...@@ -6674,6 +6672,8 @@ static void iwl_down(struct iwl_priv *priv) ...@@ -6674,6 +6672,8 @@ static void iwl_down(struct iwl_priv *priv)
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
__iwl_down(priv); __iwl_down(priv);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
iwl_cancel_deferred_work(priv);
} }
#define MAX_HW_RESTARTS 5 #define MAX_HW_RESTARTS 5
...@@ -9171,10 +9171,9 @@ static void iwl_pci_remove(struct pci_dev *pdev) ...@@ -9171,10 +9171,9 @@ static void iwl_pci_remove(struct pci_dev *pdev)
IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n"); IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
mutex_lock(&priv->mutex);
set_bit(STATUS_EXIT_PENDING, &priv->status); set_bit(STATUS_EXIT_PENDING, &priv->status);
__iwl_down(priv);
mutex_unlock(&priv->mutex); iwl_down(priv);
/* Free MAC hash list for ADHOC */ /* Free MAC hash list for ADHOC */
for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) { 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) ...@@ -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); struct iwl_priv *priv = pci_get_drvdata(pdev);
mutex_lock(&priv->mutex);
set_bit(STATUS_IN_SUSPEND, &priv->status); set_bit(STATUS_IN_SUSPEND, &priv->status);
/* Take down the device; powers it off, etc. */ /* Take down the device; powers it off, etc. */
__iwl_down(priv); iwl_down(priv);
if (priv->mac80211_registered) if (priv->mac80211_registered)
ieee80211_stop_queues(priv->hw); ieee80211_stop_queues(priv->hw);
...@@ -9247,8 +9244,6 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -9247,8 +9244,6 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot); pci_set_power_state(pdev, PCI_D3hot);
mutex_unlock(&priv->mutex);
return 0; return 0;
} }
...@@ -9306,8 +9301,6 @@ static int iwl_pci_resume(struct pci_dev *pdev) ...@@ -9306,8 +9301,6 @@ static int iwl_pci_resume(struct pci_dev *pdev)
printk(KERN_INFO "Coming out of suspend...\n"); printk(KERN_INFO "Coming out of suspend...\n");
mutex_lock(&priv->mutex);
pci_set_power_state(pdev, PCI_D0); pci_set_power_state(pdev, PCI_D0);
err = pci_enable_device(pdev); err = pci_enable_device(pdev);
pci_restore_state(pdev); pci_restore_state(pdev);
...@@ -9321,7 +9314,6 @@ static int iwl_pci_resume(struct pci_dev *pdev) ...@@ -9321,7 +9314,6 @@ static int iwl_pci_resume(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x41, 0x00); pci_write_config_byte(pdev, 0x41, 0x00);
iwl_resume(priv); iwl_resume(priv);
mutex_unlock(&priv->mutex);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册