Aaron Lu 10c580e423 [SCSI] sd: call blk_pm_runtime_init before add_disk
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@intel.com>
Reported-and-tested-by: Sujit Reddy Thumma <sthumma@codeaurora.org>
Cc: stable@vger.kernel.org
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
2013-10-23 14:09:18 +01:00
..
2013-07-04 12:30:30 -07:00
2013-05-28 12:02:12 +02:00
2013-04-09 14:13:27 -04:00
2013-07-13 17:41:21 -07:00
2013-08-26 12:51:30 +04:00
2013-09-15 17:41:30 -04:00
2013-09-15 17:41:30 -04:00
2013-04-09 14:13:21 -04:00
2013-09-03 15:48:06 -07:00
2013-02-22 23:31:31 -05:00
2013-02-22 23:31:31 -05:00
2013-04-09 14:13:15 -04:00
2013-04-09 14:13:22 -04:00
2013-04-09 14:13:23 -04:00
2013-04-09 14:13:24 -04:00
2013-02-27 19:10:18 -08:00
2013-04-09 14:13:24 -04:00
2013-04-09 14:13:24 -04:00
2013-04-09 14:13:17 -04:00
2013-04-09 14:13:17 -04:00
2013-04-09 14:13:17 -04:00
2013-04-09 14:13:16 -04:00
2013-04-09 14:13:16 -04:00
2013-04-09 14:13:16 -04:00
2013-04-09 14:13:16 -04:00
2013-04-09 14:13:15 -04:00
2013-09-15 17:41:30 -04:00
2013-08-26 12:51:31 +04:00
2013-04-09 14:13:16 -04:00
2013-04-09 14:13:25 -04:00
2013-04-09 14:13:27 -04:00
2013-09-03 15:48:06 -07:00
2013-04-09 14:13:17 -04:00
2013-04-09 14:13:17 -04:00
2013-04-09 14:13:15 -04:00
2013-04-09 14:13:17 -04:00
2013-04-09 14:13:17 -04:00
2013-04-09 14:13:17 -04:00
2013-04-09 14:13:17 -04:00
2013-06-18 13:48:45 +02:00
2013-04-09 14:13:17 -04:00
2013-06-26 17:56:18 -07:00
2013-05-04 14:50:16 -04:00
2013-05-04 14:50:16 -04:00
2013-05-04 14:50:16 -04:00
2013-04-09 14:13:17 -04:00
2013-04-09 14:13:17 -04:00
2013-04-09 14:13:15 -04:00
2013-04-09 14:13:15 -04:00
2013-04-09 14:13:15 -04:00