[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20131109065206.511780269@linuxfoundation.org>
Date: Fri, 8 Nov 2013 22:51:38 -0800
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, Aaron Lu <aaron.lu@...el.com>,
James Bottomley <JBottomley@...allels.com>
Subject: [PATCH 3.11 32/94] SCSI: sd: call blk_pm_runtime_init before add_disk
3.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Lu <aaron.lu@...el.com>
commit 10c580e4239df5c3344ca00322eca86ab2de880b upstream.
Sujit has found a race condition that would make q->nr_pending
unbalanced, it occurs as Sujit explained:
"
sd_probe_async() ->
add_disk() ->
disk_add_event() ->
schedule(disk_events_workfn)
sd_revalidate_disk()
blk_pm_runtime_init()
return;
Let's say the disk_events_workfn() calls sd_check_events() which tries
to send test_unit_ready() and because of sd_revalidate_disk() trying to
send another commands the test_unit_ready() might be re-queued as the
tagged command queuing is disabled.
So the race condition is -
Thread 1 | Thread 2
sd_revalidate_disk() | sd_check_events()
...nr_pending = 0 as q->dev = NULL| scsi_queue_insert()
blk_runtime_pm_init() | blk_pm_requeue_request() ->
| nr_pending = -1 since
| q->dev != NULL
"
The problem is, the test_unit_ready request doesn't get counted the
first time it is queued, so the later decrement of q->nr_pending in
blk_pm_requeue_request makes it unbalanced.
Fix this by calling blk_pm_runtime_init before add_disk so that all
requests initiated there will all be counted.
Signed-off-by: Aaron Lu <aaron.lu@...el.com>
Reported-and-tested-by: Sujit Reddy Thumma <sthumma@...eaurora.org>
Signed-off-by: James Bottomley <JBottomley@...allels.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
drivers/scsi/sd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2853,6 +2853,7 @@ static void sd_probe_async(void *data, a
gd->events |= DISK_EVENT_MEDIA_CHANGE;
}
+ blk_pm_runtime_init(sdp->request_queue, dev);
add_disk(gd);
if (sdkp->capacity)
sd_dif_config_host(sdkp);
@@ -2861,7 +2862,6 @@ static void sd_probe_async(void *data, a
sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
sdp->removable ? "removable " : "");
- blk_pm_runtime_init(sdp->request_queue, dev);
scsi_autopm_put_device(sdp);
put_device(&sdkp->dev);
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists