From b099847e11f8229b68c307bae6198f65ca556973 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Mon, 18 May 2015 10:55:01 +0530 Subject: [PATCH] mmc: host: Fix spinbug in performance sysfs nodes In CMDQ, the mmc_release_host runs in softirq context. There's a potential race condition between show/set_perf since it doesn't disable pre-emption. Change this to disable preemption. Change-Id: I20918a459e8b35ac666971b8ebf179f44aa9c40f Signed-off-by: Asutosh Das Signed-off-by: Venkat Gopalakrishnan --- drivers/mmc/core/host.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 2871f21803bd..e30261c1d9d2 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -776,9 +776,9 @@ show_perf(struct device *dev, struct device_attribute *attr, char *buf) { struct mmc_host *host = cls_dev_to_mmc_host(dev); int64_t rtime_drv, wtime_drv; - unsigned long rbytes_drv, wbytes_drv; + unsigned long rbytes_drv, wbytes_drv, flags; - spin_lock(&host->lock); + spin_lock_irqsave(&host->lock, flags); rbytes_drv = host->perf.rbytes_drv; wbytes_drv = host->perf.wbytes_drv; @@ -786,7 +786,7 @@ show_perf(struct device *dev, struct device_attribute *attr, char *buf) rtime_drv = ktime_to_us(host->perf.rtime_drv); wtime_drv = ktime_to_us(host->perf.wtime_drv); - spin_unlock(&host->lock); + spin_unlock_irqrestore(&host->lock, flags); return snprintf(buf, PAGE_SIZE, "Write performance at driver Level:" "%lu bytes in %lld microseconds\n" @@ -802,16 +802,17 @@ set_perf(struct device *dev, struct device_attribute *attr, { struct mmc_host *host = cls_dev_to_mmc_host(dev); int64_t value; + unsigned long flags; sscanf(buf, "%lld", &value); - spin_lock(&host->lock); + spin_lock_irqsave(&host->lock, flags); if (!value) { memset(&host->perf, 0, sizeof(host->perf)); host->perf_enable = false; } else { host->perf_enable = true; } - spin_unlock(&host->lock); + spin_unlock_irqrestore(&host->lock, flags); return count; }