runtime PM usage_count during driver_probe_device()?
Subsystems (4)
Continuing on the theme of runtime PM interactions with other parts of the driver core...
In drivers/base/dd.c:driver_probe_device(), the driver core increments the usage count around ->probe():
[...] pm_runtime_get_noresume(dev); pm_runtime_barrier(dev); ret = really_probe(dev, drv); pm_runtime_put_sync(dev);
I'm not following the reason for this. On driver's I'm familar with, it's not until ->probe where pm_runtime_enable() is called. What is being protected against here?
These seem to exist since the introduction of the runtime PM core, but I can't find any explanation.
The documentation refers to the increment by the core, but not the reasons why:
If the device bus type's or driver's ->probe() or ->remove() callback runs pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts, they will fail returning -EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has finished, so the PM core uses pm_runtime_idle_sync() to invoke the subsystem-level idle callback for the device at that time.
On a side note, the bit about -EAGAIN above is not accurate with today's code. For example, __pm_runtime_suspend() returns zero when the usage count decrement is non-zero, so callers can't currently know that doing a pm_runtime_suspend() or pm_runtime_put_sync() in their ->probe() actually didn't happen.
Another curiosity is that, contrary to the above documentation, there is no usage_count increment before the bus/driver ->remove() (although there is a _get_sync/_put_sync around the sysfs_remove and notifier just before the bus/driver->remove().
Also, below is a patch for a typo in the above Documentation exerpt.
Kevin
Quoted 1 line
From
069484f8d2bb86473a271c27733e10fbfd410c2cMon Sep 17 00:00:00 2001
From: Kevin Hilman <[email protected]>
Date: Thu, 30 Jun 2011 15:07:31 -0700
Subject: [PATCH] PM: Documentation: fix typo: pm_runtime_idle_sync() doesn't exist.
Replace reference to pm_runtime_idle_sync() in the driver core with pm_runtime_put_sync() which is used in the code.
--- Documentation/power/runtime_pm.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
Documentation/power/runtime_pm.txt +1 -1
@@ -506,7 +506,7 @@ pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts, they will fail returning -EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has -finished, so the PM core uses pm_runtime_idle_sync() to invoke the +finished, so the PM core uses pm_runtime_put_sync() to invoke the subsystem-level idle callback for the device at that time. The user space can effectively disallow the driver of the device to power manage
Signature · 1 line
1.7.4
Quoted 31 lines · Kevin Hilman
Continuing on the theme of runtime PM interactions with other parts of the driver core...
In drivers/base/dd.c:driver_probe_device(), the driver core increments the usage count around ->probe():
[...] pm_runtime_get_noresume(dev); pm_runtime_barrier(dev); ret = really_probe(dev, drv); pm_runtime_put_sync(dev);I'm not following the reason for this. On driver's I'm familar with, it's not until ->probe where
pm_runtime_enable()is called. What is being protected against here?These seem to exist since the introduction of the runtime PM core, but I can't find any explanation.
The documentation refers to the increment by the core, but not the reasons why:
If the device bus type's or driver's ->probe() or ->remove() callback runs
pm_runtime_suspend()orpm_runtime_idle()or their asynchronous counterparts, they will fail returning-EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has finished, so the PM core usespm_runtime_idle_sync()to invoke the subsystem-level idle callback for the device at that time.
Quoted 5 lines
On a side note, the bit about
-EAGAINabove is not accurate with today's code. For example,__pm_runtime_suspend()returns zero when the usage count decrement is non-zero, so callers can't currently know that doing apm_runtime_suspend()orpm_runtime_put_sync()in their ->probe() actually didn't happen.
Oops, I'm not quite right here.
The doc is actually right here if the driver uses pm_runtime_suspend() or pm_runtime_idle() in ->probe(). It's only when drivers use pm_runtime_put_sync() where there wouldn't be an -EAGAIN, but that seems correct. Sorry for the noise.
I'm still confused about the usage_count increment around ->probe though.
Kevin
Quoted 37 lines
Another curiosity is that, contrary to the above documentation, there is no
usage_countincrement before the bus/driver ->remove() (although there is a _get_sync/_put_sync around thesysfs_removeand notifier just before the bus/driver->remove().Also, below is a patch for a typo in the above Documentation exerpt.
Kevin
From
069484f8d2bb86473a271c27733e10fbfd410c2cMon Sep 17 00:00:00 2001
From: Kevin Hilman <[email protected]>
Date: Thu, 30 Jun 2011 15:07:31 -0700
Subject: [PATCH] PM: Documentation: fix typo:pm_runtime_idle_sync()doesn't exist.Replace reference to
pm_runtime_idle_sync()in the driver core withpm_runtime_put_sync()which is used in the code.Signed-off-by Kevin Hilman <[email protected]>--- Documentation/power/runtime_pm.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)Documentation/power/runtime_pm.txt +1
-1@@ -506,7 +506,7 @@ pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts, they will fail returning -EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has -finished, so the PM core uses pm_runtime_idle_sync() to invoke the +finished, so the PM core uses pm_runtime_put_sync() to invoke the subsystem-level idle callback for the device at that time. The user space can effectively disallow the driver of the device to power manage
Quoted 31 lines · Kevin Hilman
Continuing on the theme of runtime PM interactions with other parts of the driver core...
In drivers/base/dd.c:driver_probe_device(), the driver core increments the usage count around ->probe():
[...] pm_runtime_get_noresume(dev); pm_runtime_barrier(dev); ret = really_probe(dev, drv); pm_runtime_put_sync(dev);I'm not following the reason for this. On driver's I'm familar with, it's not until ->probe where
pm_runtime_enable()is called. What is being protected against here?These seem to exist since the introduction of the runtime PM core, but I can't find any explanation.
The documentation refers to the increment by the core, but not the reasons why:
If the device bus type's or driver's ->probe() or ->remove() callback runs
pm_runtime_suspend()orpm_runtime_idle()or their asynchronous counterparts, they will fail returning-EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has finished, so the PM core usespm_runtime_idle_sync()to invoke the subsystem-level idle callback for the device at that time.
Quoted 5 lines
On a side note, the bit about
-EAGAINabove is not accurate with today's code. For example,__pm_runtime_suspend()returns zero when the usage count decrement is non-zero, so callers can't currently know that doing apm_runtime_suspend()orpm_runtime_put_sync()in their ->probe() actually didn't happen.
Oops, I'm not quite right here.
The doc is actually right here if the driver uses pm_runtime_suspend() or pm_runtime_idle() in ->probe(). It's only when drivers use pm_runtime_put_sync() where there wouldn't be an -EAGAIN, but that seems correct. Sorry for the noise.
I'm still confused about the usage_count increment around ->probe though.
Kevin
Quoted 37 lines
Another curiosity is that, contrary to the above documentation, there is no
usage_countincrement before the bus/driver ->remove() (although there is a _get_sync/_put_sync around thesysfs_removeand notifier just before the bus/driver->remove().Also, below is a patch for a typo in the above Documentation exerpt.
Kevin
From
069484f8d2bb86473a271c27733e10fbfd410c2cMon Sep 17 00:00:00 2001
From: Kevin Hilman <[email protected]>
Date: Thu, 30 Jun 2011 15:07:31 -0700
Subject: [PATCH] PM: Documentation: fix typo:pm_runtime_idle_sync()doesn't exist.Replace reference to
pm_runtime_idle_sync()in the driver core withpm_runtime_put_sync()which is used in the code.Signed-off-by Kevin Hilman <[email protected]>--- Documentation/power/runtime_pm.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)Documentation/power/runtime_pm.txt +1
-1@@ -506,7 +506,7 @@ pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts, they will fail returning -EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has -finished, so the PM core uses pm_runtime_idle_sync() to invoke the +finished, so the PM core uses pm_runtime_put_sync() to invoke the subsystem-level idle callback for the device at that time. The user space can effectively disallow the driver of the device to power manage
Quoted 41 lines · Kevin Hilman
Quoted 31 lines · Kevin Hilman
Continuing on the theme of runtime PM interactions with other parts of the driver core...
In drivers/base/dd.c:driver_probe_device(), the driver core increments the usage count around ->probe():
[...] pm_runtime_get_noresume(dev); pm_runtime_barrier(dev); ret = really_probe(dev, drv); pm_runtime_put_sync(dev);I'm not following the reason for this. On driver's I'm familar with, it's not until ->probe where
pm_runtime_enable()is called. What is being protected against here?These seem to exist since the introduction of the runtime PM core, but I can't find any explanation.
The documentation refers to the increment by the core, but not the reasons why:
If the device bus type's or driver's ->probe() or ->remove() callback runs
pm_runtime_suspend()orpm_runtime_idle()or their asynchronous counterparts, they will fail returning-EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has finished, so the PM core usespm_runtime_idle_sync()to invoke the subsystem-level idle callback for the device at that time.Quoted 5 lines
On a side note, the bit about
-EAGAINabove is not accurate with today's code. For example,__pm_runtime_suspend()returns zero when the usage count decrement is non-zero, so callers can't currently know that doing apm_runtime_suspend()orpm_runtime_put_sync()in their ->probe() actually didn't happen.Oops, I'm not quite right here.
Quoted 7 lines
The doc is actually right here if the driver uses
pm_runtime_suspend()orpm_runtime_idle()in ->probe(). It's only when drivers usepm_runtime_put_sync()where there wouldn't be an-EAGAIN, but that seems correct. Sorry for the noise.I'm still confused about the
usage_countincrement around ->probe though.
In theory it is possible that a subsystem (e.g. bus type) will enable runtime PM for devices without drivers and will (for example) put them into low power states until the drivers are loaded. Then, it makes sense for the core to prevent such transitions from racing with .probe().
I'm not sure if this happens in practice, though, but also I'm not sure whether or not that's used by USB. Moreover, even if that doesn't happen right now, it may start to happen at one point.
Thanks,
Rafael
Quoted 6 lines · Rafael J. Wysocki
In theory it is possible that a subsystem (e.g. bus type) will enable runtime PM for devices without drivers and will (for example) put them into low power states until the drivers are loaded. Then, it makes sense for the core to prevent such transitions from racing with .probe().
I'm not sure if this happens in practice, though,
Yeah, this is exactly what the SDIO subsystem is doing.
Quoted 6 lines · Rafael J. Wysocki
In theory it is possible that a subsystem (e.g. bus type) will enable runtime PM for devices without drivers and will (for example) put them into low power states until the drivers are loaded. Then, it makes sense for the core to prevent such transitions from racing with .probe().
I'm not sure if this happens in practice, though,
Yeah, this is exactly what the SDIO subsystem is doing.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 9 lines · Ohad Ben-Cohen
Quoted 6 lines · Rafael J. Wysocki
In theory it is possible that a subsystem (e.g. bus type) will enable runtime PM for devices without drivers and will (for example) put them into low power states until the drivers are loaded. Then, it makes sense for the core to prevent such transitions from racing with .probe().
I'm not sure if this happens in practice, though,
Yeah, this is exactly what the SDIO subsystem is doing.
Thanks, this makes sense.
Maybe runtime_pm.txt should be updated to explain this as well.
Kevin
_______________________________________________
linux-pm mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/linux-pm
Quoted 9 lines · Ohad Ben-Cohen
Quoted 6 lines · Rafael J. Wysocki
In theory it is possible that a subsystem (e.g. bus type) will enable runtime PM for devices without drivers and will (for example) put them into low power states until the drivers are loaded. Then, it makes sense for the core to prevent such transitions from racing with .probe().
I'm not sure if this happens in practice, though,
Yeah, this is exactly what the SDIO subsystem is doing.
Thanks, this makes sense.
Maybe runtime_pm.txt should be updated to explain this as well.
Kevin
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi,
Quoted 8 lines · Rafael J. Wysocki
In theory it is possible that a subsystem (e.g. bus type) will enable runtime PM for devices without drivers and will (for example) put them into low power states until the drivers are loaded. Then, it makes sense for the core to prevent such transitions from racing with .probe().
I'm not sure if this happens in practice, though, but also I'm not sure whether or not that's used by USB. Moreover, even if that doesn't happen right now, it may start to happen at one point.
It should be used by USB, for example, uvcvideo driver has enabled auto suspend already:
- rmmod uvcvideo
- usb video class device auto suspended
- modprobe uvcvideo #driver_probe_device()
thanks,
Signature · 5 lines
Ming Lei -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi,
Quoted 8 lines · Rafael J. Wysocki
In theory it is possible that a subsystem (e.g. bus type) will enable runtime PM for devices without drivers and will (for example) put them into low power states until the drivers are loaded. Then, it makes sense for the core to prevent such transitions from racing with .probe().
I'm not sure if this happens in practice, though, but also I'm not sure whether or not that's used by USB. Moreover, even if that doesn't happen right now, it may start to happen at one point.
It should be used by USB, for example, uvcvideo driver has enabled auto suspend already:
- rmmod uvcvideo
- usb video class device auto suspended
- modprobe uvcvideo #driver_probe_device()
thanks,
Signature · 1 line
Ming Lei
Quoted 41 lines · Kevin Hilman
Quoted 31 lines · Kevin Hilman
Continuing on the theme of runtime PM interactions with other parts of the driver core...
In drivers/base/dd.c:driver_probe_device(), the driver core increments the usage count around ->probe():
[...] pm_runtime_get_noresume(dev); pm_runtime_barrier(dev); ret = really_probe(dev, drv); pm_runtime_put_sync(dev);I'm not following the reason for this. On driver's I'm familar with, it's not until ->probe where
pm_runtime_enable()is called. What is being protected against here?These seem to exist since the introduction of the runtime PM core, but I can't find any explanation.
The documentation refers to the increment by the core, but not the reasons why:
If the device bus type's or driver's ->probe() or ->remove() callback runs
pm_runtime_suspend()orpm_runtime_idle()or their asynchronous counterparts, they will fail returning-EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has finished, so the PM core usespm_runtime_idle_sync()to invoke the subsystem-level idle callback for the device at that time.Quoted 5 lines
On a side note, the bit about
-EAGAINabove is not accurate with today's code. For example,__pm_runtime_suspend()returns zero when the usage count decrement is non-zero, so callers can't currently know that doing apm_runtime_suspend()orpm_runtime_put_sync()in their ->probe() actually didn't happen.Oops, I'm not quite right here.
Quoted 7 lines
The doc is actually right here if the driver uses
pm_runtime_suspend()orpm_runtime_idle()in ->probe(). It's only when drivers usepm_runtime_put_sync()where there wouldn't be an-EAGAIN, but that seems correct. Sorry for the noise.I'm still confused about the
usage_countincrement around ->probe though.
In theory it is possible that a subsystem (e.g. bus type) will enable runtime PM for devices without drivers and will (for example) put them into low power states until the drivers are loaded. Then, it makes sense for the core to prevent such transitions from racing with .probe().
I'm not sure if this happens in practice, though, but also I'm not sure whether or not that's used by USB. Moreover, even if that doesn't happen right now, it may start to happen at one point.
Thanks,
Rafael
Quoted 2 lines · Kevin Hilman
I'm still confused about the
usage_countincrement around ->probe though.
As a few people have already pointed out, some subsystems do perform runtime PM on driverless devices.
The basic idea is simple: We don't want any PM callbacks to race with each other or with other driver-core callbacks. Incrementing the usage_count prevents runtime_suspend callbacks while the probe callback is running.
This does leave open the possibility of runtime_resume occurring concurrently with probe. For the most part this should be okay because without a driver, no part of the kernel will try to resume the device.
Hmmm, but a resume could occur as a result of userspace writing to a sysfs attribute. It looks like we need to add some lock_device() calls to control_store() and autosuspend_delay_ms_store().
Alan Stern
Quoted 2 lines · Kevin Hilman
I'm still confused about the
usage_countincrement around ->probe though.
As a few people have already pointed out, some subsystems do perform runtime PM on driverless devices.
The basic idea is simple: We don't want any PM callbacks to race with each other or with other driver-core callbacks. Incrementing the usage_count prevents runtime_suspend callbacks while the probe callback is running.
This does leave open the possibility of runtime_resume occurring concurrently with probe. For the most part this should be okay because without a driver, no part of the kernel will try to resume the device.
Hmmm, but a resume could occur as a result of userspace writing to a sysfs attribute. It looks like we need to add some lock_device() calls to control_store() and autosuspend_delay_ms_store().
Alan Stern
PATCH 1/1 PM: prevent runtime_resume from racing with probe
This patch (as1475) adds device_lock() and device_unlock() calls to the store methods for the power/control and power/autosuspend_delay_ms sysfs attribute files. We don't want badly timed writes to these files to cause runtime_resume callbacks to occur while a driver is being probed for a device.
---
drivers/base/power/sysfs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/base/power/sysfs.c +5 -1
@@ -116,12 +116,14 @@ static ssize_t control_store(struct devi cp =memchr (buf,'\n' , n);if (cp) len = cp - buf; +device_lock (dev);if (len ==sizeof ctrl_auto -1 &&strncmp (buf, ctrl_auto, len) ==0 )pm_runtime_allow (dev);else if (len ==sizeof ctrl_on -1 &&strncmp (buf, ctrl_on, len) ==0 )pm_runtime_forbid (dev);else -return -EINVAL ; + n = -EINVAL ; +device_unlock (dev);return n; }
@@ -205,7 +207,9 @@ static ssize_t autosuspend_delay_ms_storif (strict_strtol (buf,10 , &delay) !=0 || delay != (int ) delay)return -EINVAL ; +device_lock (dev);pm_runtime_set_autosuspend_delay (dev, delay); +device_unlock (dev);return n; }
Rafael J. Wysocki
AppliedRe: [PATCH] PM: prevent runtime_resume from racing with probe
Quoted 7 lines · Alan Stern
This patch (as1475) adds
device_lock()anddevice_unlock()calls to the store methods for the power/control and power/autosuspend_delay_ms sysfs attribute files. We don't want badly timed writes to these files to causeruntime_resumecallbacks to occur while a driver is being probed for a device.Signed-off-by Alan Stern <[email protected]>
Applied to suspend-2.6/linux-next.
Thanks,
Rafael
Quoted 38 lines
---
drivers/base/power/sysfs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)Index:
usb-3.0/drivers/base/power/sysfs.c
===================================================================drivers/base/power/sysfs.c +5
-1@@ -116,12 +116,14 @@ static ssize_t control_store(struct devi cp =memchr (buf,'\n' , n);if (cp) len = cp - buf; +device_lock (dev);if (len ==sizeof ctrl_auto -1 &&strncmp (buf, ctrl_auto, len) ==0 )pm_runtime_allow (dev);else if (len ==sizeof ctrl_on -1 &&strncmp (buf, ctrl_on, len) ==0 )pm_runtime_forbid (dev);else -return -EINVAL ; + n = -EINVAL ; +device_unlock (dev);return n; }@@ -205,7 +207,9 @@ static ssize_t autosuspend_delay_ms_storif (strict_strtol (buf,10 , &delay) !=0 || delay != (int ) delay)return -EINVAL ; +device_lock (dev);pm_runtime_set_autosuspend_delay (dev, delay); +device_unlock (dev);return n; }
Quoted 4 lines · Kevin Hilman
Another curiosity is that, contrary to the above documentation, there is no
usage_countincrement before the bus/driver ->remove() (although there is a _get_sync/_put_sync around thesysfs_removeand notifier just before the bus/driver->remove().
I hadn't noticed that. There may be a reason for using get_sync instead of get_noresume, but it isn't explained anywhere. And it certainly looks like a mistake for the put_sync to occur before the ->remove() call instead of after.
This needs to be fixed.
Alan Stern
Quoted 4 lines · Kevin Hilman
Another curiosity is that, contrary to the above documentation, there is no
usage_countincrement before the bus/driver ->remove() (although there is a _get_sync/_put_sync around thesysfs_removeand notifier just before the bus/driver->remove().
I hadn't noticed that. There may be a reason for using get_sync instead of get_noresume, but it isn't explained anywhere. And it certainly looks like a mistake for the put_sync to occur before the ->remove() call instead of after.
This needs to be fixed.
Alan Stern
Kevin Hilman <[email protected]> writes:
[...]
Quoted 8 lines
If the device bus type's or driver's ->probe() or ->remove() callback runs
pm_runtime_suspend()orpm_runtime_idle()or their asynchronous counterparts, they will fail returning-EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has finished, so the PM core usespm_runtime_idle_sync()to invoke the subsystem-level idle callback for the device at that time.
[...]
Quoted 4 lines
Another curiosity is that, contrary to the above documentation, there is no
usage_countincrement before the bus/driver ->remove() (although there is a _get_sync/_put_sync around thesysfs_removeand notifier just before the bus/driver->remove().
OK, so the ->probe() part has been explained and makes sense, but I would expect ->remove() to be similarily protected (as the documentation states.) But that is not the case. Is that a bug? If so, patch below makes the code match the documentation.
Kevin
Quoted 1 line
From
eef73ab2feb203bacb57dc35862f2a9969b61593Mon Sep 17 00:00:00 2001
From: Kevin Hilman <[email protected]>
Date: Fri, 1 Jul 2011 07:37:47 -0700
Subject: [PATCH] driver core: prevent runtime PM races with ->remove()
Runtime PM Documentation states that the runtime PM usage count is incremented during driver ->probe() and ->remove(). This is designed to prevent driver runtime PM races with subsystems which may initiate runtime PM transitions before during and after drivers are loaded.
Current code increments the usage_count during ->probe() but not during ->remove(). This patch fixes the ->remove() part and makes the code match the documentation.
--- drivers/base/dd.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/base/dd.c +3 -3
@@ -329,13 +329,13 @@ static void __device_release_driver(struct device *dev)blocking_notifier_call_chain (&dev->bus->p->bus_notifier,BUS_NOTIFY_UNBIND_DRIVER , dev); - -pm_runtime_put_sync (dev); -if (dev->bus && dev->bus->remove) dev->bus->remove (dev);else if (drv->remove) drv->remove (dev); + +pm_runtime_put_sync (dev); +devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);
Signature · 1 line
1.7.4
Kevin Hilman <[email protected]> writes:
[...]
Quoted 8 lines
If the device bus type's or driver's ->probe() or ->remove() callback runs
pm_runtime_suspend()orpm_runtime_idle()or their asynchronous counterparts, they will fail returning-EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has finished, so the PM core usespm_runtime_idle_sync()to invoke the subsystem-level idle callback for the device at that time.
[...]
Quoted 4 lines
Another curiosity is that, contrary to the above documentation, there is no
usage_countincrement before the bus/driver ->remove() (although there is a _get_sync/_put_sync around thesysfs_removeand notifier just before the bus/driver->remove().
OK, so the ->probe() part has been explained and makes sense, but I would expect ->remove() to be similarily protected (as the documentation states.) But that is not the case. Is that a bug? If so, patch below makes the code match the documentation.
Kevin
Quoted 1 line
From
eef73ab2feb203bacb57dc35862f2a9969b61593Mon Sep 17 00:00:00 2001
From: Kevin Hilman <[email protected]>
Date: Fri, 1 Jul 2011 07:37:47 -0700
Subject: [PATCH] driver core: prevent runtime PM races with ->remove()
Runtime PM Documentation states that the runtime PM usage count is incremented during driver ->probe() and ->remove(). This is designed to prevent driver runtime PM races with subsystems which may initiate runtime PM transitions before during and after drivers are loaded.
Current code increments the usage_count during ->probe() but not during ->remove(). This patch fixes the ->remove() part and makes the code match the documentation.
--- drivers/base/dd.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/base/dd.c +3 -3
@@ -329,13 +329,13 @@ static void __device_release_driver(struct device *dev)blocking_notifier_call_chain (&dev->bus->p->bus_notifier,BUS_NOTIFY_UNBIND_DRIVER , dev); - -pm_runtime_put_sync (dev); -if (dev->bus && dev->bus->remove) dev->bus->remove (dev);else if (drv->remove) drv->remove (dev); + +pm_runtime_put_sync (dev); +devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);
Signature · 1 line
1.7.4
Quoted 4 lines · Kevin Hilman
OK, so the ->probe() part has been explained and makes sense, but I would expect ->remove() to be similarily protected (as the documentation states.) But that is not the case. Is that a bug? If so, patch below makes the code match the documentation.
I suspect it is a bug, but it's hard to be sure. It's so _blatantly_ wrong that it looks like it was done deliberately.
Quoted 32 lines
Kevin
From
eef73ab2feb203bacb57dc35862f2a9969b61593Mon Sep 17 00:00:00 2001
From: Kevin Hilman <[email protected]>
Date: Fri, 1 Jul 2011 07:37:47 -0700
Subject: [PATCH] driver core: prevent runtime PM races with ->remove()Runtime PM Documentation states that the runtime PM usage count is incremented during driver ->probe() and ->remove(). This is designed to prevent driver runtime PM races with subsystems which may initiate runtime PM transitions before during and after drivers are loaded.
Current code increments the
usage_countduring ->probe() but not during ->remove(). This patch fixes the ->remove() part and makes the code match the documentation.Signed-off-by Kevin Hilman <[email protected]>--- drivers/base/dd.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)drivers/base/dd.c +0
-3@@ -329,13 +329,13 @@ static void __device_release_driver(struct device *dev)blocking_notifier_call_chain (&dev->bus->p->bus_notifier,BUS_NOTIFY_UNBIND_DRIVER , dev); - -pm_runtime_put_sync (dev); -
drivers/base/dd.c static void __device_release_driver(struct device *dev) · line 341
Quoted 10 lines
drivers/base/dd.c +3
-0if (dev->bus && dev->bus->remove) dev->bus->remove (dev);else if (drv->remove) drv->remove (dev); + +pm_runtime_put_sync (dev); +devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);
To be safer, the put_sync() call should be moved down here. Or maybe even after the blocking_notifier_call_chain() that occurs here.
Alan Stern
Quoted 4 lines · Kevin Hilman
OK, so the ->probe() part has been explained and makes sense, but I would expect ->remove() to be similarily protected (as the documentation states.) But that is not the case. Is that a bug? If so, patch below makes the code match the documentation.
I suspect it is a bug, but it's hard to be sure. It's so _blatantly_ wrong that it looks like it was done deliberately.
Quoted 32 lines
Kevin
From
eef73ab2feb203bacb57dc35862f2a9969b61593Mon Sep 17 00:00:00 2001
From: Kevin Hilman <[email protected]>
Date: Fri, 1 Jul 2011 07:37:47 -0700
Subject: [PATCH] driver core: prevent runtime PM races with ->remove()Runtime PM Documentation states that the runtime PM usage count is incremented during driver ->probe() and ->remove(). This is designed to prevent driver runtime PM races with subsystems which may initiate runtime PM transitions before during and after drivers are loaded.
Current code increments the
usage_countduring ->probe() but not during ->remove(). This patch fixes the ->remove() part and makes the code match the documentation.Signed-off-by Kevin Hilman <[email protected]>--- drivers/base/dd.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)drivers/base/dd.c +0
-3@@ -329,13 +329,13 @@ static void __device_release_driver(struct device *dev)blocking_notifier_call_chain (&dev->bus->p->bus_notifier,BUS_NOTIFY_UNBIND_DRIVER , dev); - -pm_runtime_put_sync (dev); -
drivers/base/dd.c static void __device_release_driver(struct device *dev) · line 341
Quoted 10 lines
drivers/base/dd.c +3
-0if (dev->bus && dev->bus->remove) dev->bus->remove (dev);else if (drv->remove) drv->remove (dev); + +pm_runtime_put_sync (dev); +devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);
To be safer, the put_sync() call should be moved down here. Or maybe even after the blocking_notifier_call_chain() that occurs here.
Alan Stern
Quoted 9 lines · Alan Stern
Quoted 4 lines · Kevin Hilman
OK, so the ->probe() part has been explained and makes sense, but I would expect ->remove() to be similarily protected (as the documentation states.) But that is not the case. Is that a bug? If so, patch below makes the code match the documentation.
I suspect it is a bug, but it's hard to be sure. It's so _blatantly_ wrong that it looks like it was done deliberately.
heh
Quoted 37 lines
Quoted 37 lines
Kevin
From
eef73ab2feb203bacb57dc35862f2a9969b61593Mon Sep 17 00:00:00 2001
From: Kevin Hilman <[email protected]>
Date: Fri, 1 Jul 2011 07:37:47 -0700
Subject: [PATCH] driver core: prevent runtime PM races with ->remove()Runtime PM Documentation states that the runtime PM usage count is incremented during driver ->probe() and ->remove(). This is designed to prevent driver runtime PM races with subsystems which may initiate runtime PM transitions before during and after drivers are loaded.
Current code increments the
usage_countduring ->probe() but not during ->remove(). This patch fixes the ->remove() part and makes the code match the documentation.Signed-off-by Kevin Hilman <[email protected]>--- drivers/base/dd.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)drivers/base/dd.c +1
-3@@ -329,13 +329,13 @@ static void __device_release_driver(struct device *dev)blocking_notifier_call_chain (&dev->bus->p->bus_notifier,BUS_NOTIFY_UNBIND_DRIVER , dev); - -pm_runtime_put_sync (dev); -if (dev->bus && dev->bus->remove) dev->bus->remove (dev);else if (drv->remove) drv->remove (dev); +
Quoted 8 lines
drivers/base/dd.c static void __device_release_driver(struct device *dev) · line 341
Quoted 5 lines
drivers/base/dd.c +2
-0+pm_runtime_put_sync (dev); +devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);To be safer, the
put_sync()call should be moved down here. Or maybe even after theblocking_notifier_call_chain()that occurs here.
I was actually thinking about the other direction: moving the get_sync after the first notifier chain. IOW, the get_sync/put_sync only protects the ->remove() calls, not the notifiers.
The protection around the notifiers doesn't make sense to me, at least in the context of driver runtime PM racing with the subsystem. Especially since these notifiers are likely how the subsystem/bus/pm_domain code getting notified that there may be a device to manage in the first place.
Kevin
Quoted 9 lines · Alan Stern
Quoted 4 lines · Kevin Hilman
OK, so the ->probe() part has been explained and makes sense, but I would expect ->remove() to be similarily protected (as the documentation states.) But that is not the case. Is that a bug? If so, patch below makes the code match the documentation.
I suspect it is a bug, but it's hard to be sure. It's so _blatantly_ wrong that it looks like it was done deliberately.
heh
Quoted 37 lines
Quoted 37 lines
Kevin
From
eef73ab2feb203bacb57dc35862f2a9969b61593Mon Sep 17 00:00:00 2001
From: Kevin Hilman <[email protected]>
Date: Fri, 1 Jul 2011 07:37:47 -0700
Subject: [PATCH] driver core: prevent runtime PM races with ->remove()Runtime PM Documentation states that the runtime PM usage count is incremented during driver ->probe() and ->remove(). This is designed to prevent driver runtime PM races with subsystems which may initiate runtime PM transitions before during and after drivers are loaded.
Current code increments the
usage_countduring ->probe() but not during ->remove(). This patch fixes the ->remove() part and makes the code match the documentation.Signed-off-by Kevin Hilman <[email protected]>--- drivers/base/dd.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)drivers/base/dd.c +1
-3@@ -329,13 +329,13 @@ static void __device_release_driver(struct device *dev)blocking_notifier_call_chain (&dev->bus->p->bus_notifier,BUS_NOTIFY_UNBIND_DRIVER , dev); - -pm_runtime_put_sync (dev); -if (dev->bus && dev->bus->remove) dev->bus->remove (dev);else if (drv->remove) drv->remove (dev); +
Quoted 8 lines
drivers/base/dd.c static void __device_release_driver(struct device *dev) · line 341
Quoted 5 lines
drivers/base/dd.c +2
-0+pm_runtime_put_sync (dev); +devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);To be safer, the
put_sync()call should be moved down here. Or maybe even after theblocking_notifier_call_chain()that occurs here.
I was actually thinking about the other direction: moving the get_sync after the first notifier chain. IOW, the get_sync/put_sync only protects the ->remove() calls, not the notifiers.
The protection around the notifiers doesn't make sense to me, at least in the context of driver runtime PM racing with the subsystem. Especially since these notifiers are likely how the subsystem/bus/pm_domain code getting notified that there may be a device to manage in the first place.
Kevin
Quoted 27 lines · Kevin Hilman
Quoted 14 lines
Quoted 14 lines
drivers/base/dd.c +1
-3@@ -329,13 +329,13 @@ static void __device_release_driver(struct device *dev)blocking_notifier_call_chain (&dev->bus->p->bus_notifier,BUS_NOTIFY_UNBIND_DRIVER , dev); - -pm_runtime_put_sync (dev); -if (dev->bus && dev->bus->remove) dev->bus->remove (dev);else if (drv->remove) drv->remove (dev); +Quoted 8 lines
drivers/base/dd.c static void __device_release_driver(struct device *dev) · line 341
Quoted 5 lines
drivers/base/dd.c +2
-0+pm_runtime_put_sync (dev); +devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);To be safer, the
put_sync()call should be moved down here. Or maybe even after theblocking_notifier_call_chain()that occurs here.I was actually thinking about the other direction: moving the
get_syncafter the first notifier chain. IOW, the get_sync/put_sync only protects the ->remove() calls, not the notifiers.
Quoted 5 lines
The protection around the notifiers doesn't make sense to me, at least in the context of driver runtime PM racing with the subsystem. Especially since these notifiers are likely how the subsystem/bus/pm_domain code getting notified that there may be a device to manage in the first place.
The get_sync part doesn't matter so much. Moving it past the notifier call would probably be okay -- unless one of the listeners on the notifier chain expects the device to be active. Changing the get_sync to get_noresume would probably also be okay -- subject to a similar reservation.
The problem with the put_sync isn't the notifier. If you leave it where you've got it now, you'll end up invoking a callback at a time when the driver thinks it no longer controls the device but the driver-model core still thinks it does. You certainly want to do the
dev->driver = NULL;
first.
Alan Stern
Quoted 27 lines · Kevin Hilman
Quoted 14 lines
Quoted 14 lines
drivers/base/dd.c +1
-3@@ -329,13 +329,13 @@ static void __device_release_driver(struct device *dev)blocking_notifier_call_chain (&dev->bus->p->bus_notifier,BUS_NOTIFY_UNBIND_DRIVER , dev); - -pm_runtime_put_sync (dev); -if (dev->bus && dev->bus->remove) dev->bus->remove (dev);else if (drv->remove) drv->remove (dev); +Quoted 8 lines
drivers/base/dd.c static void __device_release_driver(struct device *dev) · line 341
Quoted 5 lines
drivers/base/dd.c +2
-0+pm_runtime_put_sync (dev); +devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);To be safer, the
put_sync()call should be moved down here. Or maybe even after theblocking_notifier_call_chain()that occurs here.I was actually thinking about the other direction: moving the
get_syncafter the first notifier chain. IOW, the get_sync/put_sync only protects the ->remove() calls, not the notifiers.
Quoted 5 lines
The protection around the notifiers doesn't make sense to me, at least in the context of driver runtime PM racing with the subsystem. Especially since these notifiers are likely how the subsystem/bus/pm_domain code getting notified that there may be a device to manage in the first place.
The get_sync part doesn't matter so much. Moving it past the notifier call would probably be okay -- unless one of the listeners on the notifier chain expects the device to be active. Changing the get_sync to get_noresume would probably also be okay -- subject to a similar reservation.
The problem with the put_sync isn't the notifier. If you leave it where you've got it now, you'll end up invoking a callback at a time when the driver thinks it no longer controls the device but the driver-model core still thinks it does. You certainly want to do the
dev->driver = NULL;
first.
Alan Stern
Quoted 35 lines · Alan Stern
Quoted 27 lines · Kevin Hilman
Quoted 14 lines
Quoted 14 lines
drivers/base/dd.c +1
-3@@ -329,13 +329,13 @@ static void __device_release_driver(struct device *dev)blocking_notifier_call_chain (&dev->bus->p->bus_notifier,BUS_NOTIFY_UNBIND_DRIVER , dev); - -pm_runtime_put_sync (dev); -if (dev->bus && dev->bus->remove) dev->bus->remove (dev);else if (drv->remove) drv->remove (dev); +Quoted 8 lines
drivers/base/dd.c static void __device_release_driver(struct device *dev) · line 341
Quoted 5 lines
drivers/base/dd.c +2
-0+pm_runtime_put_sync (dev); +devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);To be safer, the
put_sync()call should be moved down here. Or maybe even after theblocking_notifier_call_chain()that occurs here.I was actually thinking about the other direction: moving the
get_syncafter the first notifier chain. IOW, the get_sync/put_sync only protects the ->remove() calls, not the notifiers.Quoted 5 lines
The protection around the notifiers doesn't make sense to me, at least in the context of driver runtime PM racing with the subsystem. Especially since these notifiers are likely how the subsystem/bus/pm_domain code getting notified that there may be a device to manage in the first place.
Quoted 5 lines
The
get_syncpart doesn't matter so much. Moving it past the notifier call would probably be okay -- unless one of the listeners on the notifier chain expects the device to be active. Changing theget_synctoget_noresumewould probably also be okay -- subject to a similar reservation.
There are enough "probably"s in the above to make me a bit uncomfortable making this change. Maybe you can take this patch forward?
Kevin
Quoted 10 lines
The problem with the
put_syncisn't the notifier. If you leave it where you've got it now, you'll end up invoking a callback at a time when the driver thinks it no longer controls the device but the driver-model core still thinks it does. You certainly want to do thedev->driver = NULL;first.
Alan Stern
Quoted 35 lines · Alan Stern
Quoted 27 lines · Kevin Hilman
Quoted 14 lines
Quoted 14 lines
drivers/base/dd.c +1
-3@@ -329,13 +329,13 @@ static void __device_release_driver(struct device *dev)blocking_notifier_call_chain (&dev->bus->p->bus_notifier,BUS_NOTIFY_UNBIND_DRIVER , dev); - -pm_runtime_put_sync (dev); -if (dev->bus && dev->bus->remove) dev->bus->remove (dev);else if (drv->remove) drv->remove (dev); +Quoted 8 lines
drivers/base/dd.c static void __device_release_driver(struct device *dev) · line 341
Quoted 5 lines
drivers/base/dd.c +2
-0+pm_runtime_put_sync (dev); +devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);To be safer, the
put_sync()call should be moved down here. Or maybe even after theblocking_notifier_call_chain()that occurs here.I was actually thinking about the other direction: moving the
get_syncafter the first notifier chain. IOW, the get_sync/put_sync only protects the ->remove() calls, not the notifiers.Quoted 5 lines
The protection around the notifiers doesn't make sense to me, at least in the context of driver runtime PM racing with the subsystem. Especially since these notifiers are likely how the subsystem/bus/pm_domain code getting notified that there may be a device to manage in the first place.
Quoted 5 lines
The
get_syncpart doesn't matter so much. Moving it past the notifier call would probably be okay -- unless one of the listeners on the notifier chain expects the device to be active. Changing theget_synctoget_noresumewould probably also be okay -- subject to a similar reservation.
There are enough "probably"s in the above to make me a bit uncomfortable making this change. Maybe you can take this patch forward?
Kevin
Quoted 10 lines
The problem with the
put_syncisn't the notifier. If you leave it where you've got it now, you'll end up invoking a callback at a time when the driver thinks it no longer controls the device but the driver-model core still thinks it does. You certainly want to do thedev->driver = NULL;first.
Alan Stern
Hi,
Quoted 9 lines · Kevin Hilman
Quoted 7 lines · Alan Stern
Quoted 4 lines · Kevin Hilman
OK, so the ->probe() part has been explained and makes sense, but I would expect ->remove() to be similarily protected (as the documentation states.) But that is not the case. Is that a bug? If so, patch below makes the code match the documentation.
Quoted 4 lines
Quoted 2 lines
I suspect it is a bug, but it's hard to be sure. It's so _blatantly_ wrong that it looks like it was done deliberately.
heh
I seem to remeber having a problem with the pm_runtime_put_sync() after drv->remove(dev) ...
So the code in question was introduced by
commit e1866b33b1e89f077b7132daae3dfd9a594e9a1a
Author: Rafael J. Wysocki <[email protected]> Date: Fri Apr 29 00:33:45 2011 +0200
PM / Runtime: Rework runtime PM handling during driver removal
with a long changelog explaining the reason why. Which seems to make sense. ;-)
So I'm not sure.
Thanks,
Rafael
Quoted 22 lines · Rafael J. Wysocki
Hi,
Quoted 9 lines · Kevin Hilman
Quoted 7 lines · Alan Stern
Quoted 4 lines · Kevin Hilman
OK, so the ->probe() part has been explained and makes sense, but I would expect ->remove() to be similarily protected (as the documentation states.) But that is not the case. Is that a bug? If so, patch below makes the code match the documentation.
Quoted 4 lines
Quoted 2 lines
I suspect it is a bug, but it's hard to be sure. It's so _blatantly_ wrong that it looks like it was done deliberately.
heh
I seem to remeber having a problem with the
pm_runtime_put_sync()afterdrv->remove(dev)...So the code in question was introduced by
Quoted 7 lines
commit
e1866b33b1e89f077b7132daae3dfd9a594e9a1aAuthor: Rafael J. Wysocki <[email protected]> Date: Fri Apr 29 00:33:45 2011 +0200PM / Runtime: Rework runtime PM handling during driver removal
with a long changelog explaining the reason why. Which seems to make sense. ;-)
Okay, that seems fair enough. Looks like the documentation needs to be updated to match, though.
And we probably still want to make sure that access to the power/control and related attribute files is mutually exclusive with probe and remove.
Alan Stern
Quoted 22 lines · Rafael J. Wysocki
Hi,
Quoted 9 lines · Kevin Hilman
Quoted 7 lines · Alan Stern
Quoted 4 lines · Kevin Hilman
OK, so the ->probe() part has been explained and makes sense, but I would expect ->remove() to be similarily protected (as the documentation states.) But that is not the case. Is that a bug? If so, patch below makes the code match the documentation.
Quoted 4 lines
Quoted 2 lines
I suspect it is a bug, but it's hard to be sure. It's so _blatantly_ wrong that it looks like it was done deliberately.
heh
I seem to remeber having a problem with the
pm_runtime_put_sync()afterdrv->remove(dev)...So the code in question was introduced by
Quoted 7 lines
commit
e1866b33b1e89f077b7132daae3dfd9a594e9a1aAuthor: Rafael J. Wysocki <[email protected]> Date: Fri Apr 29 00:33:45 2011 +0200PM / Runtime: Rework runtime PM handling during driver removal
with a long changelog explaining the reason why. Which seems to make sense. ;-)
Okay, that seems fair enough. Looks like the documentation needs to be updated to match, though.
And we probably still want to make sure that access to the power/control and related attribute files is mutually exclusive with probe and remove.
Alan Stern
Quoted 28 lines · Alan Stern
Quoted 26 lines · Rafael J. Wysocki
Hi,
Quoted 9 lines · Kevin Hilman
Quoted 7 lines · Alan Stern
Quoted 4 lines · Kevin Hilman
OK, so the ->probe() part has been explained and makes sense, but I would expect ->remove() to be similarily protected (as the documentation states.) But that is not the case. Is that a bug? If so, patch below makes the code match the documentation.
Quoted 4 lines
Quoted 2 lines
I suspect it is a bug, but it's hard to be sure. It's so _blatantly_ wrong that it looks like it was done deliberately.
heh
I seem to remeber having a problem with the
pm_runtime_put_sync()afterdrv->remove(dev)...So the code in question was introduced by
commit
e1866b33b1e89f077b7132daae3dfd9a594e9a1aAuthor: Rafael J. Wysocki <[email protected]> Date: Fri Apr 29 00:33:45 2011 +0200
Quoted 6 lines
Quoted 3 lines
PM / Runtime: Rework runtime PM handling during driver removal
with a long changelog explaining the reason why. Which seems to make sense. ;-)
Okay, that seems fair enough. Looks like the documentation needs to be updated to match, though.
Yes, it does.
Quoted 3 lines
And we probably still want to make sure that access to the power/control and related attribute files is mutually exclusive with probe and remove.
I agree.
Thanks,
Rafael
Quoted 28 lines · Alan Stern
Quoted 26 lines · Rafael J. Wysocki
Hi,
Quoted 9 lines · Kevin Hilman
Quoted 7 lines · Alan Stern
Quoted 4 lines · Kevin Hilman
OK, so the ->probe() part has been explained and makes sense, but I would expect ->remove() to be similarily protected (as the documentation states.) But that is not the case. Is that a bug? If so, patch below makes the code match the documentation.
Quoted 4 lines
Quoted 2 lines
I suspect it is a bug, but it's hard to be sure. It's so _blatantly_ wrong that it looks like it was done deliberately.
heh
I seem to remeber having a problem with the
pm_runtime_put_sync()afterdrv->remove(dev)...So the code in question was introduced by
commit
e1866b33b1e89f077b7132daae3dfd9a594e9a1aAuthor: Rafael J. Wysocki <[email protected]> Date: Fri Apr 29 00:33:45 2011 +0200
Quoted 6 lines
Quoted 3 lines
PM / Runtime: Rework runtime PM handling during driver removal
with a long changelog explaining the reason why. Which seems to make sense. ;-)
Okay, that seems fair enough. Looks like the documentation needs to be updated to match, though.
Yes, it does.
Quoted 3 lines
And we probably still want to make sure that access to the power/control and related attribute files is mutually exclusive with probe and remove.
I agree.
Thanks,
Rafael
PATCH 1/1 PM / Runtime: Update documentation regarding driver removal
In reply to Alan SternFrom: Rafael J. Wysocki <[email protected]>
Commit e1866b33b1e89f077b7132daae3dfd9a594e9a1a (PM / Runtime: Rework runtime PM handling during driver removal) forgot to update the documentation in Documentation/power/runtime_pm.txt to match the new code in drivers/base/dd.c. Update that documentation to match the code it describes.
--- Documentation/power/runtime_pm.txt | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-)
Documentation/power/runtime_pm.txt +21 -5
@@ -513,13 +513,29 @@ helper functions described in Section 4. should be used. Of course, for this purpose the device's runtime PM has to be enabled earlier by calling pm_runtime_enable(). -If the device bus type's or driver's ->probe() or ->remove() callback runs +If the device bus type's or driver's ->probe() callback runs pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts, they will fail returning -EAGAIN, because the device's usage counter is -incremented by the core before executing ->probe() and ->remove(). Still, it -may be desirable to suspend the device as soon as ->probe() or ->remove() has -finished, so the PM core uses pm_runtime_put_sync() to invoke the -subsystem-level idle callback for the device at that time. +incremented by the driver core before executing ->probe(). Still, it may be +desirable to suspend the device as soon as ->probe() has finished, so the driver +core uses pm_runtime_put_sync() to invoke the subsystem-level idle callback for +the device at that time. + +Moreover, the driver core prevents runtime PM callbacks from racing with the bus +notifier callback in __device_release_driver(), which is necessary, because the +notifier is used by some subsystems to carry out operations affecting the +runtime PM functionality. It does so by calling pm_runtime_get_sync() before +driver_sysfs_remove() and the BUS_NOTIFY_UNBIND_DRIVER notifications. This +resumes the device if it's in the suspended state and prevents it from +being suspended again while those routines are being executed. + +To allow bus types and drivers to put devices into the suspended state by +calling pm_runtime_suspend() from their ->remove() routines, the driver core +executes pm_runtime_put_sync() after running the BUS_NOTIFY_UNBIND_DRIVER +notifications in __device_release_driver(). This requires bus types and +drivers to make their ->remove() callbacks avoid races with runtime PM directly, +but also it allows of more flexibility in the handling of devices during the +removal of their drivers. The user space can effectively disallow the driver of the device to power manage it at run time by changing the value of its /sys/devices/.../power/control
Re: [PATCH] PM / Runtime: Update documentation regarding driver removal
Quoted 9 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Commit
e1866b33b1e89f077b7132daae3dfd9a594e9a1a(PM / Runtime: Rework runtime PM handling during driver removal) forgot to update the documentation inDocumentation/power/runtime_pm.txtto match the new code indrivers/base/dd.c. Update that documentation to match the code it describes.Signed-off-by Rafael J. Wysocki <[email protected]>
Thanks, it's clear now.
Kevin
Re: [PATCH] PM / Runtime: Update documentation regarding driver removal
In reply to Rafael J. WysockiQuoted 9 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Commit
e1866b33b1e89f077b7132daae3dfd9a594e9a1a(PM / Runtime: Rework runtime PM handling during driver removal) forgot to update the documentation inDocumentation/power/runtime_pm.txtto match the new code indrivers/base/dd.c. Update that documentation to match the code it describes.Signed-off-by Rafael J. Wysocki <[email protected]>
Thanks, it's clear now.
Kevin
PATCH 1/1 PM / Runtime: Update documentation regarding driver removal
In reply to Alan SternFrom: Rafael J. Wysocki <[email protected]>
Commit e1866b33b1e89f077b7132daae3dfd9a594e9a1a (PM / Runtime: Rework runtime PM handling during driver removal) forgot to update the documentation in Documentation/power/runtime_pm.txt to match the new code in drivers/base/dd.c. Update that documentation to match the code it describes.
--- Documentation/power/runtime_pm.txt | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-)
Documentation/power/runtime_pm.txt +21 -5
@@ -513,13 +513,29 @@ helper functions described in Section 4. should be used. Of course, for this purpose the device's runtime PM has to be enabled earlier by calling pm_runtime_enable(). -If the device bus type's or driver's ->probe() or ->remove() callback runs +If the device bus type's or driver's ->probe() callback runs pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts, they will fail returning -EAGAIN, because the device's usage counter is -incremented by the core before executing ->probe() and ->remove(). Still, it -may be desirable to suspend the device as soon as ->probe() or ->remove() has -finished, so the PM core uses pm_runtime_put_sync() to invoke the -subsystem-level idle callback for the device at that time. +incremented by the driver core before executing ->probe(). Still, it may be +desirable to suspend the device as soon as ->probe() has finished, so the driver +core uses pm_runtime_put_sync() to invoke the subsystem-level idle callback for +the device at that time. + +Moreover, the driver core prevents runtime PM callbacks from racing with the bus +notifier callback in __device_release_driver(), which is necessary, because the +notifier is used by some subsystems to carry out operations affecting the +runtime PM functionality. It does so by calling pm_runtime_get_sync() before +driver_sysfs_remove() and the BUS_NOTIFY_UNBIND_DRIVER notifications. This +resumes the device if it's in the suspended state and prevents it from +being suspended again while those routines are being executed. + +To allow bus types and drivers to put devices into the suspended state by +calling pm_runtime_suspend() from their ->remove() routines, the driver core +executes pm_runtime_put_sync() after running the BUS_NOTIFY_UNBIND_DRIVER +notifications in __device_release_driver(). This requires bus types and +drivers to make their ->remove() callbacks avoid races with runtime PM directly, +but also it allows of more flexibility in the handling of devices during the +removal of their drivers. The user space can effectively disallow the driver of the device to power manage it at run time by changing the value of its /sys/devices/.../power/control
Hi,
Quoted 9 lines · Kevin Hilman
Quoted 7 lines · Alan Stern
Quoted 4 lines · Kevin Hilman
OK, so the ->probe() part has been explained and makes sense, but I would expect ->remove() to be similarily protected (as the documentation states.) But that is not the case. Is that a bug? If so, patch below makes the code match the documentation.
Quoted 4 lines
Quoted 2 lines
I suspect it is a bug, but it's hard to be sure. It's so _blatantly_ wrong that it looks like it was done deliberately.
heh
I seem to remeber having a problem with the pm_runtime_put_sync() after drv->remove(dev) ...
So the code in question was introduced by
commit e1866b33b1e89f077b7132daae3dfd9a594e9a1a
Author: Rafael J. Wysocki <[email protected]> Date: Fri Apr 29 00:33:45 2011 +0200
PM / Runtime: Rework runtime PM handling during driver removal
with a long changelog explaining the reason why. Which seems to make sense. ;-)
So I'm not sure.
Thanks,
Rafael
Rafael J. Wysocki
AppliedQuoted 53 lines · Kevin Hilman
Continuing on the theme of runtime PM interactions with other parts of the driver core...
In drivers/base/dd.c:driver_probe_device(), the driver core increments the usage count around ->probe():
[...] pm_runtime_get_noresume(dev); pm_runtime_barrier(dev); ret = really_probe(dev, drv); pm_runtime_put_sync(dev);I'm not following the reason for this. On driver's I'm familar with, it's not until ->probe where
pm_runtime_enable()is called. What is being protected against here?These seem to exist since the introduction of the runtime PM core, but I can't find any explanation.
The documentation refers to the increment by the core, but not the reasons why:
If the device bus type's or driver's ->probe() or ->remove() callback runs
pm_runtime_suspend()orpm_runtime_idle()or their asynchronous counterparts, they will fail returning-EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has finished, so the PM core usespm_runtime_idle_sync()to invoke the subsystem-level idle callback for the device at that time.On a side note, the bit about
-EAGAINabove is not accurate with today's code. For example,__pm_runtime_suspend()returns zero when the usage count decrement is non-zero, so callers can't currently know that doing apm_runtime_suspend()orpm_runtime_put_sync()in their ->probe() actually didn't happen.Another curiosity is that, contrary to the above documentation, there is no
usage_countincrement before the bus/driver ->remove() (although there is a _get_sync/_put_sync around thesysfs_removeand notifier just before the bus/driver->remove().Also, below is a patch for a typo in the above Documentation exerpt.
Kevin
From
069484f8d2bb86473a271c27733e10fbfd410c2cMon Sep 17 00:00:00 2001
From: Kevin Hilman <[email protected]>
Date: Thu, 30 Jun 2011 15:07:31 -0700
Subject: [PATCH] PM: Documentation: fix typo:pm_runtime_idle_sync()doesn't exist.
Quoted 4 lines
Replace reference to
pm_runtime_idle_sync()in the driver core withpm_runtime_put_sync()which is used in the code.Signed-off-by Kevin Hilman <[email protected]>
Applied to suspend-2.6/linux-next.
Thanks,
Rafael
Quoted 18 lines
--- Documentation/power/runtime_pm.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)Documentation/power/runtime_pm.txt +1
-1@@ -506,7 +506,7 @@ pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts, they will fail returning -EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has -finished, so the PM core uses pm_runtime_idle_sync() to invoke the +finished, so the PM core uses pm_runtime_put_sync() to invoke the subsystem-level idle callback for the device at that time. The user space can effectively disallow the driver of the device to power manage
Rafael J. Wysocki
AppliedQuoted 53 lines · Kevin Hilman
Continuing on the theme of runtime PM interactions with other parts of the driver core...
In drivers/base/dd.c:driver_probe_device(), the driver core increments the usage count around ->probe():
[...] pm_runtime_get_noresume(dev); pm_runtime_barrier(dev); ret = really_probe(dev, drv); pm_runtime_put_sync(dev);I'm not following the reason for this. On driver's I'm familar with, it's not until ->probe where
pm_runtime_enable()is called. What is being protected against here?These seem to exist since the introduction of the runtime PM core, but I can't find any explanation.
The documentation refers to the increment by the core, but not the reasons why:
If the device bus type's or driver's ->probe() or ->remove() callback runs
pm_runtime_suspend()orpm_runtime_idle()or their asynchronous counterparts, they will fail returning-EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has finished, so the PM core usespm_runtime_idle_sync()to invoke the subsystem-level idle callback for the device at that time.On a side note, the bit about
-EAGAINabove is not accurate with today's code. For example,__pm_runtime_suspend()returns zero when the usage count decrement is non-zero, so callers can't currently know that doing apm_runtime_suspend()orpm_runtime_put_sync()in their ->probe() actually didn't happen.Another curiosity is that, contrary to the above documentation, there is no
usage_countincrement before the bus/driver ->remove() (although there is a _get_sync/_put_sync around thesysfs_removeand notifier just before the bus/driver->remove().Also, below is a patch for a typo in the above Documentation exerpt.
Kevin
From
069484f8d2bb86473a271c27733e10fbfd410c2cMon Sep 17 00:00:00 2001
From: Kevin Hilman <[email protected]>
Date: Thu, 30 Jun 2011 15:07:31 -0700
Subject: [PATCH] PM: Documentation: fix typo:pm_runtime_idle_sync()doesn't exist.
Quoted 4 lines
Replace reference to
pm_runtime_idle_sync()in the driver core withpm_runtime_put_sync()which is used in the code.Signed-off-by Kevin Hilman <[email protected]>
Applied to suspend-2.6/linux-next.
Thanks,
Rafael
Quoted 18 lines
--- Documentation/power/runtime_pm.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)Documentation/power/runtime_pm.txt +1
-1@@ -506,7 +506,7 @@ pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts, they will fail returning -EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has -finished, so the PM core uses pm_runtime_idle_sync() to invoke the +finished, so the PM core uses pm_runtime_put_sync() to invoke the subsystem-level idle callback for the device at that time. The user space can effectively disallow the driver of the device to power manage