Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] scsi_pm: set device runtime state before parent suspended

There is a race in scsi_bus_resume_common when set device's runtime
state to active after pm_runtime_put_sync(dev->parent).

Parent device may have been suspended so pm_runtime_set_active(dev) will
fail with -EBUSY.

Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

authored by

Lin Ming and committed by
James Bottomley
33a2285d 4bdd03e6

+12 -11
+12 -11
drivers/scsi/scsi_pm.c
··· 76 76 { 77 77 int err = 0; 78 78 79 - if (scsi_is_sdev_device(dev)) { 80 - /* 81 - * Parent device may have runtime suspended as soon as 82 - * it is woken up during the system resume. 83 - * 84 - * Resume it on behalf of child. 85 - */ 86 - pm_runtime_get_sync(dev->parent); 87 - err = scsi_dev_type_resume(dev); 88 - pm_runtime_put_sync(dev->parent); 89 - } 79 + /* 80 + * Parent device may have runtime suspended as soon as 81 + * it is woken up during the system resume. 82 + * 83 + * Resume it on behalf of child. 84 + */ 85 + pm_runtime_get_sync(dev->parent); 90 86 87 + if (scsi_is_sdev_device(dev)) 88 + err = scsi_dev_type_resume(dev); 91 89 if (err == 0) { 92 90 pm_runtime_disable(dev); 93 91 pm_runtime_set_active(dev); 94 92 pm_runtime_enable(dev); 95 93 } 94 + 95 + pm_runtime_put_sync(dev->parent); 96 + 96 97 return err; 97 98 } 98 99