diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-07 12:04:32 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-07 12:04:32 -0500 |
| commit | a817e73fe693f0718b6210f4b959478877fb2e2f (patch) | |
| tree | 377b6fd9c622f4d67448bf1c716522ebc8601140 | |
| parent | e4880bc5dfb1f02b152e62a894b5c6f3e995b3cf (diff) | |
Revert "scsi: make 'state' device attribute pollable"
This reverts commit 8a97712e5314aefe16b3ffb4583a34deaa49de04.
This commit added a call to sysfs_notify() from within
scsi_device_set_state(), which in turn turns out to make libata very
unhappy, because ata_eh_detach_dev() does
spin_lock_irqsave(ap->lock, flags);
..
if (ata_scsi_offline_dev(dev)) {
dev->flags |= ATA_DFLAG_DETACHED;
ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
}
and ata_scsi_offline_dev() then does that scsi_device_set_state() to set
it offline.
So now we called sysfs_notify() from within a spinlocked region, which
really doesn't work. The 0day robot reported this as:
BUG: sleeping function called from invalid context at kernel/locking/mutex.c:238
because sysfs_notify() ends up calling kernfs_find_and_get_ns() which
then does mutex_lock(&kernfs_mutex)..
The pollability of the device state isn't critical, so revert this all
for now, and maybe we'll do it differently in the future.
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Acked-by: Tejun Heo <tj@kernel.org>
Acked-by: Martin K. Petersen <martin.petersen@oracle.com>
Acked-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | drivers/scsi/scsi_lib.c | 3 | ||||
| -rw-r--r-- | drivers/scsi/scsi_transport_srp.c | 5 |
2 files changed, 1 insertions, 7 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ad3ea24f0885..bcc1694cebcd 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -2685,7 +2685,6 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) | |||
| 2685 | 2685 | ||
| 2686 | } | 2686 | } |
| 2687 | sdev->sdev_state = state; | 2687 | sdev->sdev_state = state; |
| 2688 | sysfs_notify(&sdev->sdev_gendev.kobj, NULL, "state"); | ||
| 2689 | return 0; | 2688 | return 0; |
| 2690 | 2689 | ||
| 2691 | illegal: | 2690 | illegal: |
| @@ -3109,7 +3108,6 @@ int scsi_internal_device_unblock_nowait(struct scsi_device *sdev, | |||
| 3109 | case SDEV_BLOCK: | 3108 | case SDEV_BLOCK: |
| 3110 | case SDEV_TRANSPORT_OFFLINE: | 3109 | case SDEV_TRANSPORT_OFFLINE: |
| 3111 | sdev->sdev_state = new_state; | 3110 | sdev->sdev_state = new_state; |
| 3112 | sysfs_notify(&sdev->sdev_gendev.kobj, NULL, "state"); | ||
| 3113 | break; | 3111 | break; |
| 3114 | case SDEV_CREATED_BLOCK: | 3112 | case SDEV_CREATED_BLOCK: |
| 3115 | if (new_state == SDEV_TRANSPORT_OFFLINE || | 3113 | if (new_state == SDEV_TRANSPORT_OFFLINE || |
| @@ -3117,7 +3115,6 @@ int scsi_internal_device_unblock_nowait(struct scsi_device *sdev, | |||
| 3117 | sdev->sdev_state = new_state; | 3115 | sdev->sdev_state = new_state; |
| 3118 | else | 3116 | else |
| 3119 | sdev->sdev_state = SDEV_CREATED; | 3117 | sdev->sdev_state = SDEV_CREATED; |
| 3120 | sysfs_notify(&sdev->sdev_gendev.kobj, NULL, "state"); | ||
| 3121 | break; | 3118 | break; |
| 3122 | case SDEV_CANCEL: | 3119 | case SDEV_CANCEL: |
| 3123 | case SDEV_OFFLINE: | 3120 | case SDEV_OFFLINE: |
diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index 4f6f01cf9968..36f6190931bc 100644 --- a/drivers/scsi/scsi_transport_srp.c +++ b/drivers/scsi/scsi_transport_srp.c | |||
| @@ -556,11 +556,8 @@ int srp_reconnect_rport(struct srp_rport *rport) | |||
| 556 | */ | 556 | */ |
| 557 | shost_for_each_device(sdev, shost) { | 557 | shost_for_each_device(sdev, shost) { |
| 558 | mutex_lock(&sdev->state_mutex); | 558 | mutex_lock(&sdev->state_mutex); |
| 559 | if (sdev->sdev_state == SDEV_OFFLINE) { | 559 | if (sdev->sdev_state == SDEV_OFFLINE) |
| 560 | sdev->sdev_state = SDEV_RUNNING; | 560 | sdev->sdev_state = SDEV_RUNNING; |
| 561 | sysfs_notify(&sdev->sdev_gendev.kobj, | ||
| 562 | NULL, "state"); | ||
| 563 | } | ||
| 564 | mutex_unlock(&sdev->state_mutex); | 561 | mutex_unlock(&sdev->state_mutex); |
| 565 | } | 562 | } |
| 566 | } else if (rport->state == SRP_RPORT_RUNNING) { | 563 | } else if (rport->state == SRP_RPORT_RUNNING) { |
