diff options
-rw-r--r-- | drivers/ata/libata-scsi.c | 21 | ||||
-rw-r--r-- | kernel/freezer.c | 6 |
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); | |||
19 | bool pm_freezing; | 19 | bool pm_freezing; |
20 | bool pm_nosig_freezing; | 20 | bool 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 | */ | ||
26 | EXPORT_SYMBOL_GPL(pm_freezing); | ||
27 | |||
22 | /* protects freezing and frozen transitions */ | 28 | /* protects freezing and frozen transitions */ |
23 | static DEFINE_SPINLOCK(freezer_lock); | 29 | static DEFINE_SPINLOCK(freezer_lock); |
24 | 30 | ||