public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state()
@ 2026-04-18 16:22 Danilo Krummrich
  2026-04-18 19:16 ` Saravana Kannan
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Danilo Krummrich @ 2026-04-18 16:22 UTC (permalink / raw)
  To: gregkh, rafael, saravanak, ulf.hansson
  Cc: driver-core, linux-kernel, Danilo Krummrich

dev_has_sync_state() reads dev->driver twice without holding
device_lock() -- once for the NULL check and once to dereference
->sync_state. Some callers only hold device_links_write_lock, which
doesn't prevent a concurrent unbind from clearing dev->driver via
device_unbind_cleanup().

Fix it by reading dev->driver exactly once with READ_ONCE(), pairing
with the WRITE_ONCE() in device_set_driver().

Link: https://lore.kernel.org/driver-core/DHW8QPU1VU1F.3P6PH69HLFBYC@kernel.org/
Fixes: ac338acf514e ("driver core: Add dev_has_sync_state()")
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
 include/linux/device.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/linux/device.h b/include/linux/device.h
index ac972e7bead4..4c1c9cb8570a 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1018,9 +1018,12 @@ static inline void device_lock_assert(struct device *dev)
 
 static inline bool dev_has_sync_state(struct device *dev)
 {
+	struct device_driver *drv;
+
 	if (!dev)
 		return false;
-	if (dev->driver && dev->driver->sync_state)
+	drv = READ_ONCE(dev->driver);
+	if (drv && drv->sync_state)
 		return true;
 	if (dev->bus && dev->bus->sync_state)
 		return true;

base-commit: 5b484311507b5d403c1f7a45f6aa3778549e268b
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state()
  2026-04-18 16:22 [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state() Danilo Krummrich
@ 2026-04-18 19:16 ` Saravana Kannan
  2026-04-19 14:40 ` Greg KH
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Saravana Kannan @ 2026-04-18 19:16 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, saravanak, ulf.hansson, driver-core, linux-kernel

On Sat, Apr 18, 2026 at 9:22 AM Danilo Krummrich <dakr@kernel.org> wrote:
>
> dev_has_sync_state() reads dev->driver twice without holding
> device_lock() -- once for the NULL check and once to dereference
> ->sync_state. Some callers only hold device_links_write_lock, which
> doesn't prevent a concurrent unbind from clearing dev->driver via
> device_unbind_cleanup().
>
> Fix it by reading dev->driver exactly once with READ_ONCE(), pairing
> with the WRITE_ONCE() in device_set_driver().
>
> Link: https://lore.kernel.org/driver-core/DHW8QPU1VU1F.3P6PH69HLFBYC@kernel.org/
> Fixes: ac338acf514e ("driver core: Add dev_has_sync_state()")
> Signed-off-by: Danilo Krummrich <dakr@kernel.org>

Reviewed-by: Saravana Kannan <saravanak@kernel.org>

-Saravana

> ---
>  include/linux/device.h | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/device.h b/include/linux/device.h
> index ac972e7bead4..4c1c9cb8570a 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -1018,9 +1018,12 @@ static inline void device_lock_assert(struct device *dev)
>
>  static inline bool dev_has_sync_state(struct device *dev)
>  {
> +       struct device_driver *drv;
> +
>         if (!dev)
>                 return false;
> -       if (dev->driver && dev->driver->sync_state)
> +       drv = READ_ONCE(dev->driver);
> +       if (drv && drv->sync_state)
>                 return true;
>         if (dev->bus && dev->bus->sync_state)
>                 return true;
>
> base-commit: 5b484311507b5d403c1f7a45f6aa3778549e268b
> --
> 2.53.0
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state()
  2026-04-18 16:22 [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state() Danilo Krummrich
  2026-04-18 19:16 ` Saravana Kannan
@ 2026-04-19 14:40 ` Greg KH
  2026-04-20 10:40 ` Rafael J. Wysocki
  2026-04-28 22:38 ` Danilo Krummrich
  3 siblings, 0 replies; 9+ messages in thread
From: Greg KH @ 2026-04-19 14:40 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: rafael, saravanak, ulf.hansson, driver-core, linux-kernel

On Sat, Apr 18, 2026 at 06:22:18PM +0200, Danilo Krummrich wrote:
> dev_has_sync_state() reads dev->driver twice without holding
> device_lock() -- once for the NULL check and once to dereference
> ->sync_state. Some callers only hold device_links_write_lock, which
> doesn't prevent a concurrent unbind from clearing dev->driver via
> device_unbind_cleanup().
> 
> Fix it by reading dev->driver exactly once with READ_ONCE(), pairing
> with the WRITE_ONCE() in device_set_driver().
> 
> Link: https://lore.kernel.org/driver-core/DHW8QPU1VU1F.3P6PH69HLFBYC@kernel.org/
> Fixes: ac338acf514e ("driver core: Add dev_has_sync_state()")
> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
> ---
>  include/linux/device.h | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/device.h b/include/linux/device.h
> index ac972e7bead4..4c1c9cb8570a 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -1018,9 +1018,12 @@ static inline void device_lock_assert(struct device *dev)
>  
>  static inline bool dev_has_sync_state(struct device *dev)
>  {
> +	struct device_driver *drv;
> +
>  	if (!dev)
>  		return false;
> -	if (dev->driver && dev->driver->sync_state)
> +	drv = READ_ONCE(dev->driver);
> +	if (drv && drv->sync_state)
>  		return true;
>  	if (dev->bus && dev->bus->sync_state)
>  		return true;
> 
> base-commit: 5b484311507b5d403c1f7a45f6aa3778549e268b
> -- 
> 2.53.0
> 
> 

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state()
  2026-04-18 16:22 [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state() Danilo Krummrich
  2026-04-18 19:16 ` Saravana Kannan
  2026-04-19 14:40 ` Greg KH
@ 2026-04-20 10:40 ` Rafael J. Wysocki
  2026-05-04  9:49   ` Ulf Hansson
  2026-04-28 22:38 ` Danilo Krummrich
  3 siblings, 1 reply; 9+ messages in thread
From: Rafael J. Wysocki @ 2026-04-20 10:40 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, saravanak, ulf.hansson, driver-core, linux-kernel

On Sat, Apr 18, 2026 at 6:22 PM Danilo Krummrich <dakr@kernel.org> wrote:
>
> dev_has_sync_state() reads dev->driver twice without holding
> device_lock() -- once for the NULL check and once to dereference
> ->sync_state. Some callers only hold device_links_write_lock, which
> doesn't prevent a concurrent unbind from clearing dev->driver via
> device_unbind_cleanup().
>
> Fix it by reading dev->driver exactly once with READ_ONCE(), pairing
> with the WRITE_ONCE() in device_set_driver().
>
> Link: https://lore.kernel.org/driver-core/DHW8QPU1VU1F.3P6PH69HLFBYC@kernel.org/
> Fixes: ac338acf514e ("driver core: Add dev_has_sync_state()")
> Signed-off-by: Danilo Krummrich <dakr@kernel.org>

Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>

> ---
>  include/linux/device.h | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/device.h b/include/linux/device.h
> index ac972e7bead4..4c1c9cb8570a 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -1018,9 +1018,12 @@ static inline void device_lock_assert(struct device *dev)
>
>  static inline bool dev_has_sync_state(struct device *dev)
>  {
> +       struct device_driver *drv;
> +
>         if (!dev)
>                 return false;
> -       if (dev->driver && dev->driver->sync_state)
> +       drv = READ_ONCE(dev->driver);
> +       if (drv && drv->sync_state)
>                 return true;
>         if (dev->bus && dev->bus->sync_state)
>                 return true;
>

On a somewhat related note, I'm wondering if this function can be
moved to drivers/base/base.h?

It doesn't look like having it defined in device.h is particularly useful.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state()
  2026-04-18 16:22 [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state() Danilo Krummrich
                   ` (2 preceding siblings ...)
  2026-04-20 10:40 ` Rafael J. Wysocki
@ 2026-04-28 22:38 ` Danilo Krummrich
  3 siblings, 0 replies; 9+ messages in thread
From: Danilo Krummrich @ 2026-04-28 22:38 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, saravanak, ulf.hansson, driver-core, linux-kernel

On Sat, 18 Apr 2026 18:22:18 +0200, Danilo Krummrich wrote:
> [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state()

Applied, thanks!

  Branch: driver-core-testing
  Tree:   git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git

[1/1] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state()
      commit: e9506871a8ea

The patch will appear in the next linux-next integration (typically within 24
hours on weekdays).

The patch is in the driver-core-testing branch and will be promoted to
driver-core-next after validation.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state()
  2026-04-20 10:40 ` Rafael J. Wysocki
@ 2026-05-04  9:49   ` Ulf Hansson
  2026-05-04 10:30     ` Danilo Krummrich
  0 siblings, 1 reply; 9+ messages in thread
From: Ulf Hansson @ 2026-05-04  9:49 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Danilo Krummrich, gregkh, saravanak, driver-core, linux-kernel

On Mon, 20 Apr 2026 at 12:40, Rafael J. Wysocki <rafael@kernel.org> wrote:
>
> On Sat, Apr 18, 2026 at 6:22 PM Danilo Krummrich <dakr@kernel.org> wrote:
> >
> > dev_has_sync_state() reads dev->driver twice without holding
> > device_lock() -- once for the NULL check and once to dereference
> > ->sync_state. Some callers only hold device_links_write_lock, which
> > doesn't prevent a concurrent unbind from clearing dev->driver via
> > device_unbind_cleanup().
> >
> > Fix it by reading dev->driver exactly once with READ_ONCE(), pairing
> > with the WRITE_ONCE() in device_set_driver().
> >
> > Link: https://lore.kernel.org/driver-core/DHW8QPU1VU1F.3P6PH69HLFBYC@kernel.org/
> > Fixes: ac338acf514e ("driver core: Add dev_has_sync_state()")
> > Signed-off-by: Danilo Krummrich <dakr@kernel.org>
>
> Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
>
> > ---
> >  include/linux/device.h | 5 ++++-
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/linux/device.h b/include/linux/device.h
> > index ac972e7bead4..4c1c9cb8570a 100644
> > --- a/include/linux/device.h
> > +++ b/include/linux/device.h
> > @@ -1018,9 +1018,12 @@ static inline void device_lock_assert(struct device *dev)
> >
> >  static inline bool dev_has_sync_state(struct device *dev)
> >  {
> > +       struct device_driver *drv;
> > +
> >         if (!dev)
> >                 return false;
> > -       if (dev->driver && dev->driver->sync_state)
> > +       drv = READ_ONCE(dev->driver);
> > +       if (drv && drv->sync_state)
> >                 return true;
> >         if (dev->bus && dev->bus->sync_state)
> >                 return true;
> >
>
> On a somewhat related note, I'm wondering if this function can be
> moved to drivers/base/base.h?
>
> It doesn't look like having it defined in device.h is particularly useful.

Apologize for the delay. Genpd needs the function [1] when it tries to
assign a common ->sync_state() callback for its providers.

Kind regards
Uffe

[1]
https://lore.kernel.org/all/20260410104058.83748-6-ulf.hansson@linaro.org/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state()
  2026-05-04  9:49   ` Ulf Hansson
@ 2026-05-04 10:30     ` Danilo Krummrich
  2026-05-04 18:43       ` Ulf Hansson
  0 siblings, 1 reply; 9+ messages in thread
From: Danilo Krummrich @ 2026-05-04 10:30 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, gregkh, saravanak, driver-core, linux-kernel

On Mon May 4, 2026 at 11:49 AM CEST, Ulf Hansson wrote:
> Apologize for the delay. Genpd needs the function [1] when it tries to
> assign a common ->sync_state() callback for its providers.

Can you add a revert of [1] to your patch series, so it gets (re-)exported with
a user?

[1] https://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git/commit/?h=driver-core-next&id=9db268212e0d7c7e3c4aef3494e55afbc1695b1f

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state()
  2026-05-04 10:30     ` Danilo Krummrich
@ 2026-05-04 18:43       ` Ulf Hansson
  2026-05-04 18:59         ` Danilo Krummrich
  0 siblings, 1 reply; 9+ messages in thread
From: Ulf Hansson @ 2026-05-04 18:43 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Rafael J. Wysocki, gregkh, saravanak, driver-core, linux-kernel

On Mon, 4 May 2026 at 12:30, Danilo Krummrich <dakr@kernel.org> wrote:
>
> On Mon May 4, 2026 at 11:49 AM CEST, Ulf Hansson wrote:
> > Apologize for the delay. Genpd needs the function [1] when it tries to
> > assign a common ->sync_state() callback for its providers.
>
> Can you add a revert of [1] to your patch series, so it gets (re-)exported with
> a user?

Yes!

I was trying to avoid dependent changes to the driver core to funnel
my series entirely through my pmdomain tree. Anyway, perhaps you can
host an immutable branch for me to pull in, in this case.

Let's see, I will suggest something for the merge path in the cover
letter when I post my new version.

Kind regards
Uffe

>
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git/commit/?h=driver-core-next&id=9db268212e0d7c7e3c4aef3494e55afbc1695b1f

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state()
  2026-05-04 18:43       ` Ulf Hansson
@ 2026-05-04 18:59         ` Danilo Krummrich
  0 siblings, 0 replies; 9+ messages in thread
From: Danilo Krummrich @ 2026-05-04 18:59 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, gregkh, saravanak, driver-core, linux-kernel

On Mon May 4, 2026 at 8:43 PM CEST, Ulf Hansson wrote:
> On Mon, 4 May 2026 at 12:30, Danilo Krummrich <dakr@kernel.org> wrote:
>>
>> On Mon May 4, 2026 at 11:49 AM CEST, Ulf Hansson wrote:
>> > Apologize for the delay. Genpd needs the function [1] when it tries to
>> > assign a common ->sync_state() callback for its providers.
>>
>> Can you add a revert of [1] to your patch series, so it gets (re-)exported with
>> a user?
>
> Yes!
>
> I was trying to avoid dependent changes to the driver core to funnel
> my series entirely through my pmdomain tree. Anyway, perhaps you can
> host an immutable branch for me to pull in, in this case.

I think you can just make the revert the first patch in your series and when it
is ready I can pick up only the revert in the driver-core tree; everything else
can go through your pmdomain tree.

I.e. you don't need the revert in your pmdomain tree as it should still have
dev_has_sync_state() exported in device.h.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-05-04 18:59 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-18 16:22 [PATCH] driver core: use READ_ONCE() for dev->driver in dev_has_sync_state() Danilo Krummrich
2026-04-18 19:16 ` Saravana Kannan
2026-04-19 14:40 ` Greg KH
2026-04-20 10:40 ` Rafael J. Wysocki
2026-05-04  9:49   ` Ulf Hansson
2026-05-04 10:30     ` Danilo Krummrich
2026-05-04 18:43       ` Ulf Hansson
2026-05-04 18:59         ` Danilo Krummrich
2026-04-28 22:38 ` Danilo Krummrich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox