lkml.org 
[lkml]   [2022]   [Aug]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.18 0964/1095] scsi: qla2xxx: Fix crash due to stale SRB access around I/O timeouts
    Date
    From: Arun Easi <aeasi@marvell.com>

    commit c39587bc0abaf16593f7abcdf8aeec3c038c7d52 upstream.

    Ensure SRB is returned during I/O timeout error escalation. If that is not
    possible fail the escalation path.

    Following crash stack was seen:

    BUG: unable to handle kernel paging request at 0000002f56aa90f8
    IP: qla_chk_edif_rx_sa_delete_pending+0x14/0x30 [qla2xxx]
    Call Trace:
    ? qla2x00_status_entry+0x19f/0x1c50 [qla2xxx]
    ? qla2x00_start_sp+0x116/0x1170 [qla2xxx]
    ? dma_pool_alloc+0x1d6/0x210
    ? mempool_alloc+0x54/0x130
    ? qla24xx_process_response_queue+0x548/0x12b0 [qla2xxx]
    ? qla_do_work+0x2d/0x40 [qla2xxx]
    ? process_one_work+0x14c/0x390

    Link: https://lore.kernel.org/r/20220616053508.27186-6-njavali@marvell.com
    Fixes: d74595278f4a ("scsi: qla2xxx: Add multiple queue pair functionality.")
    Cc: stable@vger.kernel.org
    Signed-off-by: Arun Easi <aeasi@marvell.com>
    Signed-off-by: Nilesh Javali <njavali@marvell.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/scsi/qla2xxx/qla_os.c | 43 ++++++++++++++++++++++++++++++------------
    1 file changed, 31 insertions(+), 12 deletions(-)

    --- a/drivers/scsi/qla2xxx/qla_os.c
    +++ b/drivers/scsi/qla2xxx/qla_os.c
    @@ -1337,21 +1337,20 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
    /*
    * Returns: QLA_SUCCESS or QLA_FUNCTION_FAILED.
    */
    -int
    -qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
    - uint64_t l, enum nexus_wait_type type)
    +static int
    +__qla2x00_eh_wait_for_pending_commands(struct qla_qpair *qpair, unsigned int t,
    + uint64_t l, enum nexus_wait_type type)
    {
    int cnt, match, status;
    unsigned long flags;
    - struct qla_hw_data *ha = vha->hw;
    - struct req_que *req;
    + scsi_qla_host_t *vha = qpair->vha;
    + struct req_que *req = qpair->req;
    srb_t *sp;
    struct scsi_cmnd *cmd;

    status = QLA_SUCCESS;

    - spin_lock_irqsave(&ha->hardware_lock, flags);
    - req = vha->req;
    + spin_lock_irqsave(qpair->qp_lock_ptr, flags);
    for (cnt = 1; status == QLA_SUCCESS &&
    cnt < req->num_outstanding_cmds; cnt++) {
    sp = req->outstanding_cmds[cnt];
    @@ -1378,12 +1377,32 @@ qla2x00_eh_wait_for_pending_commands(scs
    if (!match)
    continue;

    - spin_unlock_irqrestore(&ha->hardware_lock, flags);
    + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
    status = qla2x00_eh_wait_on_command(cmd);
    - spin_lock_irqsave(&ha->hardware_lock, flags);
    + spin_lock_irqsave(qpair->qp_lock_ptr, flags);
    }
    - spin_unlock_irqrestore(&ha->hardware_lock, flags);
    + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
    +
    + return status;
    +}
    +
    +int
    +qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
    + uint64_t l, enum nexus_wait_type type)
    +{
    + struct qla_qpair *qpair;
    + struct qla_hw_data *ha = vha->hw;
    + int i, status = QLA_SUCCESS;

    + status = __qla2x00_eh_wait_for_pending_commands(ha->base_qpair, t, l,
    + type);
    + for (i = 0; status == QLA_SUCCESS && i < ha->max_qpairs; i++) {
    + qpair = ha->queue_pair_map[i];
    + if (!qpair)
    + continue;
    + status = __qla2x00_eh_wait_for_pending_commands(qpair, t, l,
    + type);
    + }
    return status;
    }

    @@ -1420,7 +1439,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd
    return err;

    if (fcport->deleted)
    - return SUCCESS;
    + return FAILED;

    ql_log(ql_log_info, vha, 0x8009,
    "DEVICE RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", vha->host_no,
    @@ -1488,7 +1507,7 @@ qla2xxx_eh_target_reset(struct scsi_cmnd
    return err;

    if (fcport->deleted)
    - return SUCCESS;
    + return FAILED;

    ql_log(ql_log_info, vha, 0x8009,
    "TARGET RESET ISSUED nexus=%ld:%d cmd=%p.\n", vha->host_no,

    \
     
     \ /
      Last update: 2022-08-16 01:11    [W:3.314 / U:0.416 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site