ACPI/sbshc: Fix rare oops when removing modules.
PATCH 1/1 ACPI/sbshc: Fix rare oops when removing modules.
There was a small race when removing the sbshc module where smbus_alarm() had queued acpi_smbus_callback() for deferred execution but it hadn't been run yet, so that when it did run hc had been freed and the module unloaded, resulting in an invalid paging request.
A similar race existed when removing the sbs module with regards to acpi_sbs_callback() (which is called from acpi_smbus_callback()).
We therefore need to ensure no callbacks are pending or executing before the cleanups are done and the modules are removed.
--- drivers/acpi/osl.c | 1 + drivers/acpi/sbshc.c | 2 ++ 2 files changed, 3 insertions(+)
drivers/acpi/osl.c +1 -0
@@ -1129,6 +1129,7 @@ void acpi_os_wait_events_complete(void)flush_workqueue (kacpid_wq);flush_workqueue (kacpi_notify_wq); } +EXPORT_SYMBOL (acpi_os_wait_events_complete);struct acpi_hp_work {struct work_struct work;
drivers/acpi/sbshc.c +2 -0
@@ -196,6 +196,7 @@ int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc) hc->callback =NULL ; hc->context =NULL ;mutex_unlock (&hc->lock); +acpi_os_wait_events_complete ();return 0 ; }
@@ -292,6 +293,7 @@ static int acpi_smbus_hc_remove(struct acpi_device *device) hc =acpi_driver_data (device);acpi_ec_remove_query_handler (hc->ec, hc->query_bit); +acpi_os_wait_events_complete ();kfree (hc); device->driver_data =NULL ;return 0 ;
Signature · 1 line
2.17.1
Rafael J. Wysocki
AppliedQuoted 43 lines · CEST Ronald Tschalär
There was a small race when removing the sbshc module where
smbus_alarm()had queuedacpi_smbus_callback()for deferred execution but it hadn't been run yet, so that when it did run hc had been freed and the module unloaded, resulting in an invalid paging request.A similar race existed when removing the sbs module with regards to
acpi_sbs_callback()(which is called fromacpi_smbus_callback()).We therefore need to ensure no callbacks are pending or executing before the cleanups are done and the modules are removed.
Signed-off-by Ronald Tschalär <[email protected]>--- drivers/acpi/osl.c | 1 + drivers/acpi/sbshc.c | 2 ++ 2 files changed, 3 insertions(+)drivers/acpi/osl.c +1
-0@@ -1129,6 +1129,7 @@ void acpi_os_wait_events_complete(void)flush_workqueue (kacpid_wq);flush_workqueue (kacpi_notify_wq); } +EXPORT_SYMBOL (acpi_os_wait_events_complete);struct acpi_hp_work {struct work_struct work;drivers/acpi/sbshc.c +1
-0@@ -196,6 +196,7 @@ int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc) hc->callback =NULL ; hc->context =NULL ;mutex_unlock (&hc->lock); +acpi_os_wait_events_complete ();return 0 ; }
drivers/acpi/sbshc.c static int acpi_smbus_hc_remove(struct acpi_device *device) · line 299
Quoted 7 lines
drivers/acpi/sbshc.c +1
-0@@ -292,6 +293,7 @@ static int acpi_smbus_hc_remove(struct acpi_device *device) hc =acpi_driver_data (device);acpi_ec_remove_query_handler (hc->ec, hc->query_bit); +acpi_os_wait_events_complete ();kfree (hc); device->driver_data =NULL ;return 0 ;
Applied, thanks!