[PATCH] ACPI: Avoid flush_scheduled_work() usage

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

 



Flushing system-wide workqueues is dangerous and will be forbidden.
Replace system_wq with local acpi_wq.

Link: https://lkml.kernel.org/r/49925af7-78a8-a3dd-bce6-cfc02e1a9236@xxxxxxxxxxxxxxxxxxx
Signed-off-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx>
---
This patch blindly converts schedule_{,rcu_}work() into queue_{,rcu_}work()
within drivers/acpi/ directory, based on an assumption that none of work items
outside of drivers/acpi/ directory needs to be handled by acpi_wq.
Also, I kept sharing acpi_wq between acpi/ and acpi/apei, based on assumption
that sharing is safe and correct behavior. Did I convert correctly?

 drivers/acpi/acpi_video.c         | 2 +-
 drivers/acpi/apei/apei-internal.h | 1 +
 drivers/acpi/apei/ghes.c          | 2 +-
 drivers/acpi/bus.c                | 2 +-
 drivers/acpi/internal.h           | 1 +
 drivers/acpi/osl.c                | 6 +++++-
 drivers/acpi/scan.c               | 2 +-
 drivers/acpi/video_detect.c       | 2 +-
 8 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index 990ff5b0aeb8..18a5b8dd766e 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -1637,7 +1637,7 @@ static void brightness_switch_event(struct acpi_video_device *video_device,
 		return;
 
 	video_device->switch_brightness_event = event;
-	schedule_delayed_work(&video_device->switch_brightness_work, HZ / 10);
+	queue_delayed_work(acpi_wq, &video_device->switch_brightness_work, HZ / 10);
 }
 
 static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h
index 1d6ef9654725..205dcacf8abf 100644
--- a/drivers/acpi/apei/apei-internal.h
+++ b/drivers/acpi/apei/apei-internal.h
@@ -136,4 +136,5 @@ int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus);
 int cper_estatus_check(const struct acpi_hest_generic_status *estatus);
 
 int apei_osc_setup(void);
+extern struct workqueue_struct *acpi_wq;
 #endif
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index d91ad378c00d..871b5f6c2b45 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -619,7 +619,7 @@ static void ghes_defer_non_standard_event(struct acpi_hest_generic_data *gdata,
 	entry->error_severity = sev;
 
 	INIT_WORK(&entry->work, ghes_vendor_record_work_func);
-	schedule_work(&entry->work);
+	queue_work(acpi_wq, &entry->work);
 }
 
 static bool ghes_do_proc(struct ghes *ghes,
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index e807bffc0804..7dae7f884187 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -608,7 +608,7 @@ static void acpi_sb_notify(acpi_handle handle, u32 event, void *data)
 
 	if (event == ACPI_SB_NOTIFY_SHUTDOWN_REQUEST) {
 		if (!work_busy(&acpi_sb_work))
-			schedule_work(&acpi_sb_work);
+			queue_work(acpi_wq, &acpi_sb_work);
 	} else
 		pr_warn("event %x is not supported by \\_SB device\n", event);
 }
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 628bf8f18130..5f77c7c573a6 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -77,6 +77,7 @@ void acpi_lpss_init(void);
 #else
 static inline void acpi_lpss_init(void) {}
 #endif
+extern struct workqueue_struct *acpi_wq;
 
 void acpi_apd_init(void);
 
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 7a70c4bfc23c..1725125890cd 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -64,6 +64,7 @@ static int (*__acpi_os_prepare_extended_sleep)(u8 sleep_state, u32 val_a,
 
 static acpi_osd_handler acpi_irq_handler;
 static void *acpi_irq_context;
+struct workqueue_struct *acpi_wq;
 static struct workqueue_struct *kacpid_wq;
 static struct workqueue_struct *kacpi_notify_wq;
 static struct workqueue_struct *kacpi_hotplug_wq;
@@ -1575,7 +1576,7 @@ acpi_status acpi_release_memory(acpi_handle handle, struct resource *res,
 	 */
 	synchronize_rcu();
 	rcu_barrier();
-	flush_scheduled_work();
+	flush_workqueue(acpi_wq);
 
 	return AE_OK;
 }
@@ -1755,9 +1756,11 @@ acpi_status __init acpi_os_initialize(void)
 
 acpi_status __init acpi_os_initialize1(void)
 {
+	acpi_wq = alloc_workqueue("acpi", 0, 0);
 	kacpid_wq = alloc_workqueue("kacpid", 0, 1);
 	kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
 	kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0);
+	BUG_ON(!acpi_wq);
 	BUG_ON(!kacpid_wq);
 	BUG_ON(!kacpi_notify_wq);
 	BUG_ON(!kacpi_hotplug_wq);
@@ -1786,6 +1789,7 @@ acpi_status acpi_os_terminate(void)
 	destroy_workqueue(kacpid_wq);
 	destroy_workqueue(kacpi_notify_wq);
 	destroy_workqueue(kacpi_hotplug_wq);
+	destroy_workqueue(acpi_wq);
 
 	return AE_OK;
 }
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 762b61f67e6c..f16aaec445f2 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2676,7 +2676,7 @@ void acpi_scan_table_notify(void)
 		return;
 
 	INIT_WORK(work, acpi_table_events_fn);
-	schedule_work(work);
+	queue_work(acpi_wq, work);
 }
 
 int acpi_reconfig_notifier_register(struct notifier_block *nb)
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index becc198e4c22..441664275645 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -529,7 +529,7 @@ static int acpi_video_backlight_notify(struct notifier_block *nb,
 	/* A raw bl registering may change video -> native */
 	if (backlight->props.type == BACKLIGHT_RAW &&
 	    val == BACKLIGHT_REGISTERED)
-		schedule_work(&backlight_notify_work);
+		queue_work(acpi_wq, &backlight_notify_work);
 
 	return NOTIFY_OK;
 }
-- 
2.32.0




[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