aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBart Van Assche <bart.vanassche@wdc.com>2018-01-05 12:19:09 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-01-09 19:10:20 -0500
commit203f8c250e2195371d418b1e8466e4caf1a0ed51 (patch)
tree4a9b736baad695ac73ebaa50e0efef6205f8f59d
parent4bf236a3330e97d275e5848420f7e31948fef07a (diff)
block, scsi: Fix race between SPI domain validation and system suspend
Avoid that the following warning is reported when suspending a system that is using the mptspi driver: WARNING: CPU: 0 PID: 4187 at drivers/scsi/scsi_lib.c:2960 scsi_device_quiesce+0x20/0xb0 EIP: scsi_device_quiesce+0x20/0xb0 Call Trace: spi_dv_device+0x65/0x5f0 [scsi_transport_spi] mptspi_dv_device+0x4d/0x170 [mptspi] mptspi_dv_renegotiate_work+0x49/0xc0 [mptspi] process_one_work+0x190/0x2e0 worker_thread+0x37/0x3f0 kthread+0xcb/0x100 ret_from_fork+0x19/0x24 Fixes: 3a0a529971ec (block, scsi: Make SCSI quiesce and resume work reliably) Reported-by: Woody Suwalski <terraluna977@gmail.com> Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com> Acked-by: Martin K. Petersen <martin.petersen@oracle.com> [ rjw : Subject ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/scsi/scsi_transport_spi.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 10ebb213ddb3..871ea582029e 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -26,6 +26,7 @@
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/sysfs.h> 27#include <linux/sysfs.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/suspend.h>
29#include <scsi/scsi.h> 30#include <scsi/scsi.h>
30#include "scsi_priv.h" 31#include "scsi_priv.h"
31#include <scsi/scsi_device.h> 32#include <scsi/scsi_device.h>
@@ -1009,11 +1010,20 @@ spi_dv_device(struct scsi_device *sdev)
1009 u8 *buffer; 1010 u8 *buffer;
1010 const int len = SPI_MAX_ECHO_BUFFER_SIZE*2; 1011 const int len = SPI_MAX_ECHO_BUFFER_SIZE*2;
1011 1012
1013 /*
1014 * Because this function and the power management code both call
1015 * scsi_device_quiesce(), it is not safe to perform domain validation
1016 * while suspend or resume is in progress. Hence the
1017 * lock/unlock_system_sleep() calls.
1018 */
1019 lock_system_sleep();
1020
1012 if (unlikely(spi_dv_in_progress(starget))) 1021 if (unlikely(spi_dv_in_progress(starget)))
1013 return; 1022 goto unlock;
1014 1023
1015 if (unlikely(scsi_device_get(sdev))) 1024 if (unlikely(scsi_device_get(sdev)))
1016 return; 1025 goto unlock;
1026
1017 spi_dv_in_progress(starget) = 1; 1027 spi_dv_in_progress(starget) = 1;
1018 1028
1019 buffer = kzalloc(len, GFP_KERNEL); 1029 buffer = kzalloc(len, GFP_KERNEL);
@@ -1049,6 +1059,8 @@ spi_dv_device(struct scsi_device *sdev)
1049 out_put: 1059 out_put:
1050 spi_dv_in_progress(starget) = 0; 1060 spi_dv_in_progress(starget) = 0;
1051 scsi_device_put(sdev); 1061 scsi_device_put(sdev);
1062unlock:
1063 unlock_system_sleep();
1052} 1064}
1053EXPORT_SYMBOL(spi_dv_device); 1065EXPORT_SYMBOL(spi_dv_device);
1054 1066