mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:04:41 +01:00
SCSI fixes on 20260125
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). Signed-off-by: James E.J. Bottomley <James.Bottomley@HansenPartnership.com> -----BEGIN PGP SIGNATURE----- iLgEABMIAGAWIQTnYEDbdso9F2cI+arnQslM7pishQUCaXZkyRsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMSwyLDImHGphbWVzLmJvdHRvbWxleUBoYW5zZW5wYXJ0bmVy c2hpcC5jb20ACgkQ50LJTO6YrIWQoAD9GhKN9FMdjxlLtb7cuy3GJq41QnOaTJ7K ze12EznP6RgA/RODy+aKgL9+NQXOLBycfDjUzzYDzA5BTUtR2dg4Zt5E =eS8f -----END PGP SIGNATURE----- Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi Pull SCSI fixes from James Bottomley: "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)" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: qla2xxx: Sanitize payload size to prevent member overflow 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() scsi: core: Wake up the error handler when final completions race against each other scsi: storvsc: Process unsupported MODE_SENSE_10 scsi: xen: scsiback: Fix potential memory leak in scsiback_remove()
This commit is contained in:
commit
0237777974
6 changed files with 36 additions and 4 deletions
|
|
@ -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)) ?
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue