drivers/scsi/qla2xxx/qla_isr.c | 7 +++++++ drivers/scsi/scsi_error.c | 11 ++++++++++- drivers/scsi/scsi_lib.c | 8 ++++++++ drivers/scsi/storvsc_drv.c | 3 ++- drivers/target/iscsi/iscsi_target_util.c | 10 ++++++++-- drivers/xen/xen-scsiback.c | 1 + 6 files changed, 36 insertions(+), 4 deletions(-)
only one core change, the rest are drivers. The core change reorders
some state operations in the error handler to try to prevent missed
wake ups of the error handler (which can halt error processing and
effectively freeze the entire system).
The patch is available here:
git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git scsi-fixes
The short changelog is:
Abdun Nihaal (1):
scsi: xen: scsiback: Fix potential memory leak in scsiback_remove()
David Jeffery (1):
scsi: core: Wake up the error handler when final completions race against each other
Jiasheng Jiang (1):
scsi: qla2xxx: Sanitize payload size to prevent member overflow
Long Li (1):
scsi: storvsc: Process unsupported MODE_SENSE_10
Maurizio Lombardi (2):
scsi: target: iscsi: Fix use-after-free in iscsit_dec_session_usage_count()
scsi: target: iscsi: Fix use-after-free in iscsit_dec_conn_usage_count()
And the diffstat:
drivers/scsi/qla2xxx/qla_isr.c | 7 +++++++
drivers/scsi/scsi_error.c | 11 ++++++++++-
drivers/scsi/scsi_lib.c | 8 ++++++++
drivers/scsi/storvsc_drv.c | 3 ++-
drivers/target/iscsi/iscsi_target_util.c | 10 ++++++++--
drivers/xen/xen-scsiback.c | 1 +
6 files changed, 36 insertions(+), 4 deletions(-)
With full diff below.
James
---
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index a3971afc2dd1..a04a5aa0d005 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -878,6 +878,9 @@ qla27xx_copy_multiple_pkt(struct scsi_qla_host *vha, void **pkt,
payload_size = sizeof(purex->els_frame_payload);
}
+ if (total_bytes > sizeof(item->iocb.iocb))
+ total_bytes = sizeof(item->iocb.iocb);
+
pending_bytes = total_bytes;
no_bytes = (pending_bytes > payload_size) ? payload_size :
pending_bytes;
@@ -1163,6 +1166,10 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt,
total_bytes = (le16_to_cpu(purex->frame_size) & 0x0FFF)
- PURX_ELS_HEADER_SIZE;
+
+ if (total_bytes > sizeof(item->iocb.iocb))
+ total_bytes = sizeof(item->iocb.iocb);
+
pending_bytes = total_bytes;
entry_count = entry_count_remaining = purex->entry_count;
no_bytes = (pending_bytes > sizeof(purex->els_frame_payload)) ?
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index eebca96c1fc1..b6e8730e049e 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -282,11 +282,20 @@ 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 int busy;
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
shost->host_failed++;
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ /*
+ * The counting of busy requests needs to occur after adding to
+ * host_failed or after the lock acquire for adding to host_failed
+ * to prevent a race with host unbusy and missing an eh wakeup.
+ */
+ busy = scsi_host_busy(shost);
+
+ spin_lock_irqsave(shost->host_lock, flags);
scsi_eh_wakeup(shost, busy);
spin_unlock_irqrestore(shost->host_lock, flags);
}
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index c7d6b76c86d2..4a902c9dfd8b 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -376,6 +376,14 @@ 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))) {
+ /*
+ * Ensure the clear of SCMD_STATE_INFLIGHT is visible to
+ * other CPUs before counting busy requests. Otherwise,
+ * reordering can cause CPUs to race and miss an eh wakeup
+ * when no CPU sees all busy requests as done or timed out.
+ */
+ smp_mb();
+
unsigned int busy = scsi_host_busy(shost);
spin_lock_irqsave(shost->host_lock, flags);
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 6e4112143c76..b43d876747b7 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1144,7 +1144,7 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device,
* The current SCSI handling on the host side does
* not correctly handle:
* INQUIRY command with page code parameter set to 0x80
- * MODE_SENSE command with cmd[2] == 0x1c
+ * MODE_SENSE and MODE_SENSE_10 command with cmd[2] == 0x1c
* MAINTENANCE_IN is not supported by HyperV FC passthrough
*
* Setup srb and scsi status so this won't be fatal.
@@ -1154,6 +1154,7 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device,
if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) ||
(stor_pkt->vm_srb.cdb[0] == MODE_SENSE) ||
+ (stor_pkt->vm_srb.cdb[0] == MODE_SENSE_10) ||
(stor_pkt->vm_srb.cdb[0] == MAINTENANCE_IN &&
hv_dev_is_fc(device))) {
vstor_packet->vm_srb.scsi_status = 0;
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index 5e6cf34929b5..c1888c42afdd 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -741,8 +741,11 @@ void iscsit_dec_session_usage_count(struct iscsit_session *sess)
spin_lock_bh(&sess->session_usage_lock);
sess->session_usage_count--;
- if (!sess->session_usage_count && sess->session_waiting_on_uc)
+ if (!sess->session_usage_count && sess->session_waiting_on_uc) {
+ spin_unlock_bh(&sess->session_usage_lock);
complete(&sess->session_waiting_on_uc_comp);
+ return;
+ }
spin_unlock_bh(&sess->session_usage_lock);
}
@@ -810,8 +813,11 @@ void iscsit_dec_conn_usage_count(struct iscsit_conn *conn)
spin_lock_bh(&conn->conn_usage_lock);
conn->conn_usage_count--;
- if (!conn->conn_usage_count && conn->conn_waiting_on_uc)
+ if (!conn->conn_usage_count && conn->conn_waiting_on_uc) {
+ spin_unlock_bh(&conn->conn_usage_lock);
complete(&conn->conn_waiting_on_uc_comp);
+ return;
+ }
spin_unlock_bh(&conn->conn_usage_lock);
}
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index 0c51edfd13dc..7d5117e5efe0 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -1262,6 +1262,7 @@ static void scsiback_remove(struct xenbus_device *dev)
gnttab_page_cache_shrink(&info->free_pages, 0);
dev_set_drvdata(&dev->dev, NULL);
+ kfree(info);
}
static int scsiback_probe(struct xenbus_device *dev,
On Sat, 24 Jan 2026 at 20:14, James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
>
> The patch is available here:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git scsi-fixes
Nothing there. Forgot to push?
Linus
On Sun, 2026-01-25 at 09:42 -0800, Linus Torvalds wrote: > On Sat, 24 Jan 2026 at 20:14, James Bottomley > <James.Bottomley@hansenpartnership.com> wrote: > > > > The patch is available here: > > > > git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git scsi- > > fixes > > Nothing there. Forgot to push? Um, no, it pushed, but the tag didn't get transferred due to signature problems with gpg because my key had expired. I know you hate expiring keys, so I've extended them all by 10 years this time (including my master key) and tidied up all the expired uids. You can either ignore the expired key warning on your end or get the updated key here gpg --auto-key-locate dane --locate-keys james.bottomley@hansenpartnership.com Sorry about that, James
On Sun, 25 Jan 2026 at 11:14, James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
>
> You can either ignore the expired key warning on your end
Done, and pulled.
> or get the updated key here
>
> gpg --auto-key-locate dane --locate-keys james.bottomley@hansenpartnership.com
Well, that does nothing. Possibly due to DNS propagation delays. I
guess I'll try again later.
Linus
On Sun, 25 Jan 2026 at 12:10, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> On Sun, 25 Jan 2026 at 11:14, James Bottomley
> <James.Bottomley@hansenpartnership.com> wrote:
> >
> > You can either ignore the expired key warning on your end
>
> Done, and pulled.
Oh, and it looks like you're not getting a pr-tracker-bot reply.
Probably because your pull request was slightly broken, and didn't
include the top commit ID. Your pull requests don't have the normal
lines like this:
for you to fetch changes up to 19bc5f2a6962dfaa0e32d0e0bc2271993d85d414:
scsi: qla2xxx: Sanitize payload size to prevent member overflow
and then presumably pr-tracker-bot had the exact same problem I had,
and couldn't fetch the actual git tree, so it just didn't know what
commits you were talking about and so doesn't react to my having
pushed out the result.
Linus
© 2016 - 2026 Red Hat, Inc.