aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-scsi.c21
-rw-r--r--kernel/freezer.c6
2 files changed, 27 insertions, 0 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 4abdbdff6943..81a353590b8a 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3864,6 +3864,27 @@ void ata_scsi_hotplug(struct work_struct *work)
3864 return; 3864 return;
3865 } 3865 }
3866 3866
3867 /*
3868 * XXX - UGLY HACK
3869 *
3870 * The block layer suspend/resume path is fundamentally broken due
3871 * to freezable kthreads and workqueue and may deadlock if a block
3872 * device gets removed while resume is in progress. I don't know
3873 * what the solution is short of removing freezable kthreads and
3874 * workqueues altogether.
3875 *
3876 * The following is an ugly hack to avoid kicking off device
3877 * removal while freezer is active. This is a joke but does avoid
3878 * this particular deadlock scenario.
3879 *
3880 * https://bugzilla.kernel.org/show_bug.cgi?id=62801
3881 * http://marc.info/?l=linux-kernel&m=138695698516487
3882 */
3883#ifdef CONFIG_FREEZER
3884 while (pm_freezing)
3885 msleep(10);
3886#endif
3887
3867 DPRINTK("ENTER\n"); 3888 DPRINTK("ENTER\n");
3868 mutex_lock(&ap->scsi_scan_mutex); 3889 mutex_lock(&ap->scsi_scan_mutex);
3869 3890
diff --git a/kernel/freezer.c b/kernel/freezer.c
index c38893b0efba..78758512b1e1 100644
--- a/kernel/freezer.c
+++ b/kernel/freezer.c
@@ -19,6 +19,12 @@ EXPORT_SYMBOL(system_freezing_cnt);
19bool pm_freezing; 19bool pm_freezing;
20bool pm_nosig_freezing; 20bool pm_nosig_freezing;
21 21
22/*
23 * Temporary export for the deadlock workaround in ata_scsi_hotplug().
24 * Remove once the hack becomes unnecessary.
25 */
26EXPORT_SYMBOL_GPL(pm_freezing);
27
22/* protects freezing and frozen transitions */ 28/* protects freezing and frozen transitions */
23static DEFINE_SPINLOCK(freezer_lock); 29static DEFINE_SPINLOCK(freezer_lock);
24 30