From fcfc638c6b1345b6646523dbab0065b36a868ffc Mon Sep 17 00:00:00 2001 From: "Alexey Y. Starikovskiy" Date: Tue, 26 Sep 2006 04:18:16 -0400 Subject: [PATCH 1/2] ACPI: Remove deferred execution from global lock acquire wakeup path On acquiring the ACPI global lock, if there were sleepers on the lock, we used to use acpi_os_execute() to defer a thread which would signal sleepers. Now just signal the semaphore directly. http://bugzilla.kernel.org/show_bug.cgi?id=5534#c159 Signed-off-by: Len Brown --- drivers/acpi/events/evmisc.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index 6eef4efddcf6..ee2a10bf9077 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c @@ -342,20 +342,8 @@ static u32 acpi_ev_global_lock_handler(void *context) if (acquired) { /* Got the lock, now wake all threads waiting for it */ - acpi_gbl_global_lock_acquired = TRUE; - - /* Run the Global Lock thread which will signal all waiting threads */ - - status = - acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER, - acpi_ev_global_lock_thread, context); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "Could not queue Global Lock thread")); - - return (ACPI_INTERRUPT_NOT_HANDLED); - } + acpi_ev_global_lock_thread(context); } return (ACPI_INTERRUPT_HANDLED); From 37605a6900f6b4d886d995751fcfeef88c4e462c Mon Sep 17 00:00:00 2001 From: "Alexey Y. Starikovskiy" Date: Tue, 26 Sep 2006 04:20:47 -0400 Subject: [PATCH 2/2] ACPI: created a dedicated workqueue for notify() execution http://bugzilla.kernel.org/show_bug.cgi?id=5534#c160 Signed-off-by: Len Brown --- drivers/acpi/osl.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 068fe4f100b0..c84286cbbe25 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -73,6 +73,7 @@ static unsigned int acpi_irq_irq; static acpi_osd_handler acpi_irq_handler; static void *acpi_irq_context; static struct workqueue_struct *kacpid_wq; +static struct workqueue_struct *kacpi_notify_wq; acpi_status acpi_os_initialize(void) { @@ -91,8 +92,9 @@ acpi_status acpi_os_initialize1(void) return AE_NULL_ENTRY; } kacpid_wq = create_singlethread_workqueue("kacpid"); + kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); BUG_ON(!kacpid_wq); - + BUG_ON(!kacpi_notify_wq); return AE_OK; } @@ -104,6 +106,7 @@ acpi_status acpi_os_terminate(void) } destroy_workqueue(kacpid_wq); + destroy_workqueue(kacpi_notify_wq); return AE_OK; } @@ -566,10 +569,7 @@ void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */ static void acpi_os_execute_deferred(void *context) { - struct acpi_os_dpc *dpc = NULL; - - - dpc = (struct acpi_os_dpc *)context; + struct acpi_os_dpc *dpc = (struct acpi_os_dpc *)context; if (!dpc) { printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); return; @@ -604,14 +604,12 @@ acpi_status acpi_os_execute(acpi_execute_type type, struct acpi_os_dpc *dpc; struct work_struct *task; - ACPI_FUNCTION_TRACE("os_queue_for_execution"); - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Scheduling function [%p(%p)] for deferred execution.\n", function, context)); if (!function) - return_ACPI_STATUS(AE_BAD_PARAMETER); + return AE_BAD_PARAMETER; /* * Allocate/initialize DPC structure. Note that this memory will be @@ -624,26 +622,20 @@ acpi_status acpi_os_execute(acpi_execute_type type, * from the same memory. */ - dpc = - kmalloc(sizeof(struct acpi_os_dpc) + sizeof(struct work_struct), - GFP_ATOMIC); + dpc = kmalloc(sizeof(struct acpi_os_dpc) + + sizeof(struct work_struct), GFP_ATOMIC); if (!dpc) - return_ACPI_STATUS(AE_NO_MEMORY); - + return AE_NO_MEMORY; dpc->function = function; dpc->context = context; - task = (void *)(dpc + 1); INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc); - - if (!queue_work(kacpid_wq, task)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Call to queue_work() failed.\n")); - kfree(dpc); + if (!queue_work((type == OSL_NOTIFY_HANDLER)? + kacpi_notify_wq : kacpid_wq, task)) { status = AE_ERROR; + kfree(dpc); } - - return_ACPI_STATUS(status); + return status; } EXPORT_SYMBOL(acpi_os_execute);