Commit b976fe19 authored by Linus Torvalds's avatar Linus Torvalds

Revert "ACPI: created a dedicated workqueue for notify() execution"

This reverts commit 37605a69.

Again.

This same bug has now been introduced twice: it was done earlier by
commit b8d35192, only to be reverted
last time in commit 72945b2b.

We must NOT try to queue up notify handlers to another thread than the
normal ACPI execution thread, because the notifications on some systems
seem to just keep on accumulating until we run out of memory and/or
threads.

Keeping events within the one deferred execution thread automatically
throttles the events properly.

At least the Compaq N620c will lock up completely on the first thermal
event without this patch reverted.

Cc: David Brownell <david-b@pacbell.net>
Cc: Len Brown <len.brown@intel.com>
Cc: Alexey Starikovskiy <alexey.y.starikovskiy@linux.intel.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 808dbbb6
......@@ -73,7 +73,6 @@ 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)
{
......@@ -92,9 +91,8 @@ 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;
}
......@@ -106,7 +104,6 @@ acpi_status acpi_os_terminate(void)
}
destroy_workqueue(kacpid_wq);
destroy_workqueue(kacpi_notify_wq);
return AE_OK;
}
......@@ -569,7 +566,10 @@ void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */
static void acpi_os_execute_deferred(void *context)
{
struct acpi_os_dpc *dpc = (struct acpi_os_dpc *)context;
struct acpi_os_dpc *dpc = NULL;
dpc = (struct acpi_os_dpc *)context;
if (!dpc) {
printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
return;
......@@ -604,12 +604,14 @@ 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 AE_BAD_PARAMETER;
return_ACPI_STATUS(AE_BAD_PARAMETER);
/*
* Allocate/initialize DPC structure. Note that this memory will be
......@@ -622,20 +624,26 @@ 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 AE_NO_MEMORY;
return_ACPI_STATUS(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((type == OSL_NOTIFY_HANDLER)?
kacpi_notify_wq : kacpid_wq, task)) {
status = AE_ERROR;
if (!queue_work(kacpid_wq, task)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Call to queue_work() failed.\n"));
kfree(dpc);
status = AE_ERROR;
}
return status;
return_ACPI_STATUS(status);
}
EXPORT_SYMBOL(acpi_os_execute);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment