* [PATCH v2 1/2] driver core: Export device_link_flag_is_sync_state_only()
@ 2025-09-11 11:16 Pin-yen Lin
2025-09-11 11:16 ` [PATCH v2 2/2] PM: sleep: Don't wait for SYNC_STATE_ONLY device links Pin-yen Lin
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Pin-yen Lin @ 2025-09-11 11:16 UTC (permalink / raw)
To: Rafael J . Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman,
Danilo Krummrich, Saravana Kannan
Cc: Hsin-Te Yuan, linux-pm, Chen-Yu Tsai, linux-kernel, Pin-yen Lin
Export device_link_flag_is_sync_state_only() for future patches.
Signed-off-by: Pin-yen Lin <treapking@chromium.org>
---
Changes in v2:
- New in v2
drivers/base/core.c | 3 ++-
include/linux/device.h | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index d22d6b23e758..cc6af9b0d59d 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -287,10 +287,11 @@ static bool device_is_ancestor(struct device *dev, struct device *target)
#define DL_MARKER_FLAGS (DL_FLAG_INFERRED | \
DL_FLAG_CYCLE | \
DL_FLAG_MANAGED)
-static inline bool device_link_flag_is_sync_state_only(u32 flags)
+bool device_link_flag_is_sync_state_only(u32 flags)
{
return (flags & ~DL_MARKER_FLAGS) == DL_FLAG_SYNC_STATE_ONLY;
}
+EXPORT_SYMBOL_GPL(device_link_flag_is_sync_state_only);
/**
* device_is_dependent - Check if one device depends on another one
diff --git a/include/linux/device.h b/include/linux/device.h
index 0470d19da7f2..e27d0bf7c43d 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1197,6 +1197,7 @@ const char *dev_driver_string(const struct device *dev);
struct device_link *device_link_add(struct device *consumer,
struct device *supplier, u32 flags);
void device_link_del(struct device_link *link);
+bool device_link_flag_is_sync_state_only(u32 flags);
void device_link_remove(void *consumer, struct device *supplier);
void device_links_supplier_sync_state_pause(void);
void device_links_supplier_sync_state_resume(void);
--
2.51.0.384.g4c02a37b29-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v2 2/2] PM: sleep: Don't wait for SYNC_STATE_ONLY device links 2025-09-11 11:16 [PATCH v2 1/2] driver core: Export device_link_flag_is_sync_state_only() Pin-yen Lin @ 2025-09-11 11:16 ` Pin-yen Lin 2025-09-11 12:28 ` Greg Kroah-Hartman 2025-09-11 12:28 ` [PATCH v2 1/2] driver core: Export device_link_flag_is_sync_state_only() Greg Kroah-Hartman 2025-09-11 12:50 ` Rafael J. Wysocki 2 siblings, 1 reply; 6+ messages in thread From: Pin-yen Lin @ 2025-09-11 11:16 UTC (permalink / raw) To: Rafael J . Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman, Danilo Krummrich, Saravana Kannan Cc: Hsin-Te Yuan, linux-pm, Chen-Yu Tsai, linux-kernel, Pin-yen Lin Device links with DL_FLAG_SYNC_STATE_ONLY should not affect suspend and resume, and functions like device_reorder_to_tail() and device_link_add() doesn't try to reorder the consumers with such flag. However, dpm_wait_for_consumers() and dpm_wait_for_suppliers() doesn't check this flag before triggering dpm_wait, leading to potential hang during suspend/resume. This can be reproduced on MT8186 Corsola Chromebook with devicetree like: usb-a-connector { compatible = "usb-a-connector"; port { usb_a_con: endpoint { remote-endpoint = <&usb_hs>; }; }; }; usb_host { compatible = "mediatek,mt8186-xhci", "mediatek,mtk-xhci"; port { usb_hs: endpoint { remote-endpoint = <&usb_a_con>; }; }; }; In this case, the two nodes form a cycle and a SYNC_STATE_ONLY devlink between usb_host (supplier) and usb-a-connector (consumer) is created. Use device_link_flag_is_sync_state_only() to check this in dpm_wait_for_consumers() and dpm_wait_for_suppliers() to fix this. Fixes: 05ef983e0d65a ("driver core: Add device link support for SYNC_STATE_ONLY flag") Signed-off-by: Pin-yen Lin <treapking@chromium.org> --- Changes in v2: - Update commit message - Use device_link_flag_is_sync_state_only() drivers/base/power/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 2ea6e05e6ec9..73a1916170ae 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -282,7 +282,8 @@ static void dpm_wait_for_suppliers(struct device *dev, bool async) * walking. */ list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) - if (READ_ONCE(link->status) != DL_STATE_DORMANT) + if (READ_ONCE(link->status) != DL_STATE_DORMANT && + !device_link_flag_is_sync_state_only(link->flags)) dpm_wait(link->supplier, async); device_links_read_unlock(idx); @@ -339,7 +340,8 @@ static void dpm_wait_for_consumers(struct device *dev, bool async) * unregistration). */ list_for_each_entry_rcu_locked(link, &dev->links.consumers, s_node) - if (READ_ONCE(link->status) != DL_STATE_DORMANT) + if (READ_ONCE(link->status) != DL_STATE_DORMANT && + !device_link_flag_is_sync_state_only(link->flags)) dpm_wait(link->consumer, async); device_links_read_unlock(idx); -- 2.51.0.384.g4c02a37b29-goog ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] PM: sleep: Don't wait for SYNC_STATE_ONLY device links 2025-09-11 11:16 ` [PATCH v2 2/2] PM: sleep: Don't wait for SYNC_STATE_ONLY device links Pin-yen Lin @ 2025-09-11 12:28 ` Greg Kroah-Hartman 2025-09-11 12:49 ` Rafael J. Wysocki 0 siblings, 1 reply; 6+ messages in thread From: Greg Kroah-Hartman @ 2025-09-11 12:28 UTC (permalink / raw) To: Pin-yen Lin Cc: Rafael J . Wysocki, Len Brown, Pavel Machek, Danilo Krummrich, Saravana Kannan, Hsin-Te Yuan, linux-pm, Chen-Yu Tsai, linux-kernel On Thu, Sep 11, 2025 at 07:16:03PM +0800, Pin-yen Lin wrote: > Device links with DL_FLAG_SYNC_STATE_ONLY should not affect suspend > and resume, and functions like device_reorder_to_tail() and > device_link_add() doesn't try to reorder the consumers with such flag. > > However, dpm_wait_for_consumers() and dpm_wait_for_suppliers() doesn't > check this flag before triggering dpm_wait, leading to potential hang > during suspend/resume. > > This can be reproduced on MT8186 Corsola Chromebook with devicetree like: > > usb-a-connector { > compatible = "usb-a-connector"; > port { > usb_a_con: endpoint { > remote-endpoint = <&usb_hs>; > }; > }; > }; > > usb_host { > compatible = "mediatek,mt8186-xhci", "mediatek,mtk-xhci"; > port { > usb_hs: endpoint { > remote-endpoint = <&usb_a_con>; > }; > }; > }; > > In this case, the two nodes form a cycle and a SYNC_STATE_ONLY devlink > between usb_host (supplier) and usb-a-connector (consumer) is created. > > Use device_link_flag_is_sync_state_only() to check this in > dpm_wait_for_consumers() and dpm_wait_for_suppliers() to fix this. > > Fixes: 05ef983e0d65a ("driver core: Add device link support for SYNC_STATE_ONLY flag") > Signed-off-by: Pin-yen Lin <treapking@chromium.org> > --- > > Changes in v2: > - Update commit message > - Use device_link_flag_is_sync_state_only() > > drivers/base/power/main.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c > index 2ea6e05e6ec9..73a1916170ae 100644 > --- a/drivers/base/power/main.c > +++ b/drivers/base/power/main.c > @@ -282,7 +282,8 @@ static void dpm_wait_for_suppliers(struct device *dev, bool async) > * walking. > */ > list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) > - if (READ_ONCE(link->status) != DL_STATE_DORMANT) > + if (READ_ONCE(link->status) != DL_STATE_DORMANT && > + !device_link_flag_is_sync_state_only(link->flags)) > dpm_wait(link->supplier, async); > > device_links_read_unlock(idx); > @@ -339,7 +340,8 @@ static void dpm_wait_for_consumers(struct device *dev, bool async) > * unregistration). > */ > list_for_each_entry_rcu_locked(link, &dev->links.consumers, s_node) > - if (READ_ONCE(link->status) != DL_STATE_DORMANT) > + if (READ_ONCE(link->status) != DL_STATE_DORMANT && > + !device_link_flag_is_sync_state_only(link->flags)) > dpm_wait(link->consumer, async); > > device_links_read_unlock(idx); The way you use this new function does not require it to have been exported to modules :( thanks, greg k-h ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] PM: sleep: Don't wait for SYNC_STATE_ONLY device links 2025-09-11 12:28 ` Greg Kroah-Hartman @ 2025-09-11 12:49 ` Rafael J. Wysocki 0 siblings, 0 replies; 6+ messages in thread From: Rafael J. Wysocki @ 2025-09-11 12:49 UTC (permalink / raw) To: Greg Kroah-Hartman, Pin-yen Lin Cc: Len Brown, Pavel Machek, Danilo Krummrich, Saravana Kannan, Hsin-Te Yuan, linux-pm, Chen-Yu Tsai, linux-kernel On Thu, Sep 11, 2025 at 2:28 PM Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote: > > On Thu, Sep 11, 2025 at 07:16:03PM +0800, Pin-yen Lin wrote: > > Device links with DL_FLAG_SYNC_STATE_ONLY should not affect suspend > > and resume, and functions like device_reorder_to_tail() and > > device_link_add() doesn't try to reorder the consumers with such flag. > > > > However, dpm_wait_for_consumers() and dpm_wait_for_suppliers() doesn't > > check this flag before triggering dpm_wait, leading to potential hang > > during suspend/resume. > > > > This can be reproduced on MT8186 Corsola Chromebook with devicetree like: > > > > usb-a-connector { > > compatible = "usb-a-connector"; > > port { > > usb_a_con: endpoint { > > remote-endpoint = <&usb_hs>; > > }; > > }; > > }; > > > > usb_host { > > compatible = "mediatek,mt8186-xhci", "mediatek,mtk-xhci"; > > port { > > usb_hs: endpoint { > > remote-endpoint = <&usb_a_con>; > > }; > > }; > > }; > > > > In this case, the two nodes form a cycle and a SYNC_STATE_ONLY devlink > > between usb_host (supplier) and usb-a-connector (consumer) is created. > > > > Use device_link_flag_is_sync_state_only() to check this in > > dpm_wait_for_consumers() and dpm_wait_for_suppliers() to fix this. > > > > Fixes: 05ef983e0d65a ("driver core: Add device link support for SYNC_STATE_ONLY flag") > > Signed-off-by: Pin-yen Lin <treapking@chromium.org> > > --- > > > > Changes in v2: > > - Update commit message > > - Use device_link_flag_is_sync_state_only() > > > > drivers/base/power/main.c | 6 ++++-- > > 1 file changed, 4 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c > > index 2ea6e05e6ec9..73a1916170ae 100644 > > --- a/drivers/base/power/main.c > > +++ b/drivers/base/power/main.c > > @@ -282,7 +282,8 @@ static void dpm_wait_for_suppliers(struct device *dev, bool async) > > * walking. > > */ > > list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) > > - if (READ_ONCE(link->status) != DL_STATE_DORMANT) > > + if (READ_ONCE(link->status) != DL_STATE_DORMANT && > > + !device_link_flag_is_sync_state_only(link->flags)) > > dpm_wait(link->supplier, async); > > > > device_links_read_unlock(idx); > > @@ -339,7 +340,8 @@ static void dpm_wait_for_consumers(struct device *dev, bool async) > > * unregistration). > > */ > > list_for_each_entry_rcu_locked(link, &dev->links.consumers, s_node) > > - if (READ_ONCE(link->status) != DL_STATE_DORMANT) > > + if (READ_ONCE(link->status) != DL_STATE_DORMANT && > > + !device_link_flag_is_sync_state_only(link->flags)) > > dpm_wait(link->consumer, async); > > > > device_links_read_unlock(idx); > > The way you use this new function does not require it to have been > exported to modules :( Also, I'd just make it non-static (without exporting it to modules) and use it in the same patch because the new usage is the reason for exporting. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] driver core: Export device_link_flag_is_sync_state_only() 2025-09-11 11:16 [PATCH v2 1/2] driver core: Export device_link_flag_is_sync_state_only() Pin-yen Lin 2025-09-11 11:16 ` [PATCH v2 2/2] PM: sleep: Don't wait for SYNC_STATE_ONLY device links Pin-yen Lin @ 2025-09-11 12:28 ` Greg Kroah-Hartman 2025-09-11 12:50 ` Rafael J. Wysocki 2 siblings, 0 replies; 6+ messages in thread From: Greg Kroah-Hartman @ 2025-09-11 12:28 UTC (permalink / raw) To: Pin-yen Lin Cc: Rafael J . Wysocki, Len Brown, Pavel Machek, Danilo Krummrich, Saravana Kannan, Hsin-Te Yuan, linux-pm, Chen-Yu Tsai, linux-kernel On Thu, Sep 11, 2025 at 07:16:02PM +0800, Pin-yen Lin wrote: > Export device_link_flag_is_sync_state_only() for future patches. That says what, but not why. This feels like an odd thing to export, what should care about this type of thing? What should a driver do based on that information? We need more information here. thanks, greg k-h ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] driver core: Export device_link_flag_is_sync_state_only() 2025-09-11 11:16 [PATCH v2 1/2] driver core: Export device_link_flag_is_sync_state_only() Pin-yen Lin 2025-09-11 11:16 ` [PATCH v2 2/2] PM: sleep: Don't wait for SYNC_STATE_ONLY device links Pin-yen Lin 2025-09-11 12:28 ` [PATCH v2 1/2] driver core: Export device_link_flag_is_sync_state_only() Greg Kroah-Hartman @ 2025-09-11 12:50 ` Rafael J. Wysocki 2 siblings, 0 replies; 6+ messages in thread From: Rafael J. Wysocki @ 2025-09-11 12:50 UTC (permalink / raw) To: Pin-yen Lin Cc: Rafael J . Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman, Danilo Krummrich, Saravana Kannan, Hsin-Te Yuan, linux-pm, Chen-Yu Tsai, linux-kernel On Thu, Sep 11, 2025 at 1:21 PM Pin-yen Lin <treapking@chromium.org> wrote: > > Export device_link_flag_is_sync_state_only() for future patches. > > Signed-off-by: Pin-yen Lin <treapking@chromium.org> > > --- > > Changes in v2: > - New in v2 > > drivers/base/core.c | 3 ++- > include/linux/device.h | 1 + > 2 files changed, 3 insertions(+), 1 deletion(-) > > diff --git a/drivers/base/core.c b/drivers/base/core.c > index d22d6b23e758..cc6af9b0d59d 100644 > --- a/drivers/base/core.c > +++ b/drivers/base/core.c > @@ -287,10 +287,11 @@ static bool device_is_ancestor(struct device *dev, struct device *target) > #define DL_MARKER_FLAGS (DL_FLAG_INFERRED | \ > DL_FLAG_CYCLE | \ > DL_FLAG_MANAGED) > -static inline bool device_link_flag_is_sync_state_only(u32 flags) > +bool device_link_flag_is_sync_state_only(u32 flags) > { > return (flags & ~DL_MARKER_FLAGS) == DL_FLAG_SYNC_STATE_ONLY; > } > +EXPORT_SYMBOL_GPL(device_link_flag_is_sync_state_only); As Greg said, this isn't necessary. > > /** > * device_is_dependent - Check if one device depends on another one > diff --git a/include/linux/device.h b/include/linux/device.h > index 0470d19da7f2..e27d0bf7c43d 100644 > --- a/include/linux/device.h > +++ b/include/linux/device.h > @@ -1197,6 +1197,7 @@ const char *dev_driver_string(const struct device *dev); > struct device_link *device_link_add(struct device *consumer, > struct device *supplier, u32 flags); > void device_link_del(struct device_link *link); > +bool device_link_flag_is_sync_state_only(u32 flags); No, you only need it in drivers/base/base.h > void device_link_remove(void *consumer, struct device *supplier); > void device_links_supplier_sync_state_pause(void); > void device_links_supplier_sync_state_resume(void); > -- ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-09-11 12:50 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-09-11 11:16 [PATCH v2 1/2] driver core: Export device_link_flag_is_sync_state_only() Pin-yen Lin 2025-09-11 11:16 ` [PATCH v2 2/2] PM: sleep: Don't wait for SYNC_STATE_ONLY device links Pin-yen Lin 2025-09-11 12:28 ` Greg Kroah-Hartman 2025-09-11 12:49 ` Rafael J. Wysocki 2025-09-11 12:28 ` [PATCH v2 1/2] driver core: Export device_link_flag_is_sync_state_only() Greg Kroah-Hartman 2025-09-11 12:50 ` Rafael J. Wysocki
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox