* [PATCH v3 0/3] PM: runtime: Auto-cleanup macros for runtime PM
@ 2025-09-22 15:26 Rafael J. Wysocki
2025-09-22 15:30 ` [PATCH v3 1/3] PM: runtime: Add auto-cleanup macros for "resume and get" operations Rafael J. Wysocki
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-09-22 15:26 UTC (permalink / raw)
To: Linux PM, Takashi Iwai
Cc: LKML, Linux PCI, Alex Williamson, Bjorn Helgaas, Zhang Qilong,
Ulf Hansson
Hi All,
This is an update of
https://lore.kernel.org/linux-pm/6204724.lOV4Wx5bFT@rafael.j.wysocki/
that superseded both
https://lore.kernel.org/linux-pm/5049058.31r3eYUQgx@rafael.j.wysocki/
and
https://lore.kernel.org/linux-pm/20250919163147.4743-1-tiwai@suse.de/
The only patch in this series modified since the v2 is patch [1/3]: Two
additional class definition macros have been added to cover the case in
which resume failures can be neglected, new comments have been updated
to clarify usage conditions for the new macros, and the changelog has
been updated accordingly.
Thanks!
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 1/3] PM: runtime: Add auto-cleanup macros for "resume and get" operations
2025-09-22 15:26 [PATCH v3 0/3] PM: runtime: Auto-cleanup macros for runtime PM Rafael J. Wysocki
@ 2025-09-22 15:30 ` Rafael J. Wysocki
2025-09-23 8:53 ` Dhruva Gole
2025-09-23 19:51 ` Frank Li
2025-09-22 15:31 ` [PATCH v3 2/3] PCI/sysfs: Use runtime PM class macro for auto-cleanup Rafael J. Wysocki
2025-09-22 15:33 ` [PATCH v3 3/3] PM: runtime: Drop DEFINE_FREE() for pm_runtime_put() Rafael J. Wysocki
2 siblings, 2 replies; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-09-22 15:30 UTC (permalink / raw)
To: Linux PM, Takashi Iwai
Cc: LKML, Linux PCI, Alex Williamson, Bjorn Helgaas, Zhang Qilong,
Ulf Hansson
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
It is generally useful to be able to automatically drop a device's
runtime PM usage counter incremented by runtime PM operations that
resume a device and bump up its usage counter [1].
To that end, add DEFINE_CLASS() macros allowing pm_runtime_put()
and pm_runtime_put_autosuspend() to be used for the auto-cleanup in
those cases.
Simply put, a piece of code like below:
pm_runtime_get_sync(dev);
.....
pm_runtime_put(dev);
return 0;
can be transformed with CLASS(pm_runtime_get_sync) like:
guard(pm_runtime_get_sync)(dev);
.....
return 0;
(see pm_runtime_put() call is gone).
However, it is better to do proper error handling in the majority of
cases, so doing something like this instead of the above is recommended:
CLASS(pm_runtime_get_active, pm)(dev);
if (IS_ERR(pm))
return PTR_ERR(pm);
.....
return 0;
In all of the cases in which runtime PM is known to be enabled for the
given device or the device can be regarded as operational (and so it can
be accessed) with runtime PM disabled, a piece of code like:
ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
return ret;
.....
pm_runtime_put(dev);
return 0;
can be simplified with CLASS() like:
CLASS(pm_runtime_get_active, pm)(dev);
if (IS_ERR(pm))
return PTR_ERR(pm);
.....
return 0;
(again, see pm_runtime_put() call is gone).
Still, if the device cannot be accessed unless runtime PM has been
enabled for it, the CLASS(pm_runtime_get_active_enabled) variant
needs to be used, that is (in the context of the example above):
CLASS(pm_runtime_get_active_enabled, pm)(dev);
if (IS_ERR(pm))
return PTR_ERR(pm);
.....
return 0;
When the original code calls pm_runtime_put_autosuspend(), use one
of the "auto" class variants, CLASS(pm_runtime_get_active_auto) or
CLASS(pm_runtime_get_active_enabled_auto), so for example, a piece
of code like:
ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
return ret;
.....
pm_runtime_put_autosuspend(dev);
return 0;
will become:
CLASS(pm_runtime_get_active_enabled_auto, pm)(dev);
if (IS_ERR(pm))
return PTR_ERR(pm);
.....
return 0;
Note that the cases in which the return value of pm_runtime_get_sync()
is checked can also be handled with the help of the new class macros.
For example, a piece of code like:
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
pm_runtime_put(dev);
return ret;
}
.....
pm_runtime_put(dev);
return 0;
can be rewritten as:
CLASS(pm_runtime_get_active_enabled, pm)(dev);
if (IS_ERR(pm))
return PTR_ERR(pm);
.....
return 0;
or CLASS(pm_runtime_get_active) can be used if transparent handling of
disabled runtime PM is desirable.
Link: https://lore.kernel.org/linux-pm/878qimv24u.wl-tiwai@suse.de/ [1]
Co-developed-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
v2 -> v3:
* Two more class definitions for the case in which resume errors can be
neglected.
* Update of new code comments (for more clarity).
* Changelog update.
v1 -> v2:
* Rename the new classes and the new static inline helper.
* Add two classes for handling disabled runtime PM.
* Expand the changelog.
* Adjust the subject.
---
drivers/base/power/runtime.c | 2 +
include/linux/pm_runtime.h | 82 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 84 insertions(+)
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -796,6 +796,8 @@ static int rpm_resume(struct device *dev
if (dev->power.runtime_status == RPM_ACTIVE &&
dev->power.last_status == RPM_ACTIVE)
retval = 1;
+ else if (rpmflags & RPM_TRANSPARENT)
+ goto out;
else
retval = -EACCES;
}
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -21,6 +21,7 @@
#define RPM_GET_PUT 0x04 /* Increment/decrement the
usage_count */
#define RPM_AUTO 0x08 /* Use autosuspend_delay */
+#define RPM_TRANSPARENT 0x10 /* Succeed if runtime PM is disabled */
/*
* Use this for defining a set of PM operations to be used in all situations
@@ -533,6 +534,32 @@ static inline int pm_runtime_resume_and_
}
/**
+ * pm_runtime_get_active_dev - Resume a device and bump up its usage counter.
+ * @dev: Target device.
+ * @rpmflags: Additional runtime PM flags to combine with RPM_GET_PUT.
+ *
+ * Resume @dev synchronously and if that is successful, increment its runtime
+ * PM usage counter.
+ *
+ * Return:
+ * * 0 if the runtime PM usage counter of @dev has been incremented.
+ * * Negative error code otherwise.
+ */
+static inline struct device *pm_runtime_get_active_dev(struct device *dev,
+ int rpmflags)
+{
+ int ret;
+
+ ret = __pm_runtime_resume(dev, RPM_GET_PUT | rpmflags);
+ if (ret < 0) {
+ pm_runtime_put_noidle(dev);
+ return ERR_PTR(ret);
+ }
+
+ return dev;
+}
+
+/**
* pm_runtime_put - Drop device usage counter and queue up "idle check" if 0.
* @dev: Target device.
*
@@ -606,6 +633,61 @@ static inline int pm_runtime_put_autosus
return __pm_runtime_put_autosuspend(dev);
}
+/*
+ * The way to use the classes defined below is to define a class variable and
+ * use it going forward for representing the target device until it goes out of
+ * the scope. For example:
+ *
+ * CLASS(pm_runtime_get_active, active_dev)(dev);
+ * if (IS_ERR(active_dev))
+ * return PTR_ERR(active_dev);
+ *
+ * ... do something with active_dev (which is guaranteed to never suspend) ...
+ *
+ * If an error occurs, the runtime PM usage counter of dev will not be
+ * incremented, so using these classes without error handling is not
+ * recommended.
+ */
+DEFINE_CLASS(pm_runtime_get_active, struct device *,
+ if (!IS_ERR_OR_NULL(_T)) pm_runtime_put(_T),
+ pm_runtime_get_active_dev(dev, RPM_TRANSPARENT), struct device *dev)
+
+DEFINE_CLASS(pm_runtime_get_active_auto, struct device *,
+ if (!IS_ERR_OR_NULL(_T)) pm_runtime_put_autosuspend(_T),
+ pm_runtime_get_active_dev(dev, RPM_TRANSPARENT), struct device *dev)
+
+/*
+ * The following two classes are analogous to the two classes defined above,
+ * respectively, but they produce an error pointer if runtime PM has been
+ * disabled for the given device.
+ *
+ * They should be used only when runtime PM may be disabled for the given device
+ * and if that happens, the device is not regarded as operational and so it
+ * cannot be accessed. The classes defined above should be used instead in all
+ * of the other cases.
+ */
+DEFINE_CLASS(pm_runtime_get_active_enabled, struct device *,
+ if (!IS_ERR_OR_NULL(_T)) pm_runtime_put(_T),
+ pm_runtime_get_active_dev(dev, 0), struct device *dev)
+
+DEFINE_CLASS(pm_runtime_get_active_enabled_auto, struct device *,
+ if (!IS_ERR_OR_NULL(_T)) pm_runtime_put_autosuspend(_T),
+ pm_runtime_get_active_dev(dev, 0), struct device *dev)
+
+/*
+ * The following classes may be used instead of the above if resume failures can
+ * be neglected. However, such cases are not expected to be prevalent, so using
+ * one of these classes should always be regarded as an exception and explained
+ * in an adjacent code comment.
+ */
+DEFINE_CLASS(pm_runtime_get_sync, struct device *,
+ if (_T) pm_runtime_put(_T),
+ ({ pm_runtime_get_sync(dev); dev; }), struct device *dev)
+
+DEFINE_CLASS(pm_runtime_get_sync_auto, struct device *,
+ if (_T) pm_runtime_put_autosuspend(_T),
+ ({ pm_runtime_get_sync(dev); dev; }), struct device *dev)
+
/**
* pm_runtime_put_sync - Drop device usage counter and run "idle check" if 0.
* @dev: Target device.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 2/3] PCI/sysfs: Use runtime PM class macro for auto-cleanup
2025-09-22 15:26 [PATCH v3 0/3] PM: runtime: Auto-cleanup macros for runtime PM Rafael J. Wysocki
2025-09-22 15:30 ` [PATCH v3 1/3] PM: runtime: Add auto-cleanup macros for "resume and get" operations Rafael J. Wysocki
@ 2025-09-22 15:31 ` Rafael J. Wysocki
2025-09-22 18:50 ` Bjorn Helgaas
2025-09-22 15:33 ` [PATCH v3 3/3] PM: runtime: Drop DEFINE_FREE() for pm_runtime_put() Rafael J. Wysocki
2 siblings, 1 reply; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-09-22 15:31 UTC (permalink / raw)
To: Linux PM, Takashi Iwai
Cc: LKML, Linux PCI, Alex Williamson, Bjorn Helgaas, Zhang Qilong,
Ulf Hansson
From: Takashi Iwai <tiwai@suse.de>
Use the newly introduced class macro to simplify the code.
Also, add the proper error handling for the PM runtime get errors.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20250919163147.4743-3-tiwai@suse.de
[ rjw: Adjusted the subject and the name of the class ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
v2 -> v3: No changes
v1 -> v2:
* Adjust the name of the class to handle the disabled runtime PM case
transparently (like the original code).
---
drivers/pci/pci-sysfs.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1475,8 +1475,9 @@ static ssize_t reset_method_store(struct
return count;
}
- pm_runtime_get_sync(dev);
- struct device *pmdev __free(pm_runtime_put) = dev;
+ CLASS(pm_runtime_get_active, pmdev)(dev);
+ if (IS_ERR(pmdev))
+ return -ENXIO;
if (sysfs_streq(buf, "default")) {
pci_init_reset_methods(pdev);
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 3/3] PM: runtime: Drop DEFINE_FREE() for pm_runtime_put()
2025-09-22 15:26 [PATCH v3 0/3] PM: runtime: Auto-cleanup macros for runtime PM Rafael J. Wysocki
2025-09-22 15:30 ` [PATCH v3 1/3] PM: runtime: Add auto-cleanup macros for "resume and get" operations Rafael J. Wysocki
2025-09-22 15:31 ` [PATCH v3 2/3] PCI/sysfs: Use runtime PM class macro for auto-cleanup Rafael J. Wysocki
@ 2025-09-22 15:33 ` Rafael J. Wysocki
2025-09-23 8:54 ` Dhruva Gole
2 siblings, 1 reply; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-09-22 15:33 UTC (permalink / raw)
To: Linux PM, Takashi Iwai
Cc: LKML, Linux PCI, Alex Williamson, Bjorn Helgaas, Zhang Qilong,
Ulf Hansson
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The DEFINE_FREE() for pm_runtime_put has been superseded by recently
introduced runtime PM auto-cleanup macros and its only user has been
converted to using one of the new macros, so drop it.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
v2 -> v3: No changes
v1 -> v2: No changes
---
include/linux/pm_runtime.h | 2 --
1 file changed, 2 deletions(-)
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -582,8 +582,6 @@ static inline int pm_runtime_put(struct
return __pm_runtime_idle(dev, RPM_GET_PUT | RPM_ASYNC);
}
-DEFINE_FREE(pm_runtime_put, struct device *, if (_T) pm_runtime_put(_T))
-
/**
* __pm_runtime_put_autosuspend - Drop device usage counter and queue autosuspend if 0.
* @dev: Target device.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 2/3] PCI/sysfs: Use runtime PM class macro for auto-cleanup
2025-09-22 15:31 ` [PATCH v3 2/3] PCI/sysfs: Use runtime PM class macro for auto-cleanup Rafael J. Wysocki
@ 2025-09-22 18:50 ` Bjorn Helgaas
2025-09-26 14:06 ` Jonathan Cameron
0 siblings, 1 reply; 12+ messages in thread
From: Bjorn Helgaas @ 2025-09-22 18:50 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux PM, Takashi Iwai, LKML, Linux PCI, Alex Williamson,
Zhang Qilong, Ulf Hansson
On Mon, Sep 22, 2025 at 05:31:53PM +0200, Rafael J. Wysocki wrote:
> From: Takashi Iwai <tiwai@suse.de>
>
> Use the newly introduced class macro to simplify the code.
>
> Also, add the proper error handling for the PM runtime get errors.
>
> Signed-off-by: Takashi Iwai <tiwai@suse.de>
> Link: https://patch.msgid.link/20250919163147.4743-3-tiwai@suse.de
> [ rjw: Adjusted the subject and the name of the class ]
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
> ---
>
> v2 -> v3: No changes
>
> v1 -> v2:
> * Adjust the name of the class to handle the disabled runtime PM case
> transparently (like the original code).
>
> ---
> drivers/pci/pci-sysfs.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> --- a/drivers/pci/pci-sysfs.c
> +++ b/drivers/pci/pci-sysfs.c
> @@ -1475,8 +1475,9 @@ static ssize_t reset_method_store(struct
> return count;
> }
>
> - pm_runtime_get_sync(dev);
> - struct device *pmdev __free(pm_runtime_put) = dev;
> + CLASS(pm_runtime_get_active, pmdev)(dev);
> + if (IS_ERR(pmdev))
> + return -ENXIO;
>
> if (sysfs_streq(buf, "default")) {
> pci_init_reset_methods(pdev);
>
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/3] PM: runtime: Add auto-cleanup macros for "resume and get" operations
2025-09-22 15:30 ` [PATCH v3 1/3] PM: runtime: Add auto-cleanup macros for "resume and get" operations Rafael J. Wysocki
@ 2025-09-23 8:53 ` Dhruva Gole
2025-09-23 10:43 ` Rafael J. Wysocki
2025-09-23 19:51 ` Frank Li
1 sibling, 1 reply; 12+ messages in thread
From: Dhruva Gole @ 2025-09-23 8:53 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux PM, Takashi Iwai, LKML, Linux PCI, Alex Williamson,
Bjorn Helgaas, Zhang Qilong, Ulf Hansson
On Sep 22, 2025 at 17:30:43 +0200, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> It is generally useful to be able to automatically drop a device's
> runtime PM usage counter incremented by runtime PM operations that
> resume a device and bump up its usage counter [1].
>
> To that end, add DEFINE_CLASS() macros allowing pm_runtime_put()
> and pm_runtime_put_autosuspend() to be used for the auto-cleanup in
> those cases.
>
> Simply put, a piece of code like below:
>
> pm_runtime_get_sync(dev);
> .....
> pm_runtime_put(dev);
> return 0;
>
> can be transformed with CLASS(pm_runtime_get_sync) like:
>
> guard(pm_runtime_get_sync)(dev);
> .....
> return 0;
>
> (see pm_runtime_put() call is gone).
>
> However, it is better to do proper error handling in the majority of
> cases, so doing something like this instead of the above is recommended:
>
> CLASS(pm_runtime_get_active, pm)(dev);
> if (IS_ERR(pm))
> return PTR_ERR(pm);
> .....
> return 0;
>
> In all of the cases in which runtime PM is known to be enabled for the
> given device or the device can be regarded as operational (and so it can
> be accessed) with runtime PM disabled, a piece of code like:
>
> ret = pm_runtime_resume_and_get(dev);
> if (ret < 0)
> return ret;
> .....
> pm_runtime_put(dev);
> return 0;
>
> can be simplified with CLASS() like:
>
> CLASS(pm_runtime_get_active, pm)(dev);
> if (IS_ERR(pm))
> return PTR_ERR(pm);
> .....
> return 0;
>
> (again, see pm_runtime_put() call is gone).
>
> Still, if the device cannot be accessed unless runtime PM has been
> enabled for it, the CLASS(pm_runtime_get_active_enabled) variant
> needs to be used, that is (in the context of the example above):
>
> CLASS(pm_runtime_get_active_enabled, pm)(dev);
> if (IS_ERR(pm))
> return PTR_ERR(pm);
> .....
> return 0;
>
> When the original code calls pm_runtime_put_autosuspend(), use one
> of the "auto" class variants, CLASS(pm_runtime_get_active_auto) or
> CLASS(pm_runtime_get_active_enabled_auto), so for example, a piece
> of code like:
>
> ret = pm_runtime_resume_and_get(dev);
> if (ret < 0)
> return ret;
> .....
> pm_runtime_put_autosuspend(dev);
> return 0;
>
> will become:
>
> CLASS(pm_runtime_get_active_enabled_auto, pm)(dev);
> if (IS_ERR(pm))
> return PTR_ERR(pm);
> .....
> return 0;
>
> Note that the cases in which the return value of pm_runtime_get_sync()
> is checked can also be handled with the help of the new class macros.
> For example, a piece of code like:
>
> ret = pm_runtime_get_sync(dev);
> if (ret < 0) {
> pm_runtime_put(dev);
> return ret;
> }
> .....
> pm_runtime_put(dev);
> return 0;
>
> can be rewritten as:
>
> CLASS(pm_runtime_get_active_enabled, pm)(dev);
> if (IS_ERR(pm))
> return PTR_ERR(pm);
> .....
> return 0;
>
> or CLASS(pm_runtime_get_active) can be used if transparent handling of
> disabled runtime PM is desirable.
>
Firstly, please can we add all this documentation in runtime_pm [1]
Otherwise there's just far less developers aware of the new APIs getting
introduced other than people directly involved. Not everyone is going to
come down here to look at git log for API docs (even though we proud
ourselves in having git log as our main source of Documentation in
kernel ;) )
[1] https://docs.kernel.org/power/runtime_pm.html
> Link: https://lore.kernel.org/linux-pm/878qimv24u.wl-tiwai@suse.de/ [1]
> Co-developed-by: Takashi Iwai <tiwai@suse.de>
> Signed-off-by: Takashi Iwai <tiwai@suse.de>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>
> v2 -> v3:
> * Two more class definitions for the case in which resume errors can be
> neglected.
> * Update of new code comments (for more clarity).
> * Changelog update.
>
> v1 -> v2:
> * Rename the new classes and the new static inline helper.
> * Add two classes for handling disabled runtime PM.
> * Expand the changelog.
> * Adjust the subject.
>
> ---
> drivers/base/power/runtime.c | 2 +
> include/linux/pm_runtime.h | 82 +++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 84 insertions(+)
>
> --- a/drivers/base/power/runtime.c
> +++ b/drivers/base/power/runtime.c
> @@ -796,6 +796,8 @@ static int rpm_resume(struct device *dev
> if (dev->power.runtime_status == RPM_ACTIVE &&
> dev->power.last_status == RPM_ACTIVE)
> retval = 1;
> + else if (rpmflags & RPM_TRANSPARENT)
> + goto out;
"TRANSPARENT" doesn't tell you exactly what happens. It should be something like
RPM_IGNORE_DISABLED or RPM_ALLOW_DISABLED IMO.
> else
> retval = -EACCES;
> }
> --- a/include/linux/pm_runtime.h
> +++ b/include/linux/pm_runtime.h
> @@ -21,6 +21,7 @@
> #define RPM_GET_PUT 0x04 /* Increment/decrement the
> usage_count */
> #define RPM_AUTO 0x08 /* Use autosuspend_delay */
> +#define RPM_TRANSPARENT 0x10 /* Succeed if runtime PM is disabled */
>
> /*
> * Use this for defining a set of PM operations to be used in all situations
> @@ -533,6 +534,32 @@ static inline int pm_runtime_resume_and_
> }
>
> /**
> + * pm_runtime_get_active_dev - Resume a device and bump up its usage counter.
I am getting no clue as to why this is different than regular
pm_runtime_get_sync then? Can we describe this API better?
> + * @dev: Target device.
> + * @rpmflags: Additional runtime PM flags to combine with RPM_GET_PUT.
> + *
> + * Resume @dev synchronously and if that is successful, increment its runtime
> + * PM usage counter.
> + *
> + * Return:
> + * * 0 if the runtime PM usage counter of @dev has been incremented.
> + * * Negative error code otherwise.
> + */
> +static inline struct device *pm_runtime_get_active_dev(struct device *dev,
> + int rpmflags)
> +{
> + int ret;
> +
> + ret = __pm_runtime_resume(dev, RPM_GET_PUT | rpmflags);
> + if (ret < 0) {
> + pm_runtime_put_noidle(dev);
> + return ERR_PTR(ret);
> + }
> +
> + return dev;
> +}
> +
> +/**
> * pm_runtime_put - Drop device usage counter and queue up "idle check" if 0.
> * @dev: Target device.
> *
> @@ -606,6 +633,61 @@ static inline int pm_runtime_put_autosus
> return __pm_runtime_put_autosuspend(dev);
> }
>
> +/*
> + * The way to use the classes defined below is to define a class variable and
> + * use it going forward for representing the target device until it goes out of
> + * the scope. For example:
> + *
> + * CLASS(pm_runtime_get_active, active_dev)(dev);
> + * if (IS_ERR(active_dev))
> + * return PTR_ERR(active_dev);
> + *
> + * ... do something with active_dev (which is guaranteed to never suspend) ...
> + *
> + * If an error occurs, the runtime PM usage counter of dev will not be
> + * incremented, so using these classes without error handling is not
> + * recommended.
> + */
> +DEFINE_CLASS(pm_runtime_get_active, struct device *,
> + if (!IS_ERR_OR_NULL(_T)) pm_runtime_put(_T),
> + pm_runtime_get_active_dev(dev, RPM_TRANSPARENT), struct device *dev)
> +
> +DEFINE_CLASS(pm_runtime_get_active_auto, struct device *,
> + if (!IS_ERR_OR_NULL(_T)) pm_runtime_put_autosuspend(_T),
> + pm_runtime_get_active_dev(dev, RPM_TRANSPARENT), struct device *dev)
> +
> +/*
> + * The following two classes are analogous to the two classes defined above,
> + * respectively, but they produce an error pointer if runtime PM has been
> + * disabled for the given device.
> + *
> + * They should be used only when runtime PM may be disabled for the given device
> + * and if that happens, the device is not regarded as operational and so it
> + * cannot be accessed. The classes defined above should be used instead in all
> + * of the other cases.
> + */
> +DEFINE_CLASS(pm_runtime_get_active_enabled, struct device *,
> + if (!IS_ERR_OR_NULL(_T)) pm_runtime_put(_T),
> + pm_runtime_get_active_dev(dev, 0), struct device *dev)
> +
> +DEFINE_CLASS(pm_runtime_get_active_enabled_auto, struct device *,
> + if (!IS_ERR_OR_NULL(_T)) pm_runtime_put_autosuspend(_T),
> + pm_runtime_get_active_dev(dev, 0), struct device *dev)
> +
> +/*
> + * The following classes may be used instead of the above if resume failures can
> + * be neglected. However, such cases are not expected to be prevalent, so using
> + * one of these classes should always be regarded as an exception and explained
> + * in an adjacent code comment.
> + */
> +DEFINE_CLASS(pm_runtime_get_sync, struct device *,
> + if (_T) pm_runtime_put(_T),
> + ({ pm_runtime_get_sync(dev); dev; }), struct device *dev)
> +
> +DEFINE_CLASS(pm_runtime_get_sync_auto, struct device *,
> + if (_T) pm_runtime_put_autosuspend(_T),
> + ({ pm_runtime_get_sync(dev); dev; }), struct device *dev)
> +
However overall I like the idea of introducing these auto cleanups,
probably will help drivers get into fewer troubles with RPM :)
--
Best regards,
Dhruva Gole
Texas Instruments Incorporated
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 3/3] PM: runtime: Drop DEFINE_FREE() for pm_runtime_put()
2025-09-22 15:33 ` [PATCH v3 3/3] PM: runtime: Drop DEFINE_FREE() for pm_runtime_put() Rafael J. Wysocki
@ 2025-09-23 8:54 ` Dhruva Gole
0 siblings, 0 replies; 12+ messages in thread
From: Dhruva Gole @ 2025-09-23 8:54 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux PM, Takashi Iwai, LKML, Linux PCI, Alex Williamson,
Bjorn Helgaas, Zhang Qilong, Ulf Hansson
On Sep 22, 2025 at 17:33:07 +0200, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> The DEFINE_FREE() for pm_runtime_put has been superseded by recently
> introduced runtime PM auto-cleanup macros and its only user has been
> converted to using one of the new macros, so drop it.
>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>
> v2 -> v3: No changes
>
> v1 -> v2: No changes
>
> ---
> include/linux/pm_runtime.h | 2 --
> 1 file changed, 2 deletions(-)
>
> --- a/include/linux/pm_runtime.h
> +++ b/include/linux/pm_runtime.h
> @@ -582,8 +582,6 @@ static inline int pm_runtime_put(struct
> return __pm_runtime_idle(dev, RPM_GET_PUT | RPM_ASYNC);
> }
>
> -DEFINE_FREE(pm_runtime_put, struct device *, if (_T) pm_runtime_put(_T))
> -
> /**
Reviewed-by: Dhruva Gole <d-gole@ti.com>
--
Best regards,
Dhruva Gole
Texas Instruments Incorporated
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/3] PM: runtime: Add auto-cleanup macros for "resume and get" operations
2025-09-23 8:53 ` Dhruva Gole
@ 2025-09-23 10:43 ` Rafael J. Wysocki
2025-09-23 10:56 ` Dhruva Gole
0 siblings, 1 reply; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-09-23 10:43 UTC (permalink / raw)
To: Dhruva Gole
Cc: Rafael J. Wysocki, Linux PM, Takashi Iwai, LKML, Linux PCI,
Alex Williamson, Bjorn Helgaas, Zhang Qilong, Ulf Hansson
On Tue, Sep 23, 2025 at 10:53 AM Dhruva Gole <d-gole@ti.com> wrote:
>
> On Sep 22, 2025 at 17:30:43 +0200, Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > It is generally useful to be able to automatically drop a device's
> > runtime PM usage counter incremented by runtime PM operations that
> > resume a device and bump up its usage counter [1].
> >
> > To that end, add DEFINE_CLASS() macros allowing pm_runtime_put()
> > and pm_runtime_put_autosuspend() to be used for the auto-cleanup in
> > those cases.
> >
> > Simply put, a piece of code like below:
> >
> > pm_runtime_get_sync(dev);
> > .....
> > pm_runtime_put(dev);
> > return 0;
> >
> > can be transformed with CLASS(pm_runtime_get_sync) like:
> >
> > guard(pm_runtime_get_sync)(dev);
> > .....
> > return 0;
> >
> > (see pm_runtime_put() call is gone).
> >
> > However, it is better to do proper error handling in the majority of
> > cases, so doing something like this instead of the above is recommended:
> >
> > CLASS(pm_runtime_get_active, pm)(dev);
> > if (IS_ERR(pm))
> > return PTR_ERR(pm);
> > .....
> > return 0;
> >
> > In all of the cases in which runtime PM is known to be enabled for the
> > given device or the device can be regarded as operational (and so it can
> > be accessed) with runtime PM disabled, a piece of code like:
> >
> > ret = pm_runtime_resume_and_get(dev);
> > if (ret < 0)
> > return ret;
> > .....
> > pm_runtime_put(dev);
> > return 0;
> >
> > can be simplified with CLASS() like:
> >
> > CLASS(pm_runtime_get_active, pm)(dev);
> > if (IS_ERR(pm))
> > return PTR_ERR(pm);
> > .....
> > return 0;
> >
> > (again, see pm_runtime_put() call is gone).
> >
> > Still, if the device cannot be accessed unless runtime PM has been
> > enabled for it, the CLASS(pm_runtime_get_active_enabled) variant
> > needs to be used, that is (in the context of the example above):
> >
> > CLASS(pm_runtime_get_active_enabled, pm)(dev);
> > if (IS_ERR(pm))
> > return PTR_ERR(pm);
> > .....
> > return 0;
> >
> > When the original code calls pm_runtime_put_autosuspend(), use one
> > of the "auto" class variants, CLASS(pm_runtime_get_active_auto) or
> > CLASS(pm_runtime_get_active_enabled_auto), so for example, a piece
> > of code like:
> >
> > ret = pm_runtime_resume_and_get(dev);
> > if (ret < 0)
> > return ret;
> > .....
> > pm_runtime_put_autosuspend(dev);
> > return 0;
> >
> > will become:
> >
> > CLASS(pm_runtime_get_active_enabled_auto, pm)(dev);
> > if (IS_ERR(pm))
> > return PTR_ERR(pm);
> > .....
> > return 0;
> >
> > Note that the cases in which the return value of pm_runtime_get_sync()
> > is checked can also be handled with the help of the new class macros.
> > For example, a piece of code like:
> >
> > ret = pm_runtime_get_sync(dev);
> > if (ret < 0) {
> > pm_runtime_put(dev);
> > return ret;
> > }
> > .....
> > pm_runtime_put(dev);
> > return 0;
> >
> > can be rewritten as:
> >
> > CLASS(pm_runtime_get_active_enabled, pm)(dev);
> > if (IS_ERR(pm))
> > return PTR_ERR(pm);
> > .....
> > return 0;
> >
> > or CLASS(pm_runtime_get_active) can be used if transparent handling of
> > disabled runtime PM is desirable.
> >
>
> Firstly, please can we add all this documentation in runtime_pm [1]
> Otherwise there's just far less developers aware of the new APIs getting
> introduced other than people directly involved. Not everyone is going to
> come down here to look at git log for API docs (even though we proud
> ourselves in having git log as our main source of Documentation in
> kernel ;) )
>
> [1] https://docs.kernel.org/power/runtime_pm.html
That will happen when the early adopters tell me that it works for them.
> > Link: https://lore.kernel.org/linux-pm/878qimv24u.wl-tiwai@suse.de/ [1]
> > Co-developed-by: Takashi Iwai <tiwai@suse.de>
> > Signed-off-by: Takashi Iwai <tiwai@suse.de>
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >
> > v2 -> v3:
> > * Two more class definitions for the case in which resume errors can be
> > neglected.
> > * Update of new code comments (for more clarity).
> > * Changelog update.
> >
> > v1 -> v2:
> > * Rename the new classes and the new static inline helper.
> > * Add two classes for handling disabled runtime PM.
> > * Expand the changelog.
> > * Adjust the subject.
> >
> > ---
> > drivers/base/power/runtime.c | 2 +
> > include/linux/pm_runtime.h | 82 +++++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 84 insertions(+)
>
> >
> > --- a/drivers/base/power/runtime.c
> > +++ b/drivers/base/power/runtime.c
> > @@ -796,6 +796,8 @@ static int rpm_resume(struct device *dev
> > if (dev->power.runtime_status == RPM_ACTIVE &&
> > dev->power.last_status == RPM_ACTIVE)
> > retval = 1;
> > + else if (rpmflags & RPM_TRANSPARENT)
> > + goto out;
>
> "TRANSPARENT" doesn't tell you exactly what happens. It should be something like
> RPM_IGNORE_DISABLED or RPM_ALLOW_DISABLED IMO.
There is a description in the header file and TRANSPARENT is shorter
than the alternatives. Besides, this is mostly for internal use.
> > else
> > retval = -EACCES;
> > }
> > --- a/include/linux/pm_runtime.h
> > +++ b/include/linux/pm_runtime.h
> > @@ -21,6 +21,7 @@
> > #define RPM_GET_PUT 0x04 /* Increment/decrement the
> > usage_count */
> > #define RPM_AUTO 0x08 /* Use autosuspend_delay */
> > +#define RPM_TRANSPARENT 0x10 /* Succeed if runtime PM is disabled */
> >
> > /*
> > * Use this for defining a set of PM operations to be used in all situations
> > @@ -533,6 +534,32 @@ static inline int pm_runtime_resume_and_
> > }
> >
> > /**
> > + * pm_runtime_get_active_dev - Resume a device and bump up its usage counter.
>
> I am getting no clue as to why this is different than regular
> pm_runtime_get_sync then? Can we describe this API better?
Again, this is for internal use.
I may as well drop the kerneldoc for this function altogether, but I'm
not going to send a v4 just for this purpose.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/3] PM: runtime: Add auto-cleanup macros for "resume and get" operations
2025-09-23 10:43 ` Rafael J. Wysocki
@ 2025-09-23 10:56 ` Dhruva Gole
0 siblings, 0 replies; 12+ messages in thread
From: Dhruva Gole @ 2025-09-23 10:56 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux PM, Takashi Iwai, LKML, Linux PCI, Alex Williamson,
Bjorn Helgaas, Zhang Qilong, Ulf Hansson
On Sep 23, 2025 at 12:43:21 +0200, Rafael J. Wysocki wrote:
> On Tue, Sep 23, 2025 at 10:53 AM Dhruva Gole <d-gole@ti.com> wrote:
> >
> > On Sep 22, 2025 at 17:30:43 +0200, Rafael J. Wysocki wrote:
> > > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > >
> > > It is generally useful to be able to automatically drop a device's
> > > runtime PM usage counter incremented by runtime PM operations that
> > > resume a device and bump up its usage counter [1].
> > >
> > > To that end, add DEFINE_CLASS() macros allowing pm_runtime_put()
> > > and pm_runtime_put_autosuspend() to be used for the auto-cleanup in
> > > those cases.
> > >
> > > Simply put, a piece of code like below:
> > >
> > > pm_runtime_get_sync(dev);
> > > .....
> > > pm_runtime_put(dev);
> > > return 0;
> > >
> > > can be transformed with CLASS(pm_runtime_get_sync) like:
> > >
> > > guard(pm_runtime_get_sync)(dev);
> > > .....
> > > return 0;
> > >
> > > (see pm_runtime_put() call is gone).
> > >
> > > However, it is better to do proper error handling in the majority of
> > > cases, so doing something like this instead of the above is recommended:
> > >
> > > CLASS(pm_runtime_get_active, pm)(dev);
> > > if (IS_ERR(pm))
> > > return PTR_ERR(pm);
> > > .....
> > > return 0;
> > >
> > > In all of the cases in which runtime PM is known to be enabled for the
> > > given device or the device can be regarded as operational (and so it can
> > > be accessed) with runtime PM disabled, a piece of code like:
> > >
> > > ret = pm_runtime_resume_and_get(dev);
> > > if (ret < 0)
> > > return ret;
> > > .....
> > > pm_runtime_put(dev);
> > > return 0;
> > >
> > > can be simplified with CLASS() like:
> > >
> > > CLASS(pm_runtime_get_active, pm)(dev);
> > > if (IS_ERR(pm))
> > > return PTR_ERR(pm);
> > > .....
> > > return 0;
> > >
> > > (again, see pm_runtime_put() call is gone).
> > >
> > > Still, if the device cannot be accessed unless runtime PM has been
> > > enabled for it, the CLASS(pm_runtime_get_active_enabled) variant
> > > needs to be used, that is (in the context of the example above):
> > >
> > > CLASS(pm_runtime_get_active_enabled, pm)(dev);
> > > if (IS_ERR(pm))
> > > return PTR_ERR(pm);
> > > .....
> > > return 0;
> > >
> > > When the original code calls pm_runtime_put_autosuspend(), use one
> > > of the "auto" class variants, CLASS(pm_runtime_get_active_auto) or
> > > CLASS(pm_runtime_get_active_enabled_auto), so for example, a piece
> > > of code like:
> > >
> > > ret = pm_runtime_resume_and_get(dev);
> > > if (ret < 0)
> > > return ret;
> > > .....
> > > pm_runtime_put_autosuspend(dev);
> > > return 0;
> > >
> > > will become:
> > >
> > > CLASS(pm_runtime_get_active_enabled_auto, pm)(dev);
> > > if (IS_ERR(pm))
> > > return PTR_ERR(pm);
> > > .....
> > > return 0;
> > >
> > > Note that the cases in which the return value of pm_runtime_get_sync()
> > > is checked can also be handled with the help of the new class macros.
> > > For example, a piece of code like:
> > >
> > > ret = pm_runtime_get_sync(dev);
> > > if (ret < 0) {
> > > pm_runtime_put(dev);
> > > return ret;
> > > }
> > > .....
> > > pm_runtime_put(dev);
> > > return 0;
> > >
> > > can be rewritten as:
> > >
> > > CLASS(pm_runtime_get_active_enabled, pm)(dev);
> > > if (IS_ERR(pm))
> > > return PTR_ERR(pm);
> > > .....
> > > return 0;
> > >
> > > or CLASS(pm_runtime_get_active) can be used if transparent handling of
> > > disabled runtime PM is desirable.
> > >
> >
> > Firstly, please can we add all this documentation in runtime_pm [1]
> > Otherwise there's just far less developers aware of the new APIs getting
> > introduced other than people directly involved. Not everyone is going to
> > come down here to look at git log for API docs (even though we proud
> > ourselves in having git log as our main source of Documentation in
> > kernel ;) )
> >
> > [1] https://docs.kernel.org/power/runtime_pm.html
>
> That will happen when the early adopters tell me that it works for them.
Okay..
>
> > > Link: https://lore.kernel.org/linux-pm/878qimv24u.wl-tiwai@suse.de/ [1]
> > > Co-developed-by: Takashi Iwai <tiwai@suse.de>
> > > Signed-off-by: Takashi Iwai <tiwai@suse.de>
> > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > ---
> > >
> > > v2 -> v3:
> > > * Two more class definitions for the case in which resume errors can be
> > > neglected.
> > > * Update of new code comments (for more clarity).
> > > * Changelog update.
> > >
> > > v1 -> v2:
> > > * Rename the new classes and the new static inline helper.
> > > * Add two classes for handling disabled runtime PM.
> > > * Expand the changelog.
> > > * Adjust the subject.
> > >
> > > ---
> > > drivers/base/power/runtime.c | 2 +
> > > include/linux/pm_runtime.h | 82 +++++++++++++++++++++++++++++++++++++++++++
> > > 2 files changed, 84 insertions(+)
> >
> > >
> > > --- a/drivers/base/power/runtime.c
> > > +++ b/drivers/base/power/runtime.c
> > > @@ -796,6 +796,8 @@ static int rpm_resume(struct device *dev
> > > if (dev->power.runtime_status == RPM_ACTIVE &&
> > > dev->power.last_status == RPM_ACTIVE)
> > > retval = 1;
> > > + else if (rpmflags & RPM_TRANSPARENT)
> > > + goto out;
> >
> > "TRANSPARENT" doesn't tell you exactly what happens. It should be something like
> > RPM_IGNORE_DISABLED or RPM_ALLOW_DISABLED IMO.
>
> There is a description in the header file and TRANSPARENT is shorter
> than the alternatives. Besides, this is mostly for internal use.
OK.
>
> > > else
> > > retval = -EACCES;
> > > }
> > > --- a/include/linux/pm_runtime.h
> > > +++ b/include/linux/pm_runtime.h
> > > @@ -21,6 +21,7 @@
> > > #define RPM_GET_PUT 0x04 /* Increment/decrement the
> > > usage_count */
> > > #define RPM_AUTO 0x08 /* Use autosuspend_delay */
> > > +#define RPM_TRANSPARENT 0x10 /* Succeed if runtime PM is disabled */
> > >
> > > /*
> > > * Use this for defining a set of PM operations to be used in all situations
> > > @@ -533,6 +534,32 @@ static inline int pm_runtime_resume_and_
> > > }
> > >
> > > /**
> > > + * pm_runtime_get_active_dev - Resume a device and bump up its usage counter.
> >
> > I am getting no clue as to why this is different than regular
> > pm_runtime_get_sync then? Can we describe this API better?
>
> Again, this is for internal use.
>
> I may as well drop the kerneldoc for this function altogether, but I'm
> not going to send a v4 just for this purpose.
Alright then, fine by me since most comments were nits, and I am ok with
the general idea here...
Reviewed-by: Dhruva Gole <d-gole@ti.com>
--
Best regards,
Dhruva Gole
Texas Instruments Incorporated
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/3] PM: runtime: Add auto-cleanup macros for "resume and get" operations
2025-09-22 15:30 ` [PATCH v3 1/3] PM: runtime: Add auto-cleanup macros for "resume and get" operations Rafael J. Wysocki
2025-09-23 8:53 ` Dhruva Gole
@ 2025-09-23 19:51 ` Frank Li
1 sibling, 0 replies; 12+ messages in thread
From: Frank Li @ 2025-09-23 19:51 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux PM, Takashi Iwai, LKML, Linux PCI, Alex Williamson,
Bjorn Helgaas, Zhang Qilong, Ulf Hansson
On Mon, Sep 22, 2025 at 05:30:43PM +0200, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> It is generally useful to be able to automatically drop a device's
> runtime PM usage counter incremented by runtime PM operations that
> resume a device and bump up its usage counter [1].
>
> To that end, add DEFINE_CLASS() macros allowing pm_runtime_put()
> and pm_runtime_put_autosuspend() to be used for the auto-cleanup in
> those cases.
>
> Simply put, a piece of code like below:
>
> pm_runtime_get_sync(dev);
> .....
> pm_runtime_put(dev);
> return 0;
>
> can be transformed with CLASS(pm_runtime_get_sync) like:
>
> guard(pm_runtime_get_sync)(dev);
> .....
> return 0;
>
> (see pm_runtime_put() call is gone).
>
> However, it is better to do proper error handling in the majority of
> cases, so doing something like this instead of the above is recommended:
>
> CLASS(pm_runtime_get_active, pm)(dev);
> if (IS_ERR(pm))
> return PTR_ERR(pm);
> .....
> return 0;
>
> In all of the cases in which runtime PM is known to be enabled for the
> given device or the device can be regarded as operational (and so it can
> be accessed) with runtime PM disabled, a piece of code like:
>
> ret = pm_runtime_resume_and_get(dev);
> if (ret < 0)
> return ret;
> .....
> pm_runtime_put(dev);
> return 0;
>
> can be simplified with CLASS() like:
>
> CLASS(pm_runtime_get_active, pm)(dev);
> if (IS_ERR(pm))
> return PTR_ERR(pm);
> .....
> return 0;
>
> (again, see pm_runtime_put() call is gone).
>
> Still, if the device cannot be accessed unless runtime PM has been
> enabled for it, the CLASS(pm_runtime_get_active_enabled) variant
> needs to be used, that is (in the context of the example above):
>
> CLASS(pm_runtime_get_active_enabled, pm)(dev);
> if (IS_ERR(pm))
> return PTR_ERR(pm);
> .....
> return 0;
>
> When the original code calls pm_runtime_put_autosuspend(), use one
> of the "auto" class variants, CLASS(pm_runtime_get_active_auto) or
> CLASS(pm_runtime_get_active_enabled_auto), so for example, a piece
> of code like:
>
> ret = pm_runtime_resume_and_get(dev);
> if (ret < 0)
> return ret;
> .....
> pm_runtime_put_autosuspend(dev);
> return 0;
>
> will become:
>
> CLASS(pm_runtime_get_active_enabled_auto, pm)(dev);
> if (IS_ERR(pm))
> return PTR_ERR(pm);
> .....
> return 0;
>
> Note that the cases in which the return value of pm_runtime_get_sync()
> is checked can also be handled with the help of the new class macros.
> For example, a piece of code like:
>
> ret = pm_runtime_get_sync(dev);
> if (ret < 0) {
> pm_runtime_put(dev);
> return ret;
> }
> .....
> pm_runtime_put(dev);
> return 0;
>
> can be rewritten as:
>
> CLASS(pm_runtime_get_active_enabled, pm)(dev);
> if (IS_ERR(pm))
> return PTR_ERR(pm);
> .....
> return 0;
>
> or CLASS(pm_runtime_get_active) can be used if transparent handling of
> disabled runtime PM is desirable.
>
> Link: https://lore.kernel.org/linux-pm/878qimv24u.wl-tiwai@suse.de/ [1]
> Co-developed-by: Takashi Iwai <tiwai@suse.de>
> Signed-off-by: Takashi Iwai <tiwai@suse.de>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
Nice feature.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
>
> v2 -> v3:
> * Two more class definitions for the case in which resume errors can be
> neglected.
> * Update of new code comments (for more clarity).
> * Changelog update.
>
> v1 -> v2:
> * Rename the new classes and the new static inline helper.
> * Add two classes for handling disabled runtime PM.
> * Expand the changelog.
> * Adjust the subject.
>
> ---
> drivers/base/power/runtime.c | 2 +
> include/linux/pm_runtime.h | 82 +++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 84 insertions(+)
>
> --- a/drivers/base/power/runtime.c
> +++ b/drivers/base/power/runtime.c
> @@ -796,6 +796,8 @@ static int rpm_resume(struct device *dev
> if (dev->power.runtime_status == RPM_ACTIVE &&
> dev->power.last_status == RPM_ACTIVE)
> retval = 1;
> + else if (rpmflags & RPM_TRANSPARENT)
> + goto out;
> else
> retval = -EACCES;
> }
> --- a/include/linux/pm_runtime.h
> +++ b/include/linux/pm_runtime.h
> @@ -21,6 +21,7 @@
> #define RPM_GET_PUT 0x04 /* Increment/decrement the
> usage_count */
> #define RPM_AUTO 0x08 /* Use autosuspend_delay */
> +#define RPM_TRANSPARENT 0x10 /* Succeed if runtime PM is disabled */
>
> /*
> * Use this for defining a set of PM operations to be used in all situations
> @@ -533,6 +534,32 @@ static inline int pm_runtime_resume_and_
> }
>
> /**
> + * pm_runtime_get_active_dev - Resume a device and bump up its usage counter.
> + * @dev: Target device.
> + * @rpmflags: Additional runtime PM flags to combine with RPM_GET_PUT.
> + *
> + * Resume @dev synchronously and if that is successful, increment its runtime
> + * PM usage counter.
> + *
> + * Return:
> + * * 0 if the runtime PM usage counter of @dev has been incremented.
> + * * Negative error code otherwise.
> + */
> +static inline struct device *pm_runtime_get_active_dev(struct device *dev,
> + int rpmflags)
> +{
> + int ret;
> +
> + ret = __pm_runtime_resume(dev, RPM_GET_PUT | rpmflags);
> + if (ret < 0) {
> + pm_runtime_put_noidle(dev);
> + return ERR_PTR(ret);
> + }
> +
> + return dev;
> +}
> +
> +/**
> * pm_runtime_put - Drop device usage counter and queue up "idle check" if 0.
> * @dev: Target device.
> *
> @@ -606,6 +633,61 @@ static inline int pm_runtime_put_autosus
> return __pm_runtime_put_autosuspend(dev);
> }
>
> +/*
> + * The way to use the classes defined below is to define a class variable and
> + * use it going forward for representing the target device until it goes out of
> + * the scope. For example:
> + *
> + * CLASS(pm_runtime_get_active, active_dev)(dev);
> + * if (IS_ERR(active_dev))
> + * return PTR_ERR(active_dev);
> + *
> + * ... do something with active_dev (which is guaranteed to never suspend) ...
> + *
> + * If an error occurs, the runtime PM usage counter of dev will not be
> + * incremented, so using these classes without error handling is not
> + * recommended.
> + */
> +DEFINE_CLASS(pm_runtime_get_active, struct device *,
> + if (!IS_ERR_OR_NULL(_T)) pm_runtime_put(_T),
> + pm_runtime_get_active_dev(dev, RPM_TRANSPARENT), struct device *dev)
> +
> +DEFINE_CLASS(pm_runtime_get_active_auto, struct device *,
> + if (!IS_ERR_OR_NULL(_T)) pm_runtime_put_autosuspend(_T),
> + pm_runtime_get_active_dev(dev, RPM_TRANSPARENT), struct device *dev)
> +
> +/*
> + * The following two classes are analogous to the two classes defined above,
> + * respectively, but they produce an error pointer if runtime PM has been
> + * disabled for the given device.
> + *
> + * They should be used only when runtime PM may be disabled for the given device
> + * and if that happens, the device is not regarded as operational and so it
> + * cannot be accessed. The classes defined above should be used instead in all
> + * of the other cases.
> + */
> +DEFINE_CLASS(pm_runtime_get_active_enabled, struct device *,
> + if (!IS_ERR_OR_NULL(_T)) pm_runtime_put(_T),
> + pm_runtime_get_active_dev(dev, 0), struct device *dev)
> +
> +DEFINE_CLASS(pm_runtime_get_active_enabled_auto, struct device *,
> + if (!IS_ERR_OR_NULL(_T)) pm_runtime_put_autosuspend(_T),
> + pm_runtime_get_active_dev(dev, 0), struct device *dev)
> +
> +/*
> + * The following classes may be used instead of the above if resume failures can
> + * be neglected. However, such cases are not expected to be prevalent, so using
> + * one of these classes should always be regarded as an exception and explained
> + * in an adjacent code comment.
> + */
> +DEFINE_CLASS(pm_runtime_get_sync, struct device *,
> + if (_T) pm_runtime_put(_T),
> + ({ pm_runtime_get_sync(dev); dev; }), struct device *dev)
> +
> +DEFINE_CLASS(pm_runtime_get_sync_auto, struct device *,
> + if (_T) pm_runtime_put_autosuspend(_T),
> + ({ pm_runtime_get_sync(dev); dev; }), struct device *dev)
> +
> /**
> * pm_runtime_put_sync - Drop device usage counter and run "idle check" if 0.
> * @dev: Target device.
>
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 2/3] PCI/sysfs: Use runtime PM class macro for auto-cleanup
2025-09-22 18:50 ` Bjorn Helgaas
@ 2025-09-26 14:06 ` Jonathan Cameron
2025-09-26 14:38 ` Rafael J. Wysocki
0 siblings, 1 reply; 12+ messages in thread
From: Jonathan Cameron @ 2025-09-26 14:06 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Rafael J. Wysocki, Linux PM, Takashi Iwai, LKML, Linux PCI,
Alex Williamson, Zhang Qilong, Ulf Hansson, Dan Williams
On Mon, 22 Sep 2025 13:50:36 -0500
Bjorn Helgaas <helgaas@kernel.org> wrote:
> On Mon, Sep 22, 2025 at 05:31:53PM +0200, Rafael J. Wysocki wrote:
> > From: Takashi Iwai <tiwai@suse.de>
> >
> > Use the newly introduced class macro to simplify the code.
> >
> > Also, add the proper error handling for the PM runtime get errors.
> >
> > Signed-off-by: Takashi Iwai <tiwai@suse.de>
> > Link: https://patch.msgid.link/20250919163147.4743-3-tiwai@suse.de
> > [ rjw: Adjusted the subject and the name of the class ]
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Being half asleep I went and replied to v1 when v2 and indeed this v3
were already out. Sorry about that.
Anyhow question is why not ACQUIRE() and ACQUIRE_ERR()?
original discussion on how those came about rather that direct use of
class that you have here was I think here:
https://lore.kernel.org/all/20250509104028.GL4439@noisy.programming.kicks-ass.net/
Though note, we didn't end up with the parallel universe that is talking about.
+CC Dan,
Jonathan
>
> > ---
> >
> > v2 -> v3: No changes
> >
> > v1 -> v2:
> > * Adjust the name of the class to handle the disabled runtime PM case
> > transparently (like the original code).
> >
> > ---
> > drivers/pci/pci-sysfs.c | 5 +++--
> > 1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > --- a/drivers/pci/pci-sysfs.c
> > +++ b/drivers/pci/pci-sysfs.c
> > @@ -1475,8 +1475,9 @@ static ssize_t reset_method_store(struct
> > return count;
> > }
> >
> > - pm_runtime_get_sync(dev);
> > - struct device *pmdev __free(pm_runtime_put) = dev;
> > + CLASS(pm_runtime_get_active, pmdev)(dev);
> > + if (IS_ERR(pmdev))
> > + return -ENXIO;
> >
> > if (sysfs_streq(buf, "default")) {
> > pci_init_reset_methods(pdev);
> >
> >
> >
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 2/3] PCI/sysfs: Use runtime PM class macro for auto-cleanup
2025-09-26 14:06 ` Jonathan Cameron
@ 2025-09-26 14:38 ` Rafael J. Wysocki
0 siblings, 0 replies; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-09-26 14:38 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Bjorn Helgaas, Rafael J. Wysocki, Linux PM, Takashi Iwai, LKML,
Linux PCI, Alex Williamson, Zhang Qilong, Ulf Hansson,
Dan Williams
On Fri, Sep 26, 2025 at 4:06 PM Jonathan Cameron
<jonathan.cameron@huawei.com> wrote:
>
> On Mon, 22 Sep 2025 13:50:36 -0500
> Bjorn Helgaas <helgaas@kernel.org> wrote:
>
> > On Mon, Sep 22, 2025 at 05:31:53PM +0200, Rafael J. Wysocki wrote:
> > > From: Takashi Iwai <tiwai@suse.de>
> > >
> > > Use the newly introduced class macro to simplify the code.
> > >
> > > Also, add the proper error handling for the PM runtime get errors.
> > >
> > > Signed-off-by: Takashi Iwai <tiwai@suse.de>
> > > Link: https://patch.msgid.link/20250919163147.4743-3-tiwai@suse.de
> > > [ rjw: Adjusted the subject and the name of the class ]
> > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > Acked-by: Bjorn Helgaas <bhelgaas@google.com>
> Being half asleep I went and replied to v1 when v2 and indeed this v3
> were already out. Sorry about that.
>
> Anyhow question is why not ACQUIRE() and ACQUIRE_ERR()?
See my reply:
https://lore.kernel.org/linux-pm/CAJZ5v0gnqoJ8bALZT61ZvTA=chp8y5QBiA7ZpNQ6fFJuQzZUnA@mail.gmail.com/
I think that it can be done though.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-09-26 14:39 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-22 15:26 [PATCH v3 0/3] PM: runtime: Auto-cleanup macros for runtime PM Rafael J. Wysocki
2025-09-22 15:30 ` [PATCH v3 1/3] PM: runtime: Add auto-cleanup macros for "resume and get" operations Rafael J. Wysocki
2025-09-23 8:53 ` Dhruva Gole
2025-09-23 10:43 ` Rafael J. Wysocki
2025-09-23 10:56 ` Dhruva Gole
2025-09-23 19:51 ` Frank Li
2025-09-22 15:31 ` [PATCH v3 2/3] PCI/sysfs: Use runtime PM class macro for auto-cleanup Rafael J. Wysocki
2025-09-22 18:50 ` Bjorn Helgaas
2025-09-26 14:06 ` Jonathan Cameron
2025-09-26 14:38 ` Rafael J. Wysocki
2025-09-22 15:33 ` [PATCH v3 3/3] PM: runtime: Drop DEFINE_FREE() for pm_runtime_put() Rafael J. Wysocki
2025-09-23 8:54 ` Dhruva Gole
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox