diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:39:57 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:39:57 +0000 |
commit | dc50eab76b709d68175a358d6e23a5a3890764d3 (patch) | |
tree | c754d0390db060af0213ff994f0ac310e4cfd6e9 /drivers/scsi/scsi_lib.c | |
parent | Adding debian version 6.6.15-2. (diff) | |
download | linux-dc50eab76b709d68175a358d6e23a5a3890764d3.tar.xz linux-dc50eab76b709d68175a358d6e23a5a3890764d3.zip |
Merging upstream version 6.7.7.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index c2f647a7c1..df5ac03d5d 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -278,9 +278,11 @@ static void scsi_dec_host_busy(struct Scsi_Host *shost, struct scsi_cmnd *cmd) rcu_read_lock(); __clear_bit(SCMD_STATE_INFLIGHT, &cmd->state); if (unlikely(scsi_host_in_recovery(shost))) { + unsigned int busy = scsi_host_busy(shost); + spin_lock_irqsave(shost->host_lock, flags); if (shost->host_failed || shost->host_eh_scheduled) - scsi_eh_wakeup(shost); + scsi_eh_wakeup(shost, busy); spin_unlock_irqrestore(shost->host_lock, flags); } rcu_read_unlock(); @@ -774,6 +776,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) case 0x1b: /* sanitize in progress */ case 0x1d: /* configuration in progress */ case 0x24: /* depopulation in progress */ + case 0x25: /* depopulation restore in progress */ action = ACTION_DELAYED_RETRY; break; case 0x0a: /* ALUA state transition */ @@ -1250,28 +1253,26 @@ static inline int scsi_dev_queue_ready(struct request_queue *q, int token; token = sbitmap_get(&sdev->budget_map); - if (atomic_read(&sdev->device_blocked)) { - if (token < 0) - goto out; + if (token < 0) + return -1; - if (scsi_device_busy(sdev) > 1) - goto out_dec; + if (!atomic_read(&sdev->device_blocked)) + return token; - /* - * unblock after device_blocked iterates to zero - */ - if (atomic_dec_return(&sdev->device_blocked) > 0) - goto out_dec; - SCSI_LOG_MLQUEUE(3, sdev_printk(KERN_INFO, sdev, - "unblocking device at zero depth\n")); + /* + * Only unblock if no other commands are pending and + * if device_blocked has decreased to zero + */ + if (scsi_device_busy(sdev) > 1 || + atomic_dec_return(&sdev->device_blocked) > 0) { + sbitmap_put(&sdev->budget_map, token); + return -1; } + SCSI_LOG_MLQUEUE(3, sdev_printk(KERN_INFO, sdev, + "unblocking device at zero depth\n")); + return token; -out_dec: - if (token >= 0) - sbitmap_put(&sdev->budget_map, token); -out: - return -1; } /* @@ -2299,10 +2300,10 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries, do { result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_IN, NULL, 0, timeout, 1, &exec_args); - if (sdev->removable && scsi_sense_valid(sshdr) && + if (sdev->removable && result > 0 && scsi_sense_valid(sshdr) && sshdr->sense_key == UNIT_ATTENTION) sdev->changed = 1; - } while (scsi_sense_valid(sshdr) && + } while (result > 0 && scsi_sense_valid(sshdr) && sshdr->sense_key == UNIT_ATTENTION && --retries); return result; |