lkml.org 
[lkml]   [2021]   [Nov]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 155/279] scsi: ufs: core: Fix another task management completion race
    Date
    From: Adrian Hunter <adrian.hunter@intel.com>

    [ Upstream commit 5cb37a26355d79ab290220677b1b57d28e99a895 ]

    hba->outstanding_tasks, which is read under host_lock spinlock, tells the
    interrupt handler what task management tags are in use by the driver. The
    doorbell register bits indicate which tags are in use by the hardware. A
    doorbell bit that is 0 is because the bit has yet to be set by the driver,
    or because the task is complete. It is only possible to disambiguate the 2
    cases, if reading/writing the doorbell register is synchronized with
    reading/writing hba->outstanding_tasks.

    For that reason, reading REG_UTP_TASK_REQ_DOOR_BELL must be done under
    spinlock.

    Link: https://lore.kernel.org/r/20211108064815.569494-3-adrian.hunter@intel.com
    Fixes: f5ef336fd2e4 ("scsi: ufs: core: Fix task management completion")
    Reviewed-by: Bart Van Assche <bvanassche@acm.org>
    Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/scsi/ufs/ufshcd.c | 3 +--
    1 file changed, 1 insertion(+), 2 deletions(-)

    diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
    index 3d0da8b3fed8a..55f2e4d6f10b7 100644
    --- a/drivers/scsi/ufs/ufshcd.c
    +++ b/drivers/scsi/ufs/ufshcd.c
    @@ -6382,9 +6382,8 @@ static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba)
    irqreturn_t ret = IRQ_NONE;
    int tag;

    - pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
    -
    spin_lock_irqsave(hba->host->host_lock, flags);
    + pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
    issued = hba->outstanding_tasks & ~pending;
    for_each_set_bit(tag, &issued, hba->nutmrs) {
    struct request *req = hba->tmf_rqs[tag];
    --
    2.33.0


    \
     
     \ /
      Last update: 2021-11-24 15:10    [W:2.057 / U:0.140 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site