Commit fda19376 authored by Ming Lei's avatar Ming Lei Committed by Li Nan
Browse files

scsi: core: Move scsi_host_busy() out of host lock if it is for per-command

mainline inclusion
from mainline-v6.8-rc4
commit 4e6c9011990726f4d175e2cdfebe5b0b8cce4839
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I96GXK
CVE: CVE-2024-26627

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4e6c9011990726f4d175e2cdfebe5b0b8cce4839



--------------------------------

Commit 4373534a9850 ("scsi: core: Move scsi_host_busy() out of host lock
for waking up EH handler") intended to fix a hard lockup issue triggered by
EH. The core idea was to move scsi_host_busy() out of the host lock when
processing individual commands for EH. However, a suggested style change
inadvertently caused scsi_host_busy() to remain under the host lock. Fix
this by calling scsi_host_busy() outside the lock.

Fixes: 4373534a9850 ("scsi: core: Move scsi_host_busy() out of host lock for waking up EH handler")
Cc: Sathya Prakash Veerichetty <safhya.prakash@broadcom.com>
Cc: Bart Van Assche <bvanassche@acm.org>
Cc: Ewan D. Milne <emilne@redhat.com>
Signed-off-by: default avatarMing Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20240203024521.2006455-1-ming.lei@redhat.com


Reviewed-by: default avatarBart Van Assche <bvanassche@acm.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarLi Nan <linan122@huawei.com>
parent 8a1116c4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -282,11 +282,12 @@ static void scsi_eh_inc_host_failed(struct rcu_head *head)
{
	struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu);
	struct Scsi_Host *shost = scmd->device->host;
	unsigned int busy = scsi_host_busy(shost);
	unsigned long flags;

	spin_lock_irqsave(shost->host_lock, flags);
	shost->host_failed++;
	scsi_eh_wakeup(shost, scsi_host_busy(shost));
	scsi_eh_wakeup(shost, busy);
	spin_unlock_irqrestore(shost->host_lock, flags);
}

+3 −1
Original line number Diff line number Diff line
@@ -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_host_busy(shost));
			scsi_eh_wakeup(shost, busy);
		spin_unlock_irqrestore(shost->host_lock, flags);
	}
	rcu_read_unlock();