scsi: ufs: Atomic update for clkgating_enable
authorJaegeuk Kim <jaegeuk@google.com>
Tue, 17 Nov 2020 16:58:34 +0000 (08:58 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 20 Nov 2020 03:00:51 +0000 (22:00 -0500)
While running a stress test which enables/disables clkgating, we
occasionally hit device timeout. This patch avoids a subtle race condition
to address it.

Link: https://lore.kernel.org/r/20201117165839.1643377-3-jaegeuk@kernel.org
Reviewed-by: Can Guo <cang@codeaurora.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@google.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/ufs/ufshcd.c

index 9f53f63..3287402 100644 (file)
@@ -1818,19 +1818,19 @@ static ssize_t ufshcd_clkgate_enable_store(struct device *dev,
                return -EINVAL;
 
        value = !!value;
+
+       spin_lock_irqsave(hba->host->host_lock, flags);
        if (value == hba->clk_gating.is_enabled)
                goto out;
 
-       if (value) {
-               ufshcd_release(hba);
-       } else {
-               spin_lock_irqsave(hba->host->host_lock, flags);
+       if (value)
+               __ufshcd_release(hba);
+       else
                hba->clk_gating.active_reqs++;
-               spin_unlock_irqrestore(hba->host->host_lock, flags);
-       }
 
        hba->clk_gating.is_enabled = value;
 out:
+       spin_unlock_irqrestore(hba->host->host_lock, flags);
        return count;
 }