• Aaron Lu's avatar
    [SCSI] sd: call blk_pm_runtime_init before add_disk · 10c580e4
    Aaron Lu authored
    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: default avatarAaron Lu <aaron.lu@intel.com>
    Reported-and-tested-by: default avatarSujit Reddy Thumma <sthumma@codeaurora.org>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    10c580e4
sd.c 84.2 KB