@@ -94,6 +94,7 @@ void disk_block_events(struct gendisk *disk)
mutex_unlock(&ev->block_mutex);
}
+EXPORT_SYMBOL_GPL(disk_block_events);
static void __disk_unblock_events(struct gendisk *disk, bool check_now)
{
@@ -4064,6 +4064,7 @@ static int sd_remove(struct device *dev)
device_del(&sdkp->disk_dev);
del_gendisk(sdkp->disk);
+ sdkp->remove = 1;
if (!sdkp->suspended)
sd_shutdown(dev);
@@ -4162,6 +4163,9 @@ static void sd_shutdown(struct device *dev)
if (!sdkp)
return; /* this can happen */
+ if (sdkp->device->removable && !sdkp->remove)
+ disk_block_events(sdkp->disk);
+
if (pm_runtime_suspended(dev))
return;
@@ -156,6 +156,7 @@ struct scsi_disk {
unsigned ignore_medium_access_errors : 1;
unsigned rscs : 1; /* reduced stream control support */
unsigned use_atomic_write_boundary : 1;
+ unsigned remove : 1;
};
#define to_scsi_disk(obj) container_of(obj, struct scsi_disk, disk_dev)
@@ -879,6 +879,7 @@ int __register_blkdev(unsigned int major, const char *name,
void unregister_blkdev(unsigned int major, const char *name);
bool disk_check_media_change(struct gendisk *disk);
+void disk_block_events(struct gendisk *disk);
void set_capacity(struct gendisk *disk, sector_t size);
#ifdef CONFIG_BLOCK_HOLDER_DEPRECATED
If device shutdown is blocking for a few seconds after xhci_pci_shutdown, disk_check_events will get scheduled becase block.events_dfl_poll_msecs is set to 2000 by user space. usb-storage can get USB access error and then call usb_reset_device. Some SanDisk USB flashes, 0781:5567 and 0781:5581, are lost after reboot. This can be simulated by injecting mdelay(5000) at the end of i915_driver_shutdown. Add event block in sd_shutdown to prevent disk_check_events scheduled during the potential blocking. [ 27.324042][ T1] shutdown[1]: Rebooting. [ 27.548410][ T1] sd 1:0:0:0: [sda] Synchronizing SCSI cache [ 30.060554][ T225] usb 4-4: device not accepting address 2, error -108 [ 32.838110][ T1] ACPI: PM: Preparing to enter system sleep state S5 [ 32.851746][ T1] reboot: Restarting system [ 32.856127][ T1] reboot: machine restart Before bd738d859e71 ("drm/i915: Prevent modesets during driver init/ shutdown"), plymouthd can commit modeset during i915 shutdown process, this brings ten seconds delay. [ 36.519606][ T1] shutdown[1]: Rebooting. [ 36.763427][ T1] sd 1:0:0:0: [sda] Synchronizing SCSI cache [ 37.229513][ T7030] i915 0000:00:02.0: drm_WARN_ON(!intel_irqs_enabled(dev_priv)) ... [ 39.008748][ T4356] usb 4-4: device not accepting address 2, error -108 [ 43.116781][ T4356] usb usb4-port4: Cannot enable. Maybe the USB cable is bad? [ 47.196768][ T185] usb usb4-port4: Cannot enable. Maybe the USB cable is bad? [ 47.204511][ T185] usb 4-4: USB disconnect, device number 2 [ 48.438385][ T1] i915 0000:00:02.0: i915 raw-wakerefs=6 wakelocks=6 on cleanup Signed-off-by: Jiajia Liu <liujiajia@kylinos.cn> --- block/disk-events.c | 1 + drivers/scsi/sd.c | 4 ++++ drivers/scsi/sd.h | 1 + include/linux/blkdev.h | 1 + 4 files changed, 7 insertions(+)