Implicit notify: ensure no memory allocation within critical region.

This fix moves a memory allocation outside of the time that a
spinlock is held. Fixes issues on systems that do not allow
this behavior. Jung-uk Kim.
This commit is contained in:
Robert Moore 2012-06-27 12:01:05 -07:00
parent c725de3b1c
commit 2d8e07c517

View File

@ -371,6 +371,7 @@ AcpiSetupGpeForWake (
ACPI_GPE_EVENT_INFO *GpeEventInfo;
ACPI_NAMESPACE_NODE *DeviceNode;
ACPI_GPE_NOTIFY_INFO *Notify;
ACPI_GPE_NOTIFY_INFO *NewNotify;
ACPI_CPU_FLAGS Flags;
@ -406,6 +407,17 @@ AcpiSetupGpeForWake (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
* Allocate a new notify object up front, in case it is needed.
* Memory allocation while holding a spinlock is a big no-no
* on some hosts.
*/
NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
if (!NewNotify)
{
return_ACPI_STATUS (AE_NO_MEMORY);
}
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Ensure that we have a valid GPE number */
@ -456,16 +468,10 @@ AcpiSetupGpeForWake (
/* Add this device to the notify list for this GPE */
Notify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
if (!Notify)
{
Status = AE_NO_MEMORY;
goto UnlockAndExit;
}
Notify->DeviceNode = DeviceNode;
Notify->Next = GpeEventInfo->Dispatch.NotifyList;
GpeEventInfo->Dispatch.NotifyList = Notify;
NewNotify->DeviceNode = DeviceNode;
NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
GpeEventInfo->Dispatch.NotifyList = NewNotify;
NewNotify = NULL;
}
/* Mark the GPE as a possible wake event */
@ -473,8 +479,16 @@ AcpiSetupGpeForWake (
GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
Status = AE_OK;
UnlockAndExit:
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
/* Delete the notify object if it was not used above */
if (NewNotify)
{
ACPI_FREE (NewNotify);
}
return_ACPI_STATUS (Status);
}