[PATCH] ACPI: bus: Only call notify for a completely bound ACPI device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


Commit d6fb6ee1820c ("ACPI: bus: Drop driver member of struct
acpi_device") removed acpi_device::driver in favour of struct

However there is a problem: While the two pointers are equivalent after
the device is completely probed, there is a small time frame where
acpi_device::dev->driver is already set but acpi_device::driver wasn't.

The function acpi_bus_notify() used to have a check for
acpi_device::driver that was changed to a check for adev->dev.driver in
Commit d6fb6ee1820c.

Pierre Asselin reports that starting with above change his laptop
crashed during boot when on AC power. That's because acpi_bus_notify()
is called in that small time frame (triggered by acpi_ac_add()) which
results in a call to acpi_ac_notify while this function isn't ready yet.

So in acpi_bus_notify() check for the device being bound (which becomes
true only after the acpi probe call succeeds) instead of for

Note that usually you have to hold the device lock to call
device_is_bound(). I don't think this is the case here, so there likely
is a race condition. The problem might be that the driver unbinds after
the check but before adev->dev.driver is evaluated. However this race
already existed before commit d6fb6ee1820c, so the change here is a net
improvement even though it might not result in a completely correct

A similar check in the acpi sysfs code is also converted. This is less
critical as it happens in code that is run when a sysfs file is
accessed. That shouldn't happen for a device that isn't bound.

Fixes: d6fb6ee1820c ("ACPI: bus: Drop driver member of struct acpi_device")
Reported-by: Pierre Asselin <pa@xxxxxxxxx>
Link: https://lore.kernel.org/linux-acpi/9f6cba7a8a57e5a687c934e8e406e28c.squirrel@xxxxxxxxxxxxxx
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>
 drivers/acpi/bus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 9531dd0fef50..a5a8f82981ce 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -518,7 +518,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
 	if (!adev)
 		goto err;
-	if (adev->dev.driver) {
+	if (device_is_bound(&adev->dev)) {
 		struct acpi_driver *driver = to_acpi_driver(adev->dev.driver);
 		if (driver && driver->ops.notify &&

base-commit: fe15c26ee26efa11741a7b632e9f23b01aca4cc6

[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]
  Powered by Linux