Skip to content

Commit

Permalink
Revert "ACPI: created a dedicated workqueue for notify() execution"
Browse files Browse the repository at this point in the history
This reverts commit 37605a6.

Again.

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

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 <[email protected]>
Cc: Len Brown <[email protected]>
Cc: Alexey Starikovskiy <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Linus Torvalds committed Nov 18, 2006
1 parent 808dbbb commit b976fe1
Showing 1 changed file with 21 additions and 13 deletions.
34 changes: 21 additions & 13 deletions drivers/acpi/osl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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;
}

Expand All @@ -106,7 +104,6 @@ acpi_status acpi_os_terminate(void)
}

destroy_workqueue(kacpid_wq);
destroy_workqueue(kacpi_notify_wq);

return AE_OK;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down

0 comments on commit b976fe1

Please sign in to comment.