lkml.org 
[lkml]   [2020]   [Sep]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.19 036/206] scsi: pm80xx: Cleanup command when a reset times out
    Date
    From: peter chang <dpf@google.com>

    [ Upstream commit 51c1c5f6ed64c2b65a8cf89dac136273d25ca540 ]

    Added the fix so the if driver properly sent the abort it tries to remove
    it from the firmware's list of outstanding commands regardless of the abort
    status. This means that the task gets freed 'now' rather than possibly
    getting freed later when the scsi layer thinks it's leaked but still valid.

    Link: https://lore.kernel.org/r/20191114100910.6153-10-deepak.ukey@microchip.com
    Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
    Signed-off-by: peter chang <dpf@google.com>
    Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
    Signed-off-by: Viswas G <Viswas.G@microchip.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/scsi/pm8001/pm8001_sas.c | 50 +++++++++++++++++++++++---------
    1 file changed, 37 insertions(+), 13 deletions(-)

    diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
    index 5be4212312cb0..49cf2b65de223 100644
    --- a/drivers/scsi/pm8001/pm8001_sas.c
    +++ b/drivers/scsi/pm8001/pm8001_sas.c
    @@ -1184,8 +1184,8 @@ int pm8001_abort_task(struct sas_task *task)
    pm8001_ha = pm8001_find_ha_by_dev(dev);
    device_id = pm8001_dev->device_id;
    phy_id = pm8001_dev->attached_phy;
    - rc = pm8001_find_tag(task, &tag);
    - if (rc == 0) {
    + ret = pm8001_find_tag(task, &tag);
    + if (ret == 0) {
    pm8001_printk("no tag for task:%p\n", task);
    return TMF_RESP_FUNC_FAILED;
    }
    @@ -1223,26 +1223,50 @@ int pm8001_abort_task(struct sas_task *task)

    /* 2. Send Phy Control Hard Reset */
    reinit_completion(&completion);
    + phy->port_reset_status = PORT_RESET_TMO;
    phy->reset_success = false;
    phy->enable_completion = &completion;
    phy->reset_completion = &completion_reset;
    ret = PM8001_CHIP_DISP->phy_ctl_req(pm8001_ha, phy_id,
    PHY_HARD_RESET);
    - if (ret)
    - goto out;
    - PM8001_MSG_DBG(pm8001_ha,
    - pm8001_printk("Waiting for local phy ctl\n"));
    - wait_for_completion(&completion);
    - if (!phy->reset_success)
    + if (ret) {
    + phy->enable_completion = NULL;
    + phy->reset_completion = NULL;
    goto out;
    + }

    - /* 3. Wait for Port Reset complete / Port reset TMO */
    + /* In the case of the reset timeout/fail we still
    + * abort the command at the firmware. The assumption
    + * here is that the drive is off doing something so
    + * that it's not processing requests, and we want to
    + * avoid getting a completion for this and either
    + * leaking the task in libsas or losing the race and
    + * getting a double free.
    + */
    PM8001_MSG_DBG(pm8001_ha,
    + pm8001_printk("Waiting for local phy ctl\n"));
    + ret = wait_for_completion_timeout(&completion,
    + PM8001_TASK_TIMEOUT * HZ);
    + if (!ret || !phy->reset_success) {
    + phy->enable_completion = NULL;
    + phy->reset_completion = NULL;
    + } else {
    + /* 3. Wait for Port Reset complete or
    + * Port reset TMO
    + */
    + PM8001_MSG_DBG(pm8001_ha,
    pm8001_printk("Waiting for Port reset\n"));
    - wait_for_completion(&completion_reset);
    - if (phy->port_reset_status) {
    - pm8001_dev_gone_notify(dev);
    - goto out;
    + ret = wait_for_completion_timeout(
    + &completion_reset,
    + PM8001_TASK_TIMEOUT * HZ);
    + if (!ret)
    + phy->reset_completion = NULL;
    + WARN_ON(phy->port_reset_status ==
    + PORT_RESET_TMO);
    + if (phy->port_reset_status == PORT_RESET_TMO) {
    + pm8001_dev_gone_notify(dev);
    + goto out;
    + }
    }

    /*
    --
    2.25.1
    \
     
     \ /
      Last update: 2020-09-18 04:09    [W:5.111 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site