* [PATCH 0/3] ACPI/ACPICA: Resolve spinlock and global lock handling code divergence
@ 2011-03-23 9:26 Lin Ming
2011-03-23 9:26 ` [PATCH 1/3] ACPI: osl, add acpi_os_create_lock interface Lin Ming
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Lin Ming @ 2011-03-23 9:26 UTC (permalink / raw)
To: Len Brown, Rafael J. Wysocki, Bob Moore; +Cc: linux-acpi
Currently, linux osl code does not implement the interface acpi_os_create_lock.
This series implements and uses it. So the spinlock code divergence is fixed.
Also, fix the code divergence introduced by commit
9cd0314(ACPI / ACPICA: Fix global lock acquisition).
[PATCH 1/3] ACPI: osl, add acpi_os_create_lock interface
[PATCH 2/3] ACPICA: Use acpi_os_create_lock interface
[PATCH 3/3] ACPICA: Fix code divergence of global lock handling
Thanks,
Lin Ming
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/3] ACPI: osl, add acpi_os_create_lock interface
2011-03-23 9:26 [PATCH 0/3] ACPI/ACPICA: Resolve spinlock and global lock handling code divergence Lin Ming
@ 2011-03-23 9:26 ` Lin Ming
2011-03-23 9:26 ` [PATCH 2/3] ACPICA: Use " Lin Ming
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Lin Ming @ 2011-03-23 9:26 UTC (permalink / raw)
To: Len Brown, Rafael J. Wysocki, Bob Moore; +Cc: linux-acpi
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
---
drivers/acpi/osl.c | 33 +++++++++++++++++++++++++--------
include/acpi/acpiosxf.h | 3 +++
2 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 45ad4ff..52ca964 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -902,14 +902,6 @@ void acpi_os_wait_events_complete(void *context)
EXPORT_SYMBOL(acpi_os_wait_events_complete);
-/*
- * Deallocate the memory for a spinlock.
- */
-void acpi_os_delete_lock(acpi_spinlock handle)
-{
- return;
-}
-
acpi_status
acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
{
@@ -1341,6 +1333,31 @@ int acpi_resources_are_enforced(void)
EXPORT_SYMBOL(acpi_resources_are_enforced);
/*
+ * Create and initialize a spinlock.
+ */
+acpi_status
+acpi_os_create_lock(acpi_spinlock *out_handle)
+{
+ spinlock_t *lock;
+
+ lock = ACPI_ALLOCATE(sizeof(spinlock_t));
+ if (!lock)
+ return AE_NO_MEMORY;
+ spin_lock_init(lock);
+ *out_handle = lock;
+
+ return AE_OK;
+}
+
+/*
+ * Deallocate the memory for a spinlock.
+ */
+void acpi_os_delete_lock(acpi_spinlock handle)
+{
+ ACPI_FREE(handle);
+}
+
+/*
* Acquire a spinlock.
*
* handle is a pointer to the spinlock_t.
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index a3252a5..a756bc8 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -98,6 +98,9 @@ acpi_os_table_override(struct acpi_table_header *existing_table,
/*
* Spinlock primitives
*/
+acpi_status
+acpi_os_create_lock(acpi_spinlock *out_handle);
+
void acpi_os_delete_lock(acpi_spinlock handle);
acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock handle);
--
1.7.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] ACPICA: Use acpi_os_create_lock interface
2011-03-23 9:26 [PATCH 0/3] ACPI/ACPICA: Resolve spinlock and global lock handling code divergence Lin Ming
2011-03-23 9:26 ` [PATCH 1/3] ACPI: osl, add acpi_os_create_lock interface Lin Ming
@ 2011-03-23 9:26 ` Lin Ming
2011-03-23 9:26 ` [PATCH 3/3] ACPICA: Fix code divergence of global lock handling Lin Ming
2011-03-25 8:38 ` [PATCH 0/3] ACPI/ACPICA: Resolve spinlock and global lock handling code divergence Len Brown
3 siblings, 0 replies; 7+ messages in thread
From: Lin Ming @ 2011-03-23 9:26 UTC (permalink / raw)
To: Len Brown, Rafael J. Wysocki, Bob Moore; +Cc: linux-acpi
Replace spin_lock_init with acpi_os_create_lock.
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
---
drivers/acpi/acpica/acglobal.h | 9 +++------
drivers/acpi/acpica/utmutex.c | 17 ++++++++++++++---
2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index d69750b..6d512fc 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -226,12 +226,9 @@ ACPI_EXTERN u8 acpi_gbl_global_lock_present;
* Spinlocks are used for interfaces that can be possibly called at
* interrupt level
*/
-ACPI_EXTERN spinlock_t _acpi_gbl_gpe_lock; /* For GPE data structs and registers */
-ACPI_EXTERN spinlock_t _acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */
-ACPI_EXTERN spinlock_t _acpi_ev_global_lock_pending_lock; /* For global lock */
-#define acpi_gbl_gpe_lock &_acpi_gbl_gpe_lock
-#define acpi_gbl_hardware_lock &_acpi_gbl_hardware_lock
-#define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock
+ACPI_EXTERN acpi_spinlock acpi_gbl_gpe_lock; /* For GPE data structs and registers */
+ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */
+ACPI_EXTERN acpi_spinlock acpi_ev_global_lock_pending_lock; /* For global lock */
/*****************************************************************************
*
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index a946c68..519d4ee 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -83,9 +83,20 @@ acpi_status acpi_ut_mutex_initialize(void)
/* Create the spinlocks for use at interrupt level */
- spin_lock_init(acpi_gbl_gpe_lock);
- spin_lock_init(acpi_gbl_hardware_lock);
- spin_lock_init(acpi_ev_global_lock_pending_lock);
+ status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ status = acpi_os_create_lock (&acpi_gbl_hardware_lock);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ status = acpi_os_create_lock (&acpi_ev_global_lock_pending_lock);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
/* Mutex for _OSI support */
status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
--
1.7.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3] ACPICA: Fix code divergence of global lock handling
2011-03-23 9:26 [PATCH 0/3] ACPI/ACPICA: Resolve spinlock and global lock handling code divergence Lin Ming
2011-03-23 9:26 ` [PATCH 1/3] ACPI: osl, add acpi_os_create_lock interface Lin Ming
2011-03-23 9:26 ` [PATCH 2/3] ACPICA: Use " Lin Ming
@ 2011-03-23 9:26 ` Lin Ming
2011-03-23 20:33 ` Rafael J. Wysocki
2011-03-25 8:38 ` [PATCH 0/3] ACPI/ACPICA: Resolve spinlock and global lock handling code divergence Len Brown
3 siblings, 1 reply; 7+ messages in thread
From: Lin Ming @ 2011-03-23 9:26 UTC (permalink / raw)
To: Len Brown, Rafael J. Wysocki, Bob Moore; +Cc: linux-acpi
Commit 9cd0314(ACPI / ACPICA: Fix global lock acquisition) was backported
into ACPICA code base, and some divergence was introduced.
This patch fixed it,
- rename acpi_ev_global_lock_pending/acpi_ev_global_lock_pending_lock
to acpi_gbl_global_lock_pending/acpi_gbl_global_lock_pending_lock.
- move the initialization of acpi_gbl_global_lock_pending_lock from
acpi_ut_mutex_initialize to acpi_ev_init_global_lock_handler.
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
---
drivers/acpi/acpica/acglobal.h | 6 ++-
drivers/acpi/acpica/evmisc.c | 74 +++++++++++++++++++++------------------
drivers/acpi/acpica/utmutex.c | 5 ---
3 files changed, 44 insertions(+), 41 deletions(-)
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 6d512fc..73863d8 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -214,13 +214,16 @@ ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX];
/*
* Global lock mutex is an actual AML mutex object
- * Global lock semaphore works in conjunction with the HW global lock
+ * Global lock semaphore works in conjunction with the actual global lock
+ * Global lock spinlock is used for "pending" handshake
*/
ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex;
ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore;
+ACPI_EXTERN acpi_spinlock acpi_gbl_global_lock_pending_lock;
ACPI_EXTERN u16 acpi_gbl_global_lock_handle;
ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
ACPI_EXTERN u8 acpi_gbl_global_lock_present;
+ACPI_EXTERN u8 acpi_gbl_global_lock_pending;
/*
* Spinlocks are used for interfaces that can be possibly called at
@@ -228,7 +231,6 @@ ACPI_EXTERN u8 acpi_gbl_global_lock_present;
*/
ACPI_EXTERN acpi_spinlock acpi_gbl_gpe_lock; /* For GPE data structs and registers */
ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */
-ACPI_EXTERN acpi_spinlock acpi_ev_global_lock_pending_lock; /* For global lock */
/*****************************************************************************
*
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c
index 7dc8094..69a3b4a 100644
--- a/drivers/acpi/acpica/evmisc.c
+++ b/drivers/acpi/acpica/evmisc.c
@@ -284,39 +284,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
* RETURN: ACPI_INTERRUPT_HANDLED
*
* DESCRIPTION: Invoked directly from the SCI handler when a global lock
- * release interrupt occurs. If there's a thread waiting for
- * the global lock, signal it.
- *
- * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
- * this is not possible for some reason, a separate thread will have to be
- * scheduled to do this.
+ * release interrupt occurs. If there is actually a pending
+ * request for the lock, signal the waiting thread.
*
******************************************************************************/
-static u8 acpi_ev_global_lock_pending;
static u32 acpi_ev_global_lock_handler(void *context)
{
acpi_status status;
acpi_cpu_flags flags;
- flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
+ flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
- if (!acpi_ev_global_lock_pending) {
- goto out;
+ /*
+ * If a request for the global lock is not actually pending,
+ * we are done. This handles "spurious" global lock interrupts
+ * which are possible (and have been seen) with bad BIOSs.
+ */
+ if (!acpi_gbl_global_lock_pending) {
+ goto cleanup_and_exit;
}
- /* Send a unit to the semaphore */
-
+ /*
+ * Send a unit to the global lock semaphore. The actual acquisition
+ * of the global lock will be performed by the waiting thread.
+ */
status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
}
- acpi_ev_global_lock_pending = FALSE;
+ acpi_gbl_global_lock_pending = FALSE;
- out:
- acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
+cleanup_and_exit:
+ acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
return (ACPI_INTERRUPT_HANDLED);
}
@@ -350,14 +352,20 @@ acpi_status acpi_ev_init_global_lock_handler(void)
* Map to AE_OK, but mark global lock as not present. Any attempt to
* actually use the global lock will be flagged with an error.
*/
+ acpi_gbl_global_lock_present = FALSE;
if (status == AE_NO_HARDWARE_RESPONSE) {
ACPI_ERROR((AE_INFO,
"No response from Global Lock hardware, disabling lock"));
- acpi_gbl_global_lock_present = FALSE;
return_ACPI_STATUS(AE_OK);
}
+ status = acpi_os_create_lock(&acpi_gbl_global_lock_pending_lock);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ acpi_gbl_global_lock_pending = FALSE;
acpi_gbl_global_lock_present = TRUE;
return_ACPI_STATUS(status);
}
@@ -414,7 +422,7 @@ static int acpi_ev_global_lock_acquired;
acpi_status acpi_ev_acquire_global_lock(u16 timeout)
{
acpi_cpu_flags flags;
- acpi_status status = AE_OK;
+ acpi_status status;
u8 acquired = FALSE;
ACPI_FUNCTION_TRACE(ev_acquire_global_lock);
@@ -458,15 +466,15 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
}
/*
- * Make sure that a global lock actually exists. If not, just treat the
- * lock as a standard mutex.
+ * Make sure that a global lock actually exists. If not, just
+ * treat the lock as a standard mutex.
*/
if (!acpi_gbl_global_lock_present) {
acpi_gbl_global_lock_acquired = TRUE;
return_ACPI_STATUS(AE_OK);
}
- flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
+ flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
do {
@@ -475,20 +483,19 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
if (acquired) {
acpi_gbl_global_lock_acquired = TRUE;
-
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Acquired hardware Global Lock\n"));
break;
}
- acpi_ev_global_lock_pending = TRUE;
-
- acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
-
/*
- * Did not get the lock. The pending bit was set above, and we
- * must wait until we get the global lock released interrupt.
+ * Did not get the lock. The pending bit was set above, and
+ * we must now wait until we receive the global lock
+ * released interrupt.
*/
+ acpi_gbl_global_lock_pending = TRUE;
+ acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
+
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Waiting for hardware Global Lock\n"));
@@ -496,17 +503,16 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
* Wait for handshake with the global lock interrupt handler.
* This interface releases the interpreter if we must wait.
*/
- status = acpi_ex_system_wait_semaphore(
- acpi_gbl_global_lock_semaphore,
- ACPI_WAIT_FOREVER);
+ status =
+ acpi_ex_system_wait_semaphore
+ (acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER);
- flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
+ flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
} while (ACPI_SUCCESS(status));
- acpi_ev_global_lock_pending = FALSE;
-
- acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
+ acpi_gbl_global_lock_pending = FALSE;
+ acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index 519d4ee..7d797e2 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -93,11 +93,6 @@ acpi_status acpi_ut_mutex_initialize(void)
return_ACPI_STATUS (status);
}
- status = acpi_os_create_lock (&acpi_ev_global_lock_pending_lock);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
-
/* Mutex for _OSI support */
status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
if (ACPI_FAILURE(status)) {
--
1.7.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] ACPICA: Fix code divergence of global lock handling
2011-03-23 9:26 ` [PATCH 3/3] ACPICA: Fix code divergence of global lock handling Lin Ming
@ 2011-03-23 20:33 ` Rafael J. Wysocki
2011-03-25 3:07 ` Lin Ming
0 siblings, 1 reply; 7+ messages in thread
From: Rafael J. Wysocki @ 2011-03-23 20:33 UTC (permalink / raw)
To: Lin Ming; +Cc: Len Brown, Bob Moore, linux-acpi
On Wednesday, March 23, 2011, Lin Ming wrote:
> Commit 9cd0314(ACPI / ACPICA: Fix global lock acquisition) was backported
> into ACPICA code base, and some divergence was introduced.
>
> This patch fixed it,
> - rename acpi_ev_global_lock_pending/acpi_ev_global_lock_pending_lock
> to acpi_gbl_global_lock_pending/acpi_gbl_global_lock_pending_lock.
>
> - move the initialization of acpi_gbl_global_lock_pending_lock from
> acpi_ut_mutex_initialize to acpi_ev_init_global_lock_handler.
>
> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
> ---
> drivers/acpi/acpica/acglobal.h | 6 ++-
> drivers/acpi/acpica/evmisc.c | 74 +++++++++++++++++++++------------------
> drivers/acpi/acpica/utmutex.c | 5 ---
> 3 files changed, 44 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
> index 6d512fc..73863d8 100644
> --- a/drivers/acpi/acpica/acglobal.h
> +++ b/drivers/acpi/acpica/acglobal.h
> @@ -214,13 +214,16 @@ ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX];
>
> /*
> * Global lock mutex is an actual AML mutex object
> - * Global lock semaphore works in conjunction with the HW global lock
> + * Global lock semaphore works in conjunction with the actual global lock
> + * Global lock spinlock is used for "pending" handshake
> */
> ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex;
> ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore;
> +ACPI_EXTERN acpi_spinlock acpi_gbl_global_lock_pending_lock;
> ACPI_EXTERN u16 acpi_gbl_global_lock_handle;
> ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
> ACPI_EXTERN u8 acpi_gbl_global_lock_present;
> +ACPI_EXTERN u8 acpi_gbl_global_lock_pending;
>
> /*
> * Spinlocks are used for interfaces that can be possibly called at
> @@ -228,7 +231,6 @@ ACPI_EXTERN u8 acpi_gbl_global_lock_present;
> */
> ACPI_EXTERN acpi_spinlock acpi_gbl_gpe_lock; /* For GPE data structs and registers */
> ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */
> -ACPI_EXTERN acpi_spinlock acpi_ev_global_lock_pending_lock; /* For global lock */
>
> /*****************************************************************************
> *
> diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c
> index 7dc8094..69a3b4a 100644
> --- a/drivers/acpi/acpica/evmisc.c
> +++ b/drivers/acpi/acpica/evmisc.c
> @@ -284,39 +284,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
> * RETURN: ACPI_INTERRUPT_HANDLED
> *
> * DESCRIPTION: Invoked directly from the SCI handler when a global lock
> - * release interrupt occurs. If there's a thread waiting for
> - * the global lock, signal it.
> - *
> - * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
> - * this is not possible for some reason, a separate thread will have to be
> - * scheduled to do this.
> + * release interrupt occurs. If there is actually a pending
> + * request for the lock, signal the waiting thread.
> *
> ******************************************************************************/
> -static u8 acpi_ev_global_lock_pending;
>
> static u32 acpi_ev_global_lock_handler(void *context)
> {
> acpi_status status;
> acpi_cpu_flags flags;
>
> - flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
> + flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
>
> - if (!acpi_ev_global_lock_pending) {
> - goto out;
> + /*
> + * If a request for the global lock is not actually pending,
> + * we are done. This handles "spurious" global lock interrupts
> + * which are possible (and have been seen) with bad BIOSs.
> + */
> + if (!acpi_gbl_global_lock_pending) {
> + goto cleanup_and_exit;
> }
>
> - /* Send a unit to the semaphore */
> -
> + /*
> + * Send a unit to the global lock semaphore. The actual acquisition
> + * of the global lock will be performed by the waiting thread.
> + */
> status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
> if (ACPI_FAILURE(status)) {
> ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
> }
>
> - acpi_ev_global_lock_pending = FALSE;
> + acpi_gbl_global_lock_pending = FALSE;
>
> - out:
> - acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
> +cleanup_and_exit:
>
> + acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
> return (ACPI_INTERRUPT_HANDLED);
> }
>
> @@ -350,14 +352,20 @@ acpi_status acpi_ev_init_global_lock_handler(void)
> * Map to AE_OK, but mark global lock as not present. Any attempt to
> * actually use the global lock will be flagged with an error.
> */
> + acpi_gbl_global_lock_present = FALSE;
> if (status == AE_NO_HARDWARE_RESPONSE) {
> ACPI_ERROR((AE_INFO,
> "No response from Global Lock hardware, disabling lock"));
>
> - acpi_gbl_global_lock_present = FALSE;
> return_ACPI_STATUS(AE_OK);
> }
>
> + status = acpi_os_create_lock(&acpi_gbl_global_lock_pending_lock);
> + if (ACPI_FAILURE(status)) {
> + return_ACPI_STATUS(status);
> + }
> +
> + acpi_gbl_global_lock_pending = FALSE;
> acpi_gbl_global_lock_present = TRUE;
> return_ACPI_STATUS(status);
> }
> @@ -414,7 +422,7 @@ static int acpi_ev_global_lock_acquired;
> acpi_status acpi_ev_acquire_global_lock(u16 timeout)
> {
> acpi_cpu_flags flags;
> - acpi_status status = AE_OK;
> + acpi_status status;
> u8 acquired = FALSE;
>
> ACPI_FUNCTION_TRACE(ev_acquire_global_lock);
> @@ -458,15 +466,15 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
> }
>
> /*
> - * Make sure that a global lock actually exists. If not, just treat the
> - * lock as a standard mutex.
> + * Make sure that a global lock actually exists. If not, just
> + * treat the lock as a standard mutex.
> */
> if (!acpi_gbl_global_lock_present) {
> acpi_gbl_global_lock_acquired = TRUE;
> return_ACPI_STATUS(AE_OK);
> }
>
> - flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
> + flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
>
> do {
>
> @@ -475,20 +483,19 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
> ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
> if (acquired) {
> acpi_gbl_global_lock_acquired = TRUE;
> -
> ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
> "Acquired hardware Global Lock\n"));
> break;
> }
>
> - acpi_ev_global_lock_pending = TRUE;
> -
> - acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
> -
> /*
> - * Did not get the lock. The pending bit was set above, and we
> - * must wait until we get the global lock released interrupt.
> + * Did not get the lock. The pending bit was set above, and
> + * we must now wait until we receive the global lock
> + * released interrupt.
> */
> + acpi_gbl_global_lock_pending = TRUE;
> + acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
> +
> ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
> "Waiting for hardware Global Lock\n"));
>
> @@ -496,17 +503,16 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
> * Wait for handshake with the global lock interrupt handler.
> * This interface releases the interpreter if we must wait.
> */
> - status = acpi_ex_system_wait_semaphore(
> - acpi_gbl_global_lock_semaphore,
> - ACPI_WAIT_FOREVER);
> + status =
> + acpi_ex_system_wait_semaphore
> + (acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER);
>
> - flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
> + flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
>
> } while (ACPI_SUCCESS(status));
>
> - acpi_ev_global_lock_pending = FALSE;
> -
> - acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
> + acpi_gbl_global_lock_pending = FALSE;
> + acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
>
> return_ACPI_STATUS(status);
> }
> diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
> index 519d4ee..7d797e2 100644
> --- a/drivers/acpi/acpica/utmutex.c
> +++ b/drivers/acpi/acpica/utmutex.c
> @@ -93,11 +93,6 @@ acpi_status acpi_ut_mutex_initialize(void)
> return_ACPI_STATUS (status);
> }
>
> - status = acpi_os_create_lock (&acpi_ev_global_lock_pending_lock);
> - if (ACPI_FAILURE (status)) {
> - return_ACPI_STATUS (status);
> - }
> -
> /* Mutex for _OSI support */
> status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
> if (ACPI_FAILURE(status)) {
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] ACPICA: Fix code divergence of global lock handling
2011-03-23 20:33 ` Rafael J. Wysocki
@ 2011-03-25 3:07 ` Lin Ming
0 siblings, 0 replies; 7+ messages in thread
From: Lin Ming @ 2011-03-25 3:07 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: Lin Ming, Len Brown, Bob Moore, linux-acpi
2011/3/24 Rafael J. Wysocki <rjw@sisk.pl>:
> On Wednesday, March 23, 2011, Lin Ming wrote:
>> Commit 9cd0314(ACPI / ACPICA: Fix global lock acquisition) was backported
>> into ACPICA code base, and some divergence was introduced.
>>
>> This patch fixed it,
>> - rename acpi_ev_global_lock_pending/acpi_ev_global_lock_pending_lock
>> to acpi_gbl_global_lock_pending/acpi_gbl_global_lock_pending_lock.
>>
>> - move the initialization of acpi_gbl_global_lock_pending_lock from
>> acpi_ut_mutex_initialize to acpi_ev_init_global_lock_handler.
>>
>> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
>
> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
Len,
Could you consider applying these patches for 2.6.39-rc1?
Thanks,
Lin Ming
>
>> ---
>> drivers/acpi/acpica/acglobal.h | 6 ++-
>> drivers/acpi/acpica/evmisc.c | 74 +++++++++++++++++++++------------------
>> drivers/acpi/acpica/utmutex.c | 5 ---
>> 3 files changed, 44 insertions(+), 41 deletions(-)
>>
>> diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
>> index 6d512fc..73863d8 100644
>> --- a/drivers/acpi/acpica/acglobal.h
>> +++ b/drivers/acpi/acpica/acglobal.h
>> @@ -214,13 +214,16 @@ ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX];
>>
>> /*
>> * Global lock mutex is an actual AML mutex object
>> - * Global lock semaphore works in conjunction with the HW global lock
>> + * Global lock semaphore works in conjunction with the actual global lock
>> + * Global lock spinlock is used for "pending" handshake
>> */
>> ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex;
>> ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore;
>> +ACPI_EXTERN acpi_spinlock acpi_gbl_global_lock_pending_lock;
>> ACPI_EXTERN u16 acpi_gbl_global_lock_handle;
>> ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
>> ACPI_EXTERN u8 acpi_gbl_global_lock_present;
>> +ACPI_EXTERN u8 acpi_gbl_global_lock_pending;
>>
>> /*
>> * Spinlocks are used for interfaces that can be possibly called at
>> @@ -228,7 +231,6 @@ ACPI_EXTERN u8 acpi_gbl_global_lock_present;
>> */
>> ACPI_EXTERN acpi_spinlock acpi_gbl_gpe_lock; /* For GPE data structs and registers */
>> ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */
>> -ACPI_EXTERN acpi_spinlock acpi_ev_global_lock_pending_lock; /* For global lock */
>>
>> /*****************************************************************************
>> *
>> diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c
>> index 7dc8094..69a3b4a 100644
>> --- a/drivers/acpi/acpica/evmisc.c
>> +++ b/drivers/acpi/acpica/evmisc.c
>> @@ -284,39 +284,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
>> * RETURN: ACPI_INTERRUPT_HANDLED
>> *
>> * DESCRIPTION: Invoked directly from the SCI handler when a global lock
>> - * release interrupt occurs. If there's a thread waiting for
>> - * the global lock, signal it.
>> - *
>> - * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
>> - * this is not possible for some reason, a separate thread will have to be
>> - * scheduled to do this.
>> + * release interrupt occurs. If there is actually a pending
>> + * request for the lock, signal the waiting thread.
>> *
>> ******************************************************************************/
>> -static u8 acpi_ev_global_lock_pending;
>>
>> static u32 acpi_ev_global_lock_handler(void *context)
>> {
>> acpi_status status;
>> acpi_cpu_flags flags;
>>
>> - flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
>> + flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
>>
>> - if (!acpi_ev_global_lock_pending) {
>> - goto out;
>> + /*
>> + * If a request for the global lock is not actually pending,
>> + * we are done. This handles "spurious" global lock interrupts
>> + * which are possible (and have been seen) with bad BIOSs.
>> + */
>> + if (!acpi_gbl_global_lock_pending) {
>> + goto cleanup_and_exit;
>> }
>>
>> - /* Send a unit to the semaphore */
>> -
>> + /*
>> + * Send a unit to the global lock semaphore. The actual acquisition
>> + * of the global lock will be performed by the waiting thread.
>> + */
>> status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
>> if (ACPI_FAILURE(status)) {
>> ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
>> }
>>
>> - acpi_ev_global_lock_pending = FALSE;
>> + acpi_gbl_global_lock_pending = FALSE;
>>
>> - out:
>> - acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
>> +cleanup_and_exit:
>>
>> + acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
>> return (ACPI_INTERRUPT_HANDLED);
>> }
>>
>> @@ -350,14 +352,20 @@ acpi_status acpi_ev_init_global_lock_handler(void)
>> * Map to AE_OK, but mark global lock as not present. Any attempt to
>> * actually use the global lock will be flagged with an error.
>> */
>> + acpi_gbl_global_lock_present = FALSE;
>> if (status == AE_NO_HARDWARE_RESPONSE) {
>> ACPI_ERROR((AE_INFO,
>> "No response from Global Lock hardware, disabling lock"));
>>
>> - acpi_gbl_global_lock_present = FALSE;
>> return_ACPI_STATUS(AE_OK);
>> }
>>
>> + status = acpi_os_create_lock(&acpi_gbl_global_lock_pending_lock);
>> + if (ACPI_FAILURE(status)) {
>> + return_ACPI_STATUS(status);
>> + }
>> +
>> + acpi_gbl_global_lock_pending = FALSE;
>> acpi_gbl_global_lock_present = TRUE;
>> return_ACPI_STATUS(status);
>> }
>> @@ -414,7 +422,7 @@ static int acpi_ev_global_lock_acquired;
>> acpi_status acpi_ev_acquire_global_lock(u16 timeout)
>> {
>> acpi_cpu_flags flags;
>> - acpi_status status = AE_OK;
>> + acpi_status status;
>> u8 acquired = FALSE;
>>
>> ACPI_FUNCTION_TRACE(ev_acquire_global_lock);
>> @@ -458,15 +466,15 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
>> }
>>
>> /*
>> - * Make sure that a global lock actually exists. If not, just treat the
>> - * lock as a standard mutex.
>> + * Make sure that a global lock actually exists. If not, just
>> + * treat the lock as a standard mutex.
>> */
>> if (!acpi_gbl_global_lock_present) {
>> acpi_gbl_global_lock_acquired = TRUE;
>> return_ACPI_STATUS(AE_OK);
>> }
>>
>> - flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
>> + flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
>>
>> do {
>>
>> @@ -475,20 +483,19 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
>> ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
>> if (acquired) {
>> acpi_gbl_global_lock_acquired = TRUE;
>> -
>> ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
>> "Acquired hardware Global Lock\n"));
>> break;
>> }
>>
>> - acpi_ev_global_lock_pending = TRUE;
>> -
>> - acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
>> -
>> /*
>> - * Did not get the lock. The pending bit was set above, and we
>> - * must wait until we get the global lock released interrupt.
>> + * Did not get the lock. The pending bit was set above, and
>> + * we must now wait until we receive the global lock
>> + * released interrupt.
>> */
>> + acpi_gbl_global_lock_pending = TRUE;
>> + acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
>> +
>> ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
>> "Waiting for hardware Global Lock\n"));
>>
>> @@ -496,17 +503,16 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
>> * Wait for handshake with the global lock interrupt handler.
>> * This interface releases the interpreter if we must wait.
>> */
>> - status = acpi_ex_system_wait_semaphore(
>> - acpi_gbl_global_lock_semaphore,
>> - ACPI_WAIT_FOREVER);
>> + status =
>> + acpi_ex_system_wait_semaphore
>> + (acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER);
>>
>> - flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
>> + flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
>>
>> } while (ACPI_SUCCESS(status));
>>
>> - acpi_ev_global_lock_pending = FALSE;
>> -
>> - acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
>> + acpi_gbl_global_lock_pending = FALSE;
>> + acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
>>
>> return_ACPI_STATUS(status);
>> }
>> diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
>> index 519d4ee..7d797e2 100644
>> --- a/drivers/acpi/acpica/utmutex.c
>> +++ b/drivers/acpi/acpica/utmutex.c
>> @@ -93,11 +93,6 @@ acpi_status acpi_ut_mutex_initialize(void)
>> return_ACPI_STATUS (status);
>> }
>>
>> - status = acpi_os_create_lock (&acpi_ev_global_lock_pending_lock);
>> - if (ACPI_FAILURE (status)) {
>> - return_ACPI_STATUS (status);
>> - }
>> -
>> /* Mutex for _OSI support */
>> status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
>> if (ACPI_FAILURE(status)) {
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] ACPI/ACPICA: Resolve spinlock and global lock handling code divergence
2011-03-23 9:26 [PATCH 0/3] ACPI/ACPICA: Resolve spinlock and global lock handling code divergence Lin Ming
` (2 preceding siblings ...)
2011-03-23 9:26 ` [PATCH 3/3] ACPICA: Fix code divergence of global lock handling Lin Ming
@ 2011-03-25 8:38 ` Len Brown
3 siblings, 0 replies; 7+ messages in thread
From: Len Brown @ 2011-03-25 8:38 UTC (permalink / raw)
To: Lin Ming; +Cc: Rafael J. Wysocki, Bob Moore, linux-acpi
series applied to acpica branch and acpi-test
thanks,
Len Brown, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2011-03-25 8:38 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-23 9:26 [PATCH 0/3] ACPI/ACPICA: Resolve spinlock and global lock handling code divergence Lin Ming
2011-03-23 9:26 ` [PATCH 1/3] ACPI: osl, add acpi_os_create_lock interface Lin Ming
2011-03-23 9:26 ` [PATCH 2/3] ACPICA: Use " Lin Ming
2011-03-23 9:26 ` [PATCH 3/3] ACPICA: Fix code divergence of global lock handling Lin Ming
2011-03-23 20:33 ` Rafael J. Wysocki
2011-03-25 3:07 ` Lin Ming
2011-03-25 8:38 ` [PATCH 0/3] ACPI/ACPICA: Resolve spinlock and global lock handling code divergence Len Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).