forked from Minki/linux
Revert "ACPI: created a dedicated workqueue for notify() execution"
This reverts commit37605a6900
. Again. This same bug has now been introduced twice: it was done earlier by commitb8d35192c5
, only to be reverted last time in commit72945b2b90
. 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: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
808dbbb6bb
commit
b976fe19ac
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user