Skip to content

Commit

Permalink
ACPICA: Update for mutiple global lock acquisitions by same thread
Browse files Browse the repository at this point in the history
Allows AcpiAcquireGlobalLock external interface to be called
multiple times by the
 same thread. Allows use of AML fields that require the global
 lock while the running AML is already holding the global lock.

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
  • Loading branch information
Bob Moore authored and Len Brown committed Apr 22, 2008
1 parent f654ecb commit ba886cd
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 145 deletions.
12 changes: 6 additions & 6 deletions drivers/acpi/dispatcher/dsmethod.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
* recursive call.
*/
if (!walk_state ||
!obj_desc->method.mutex->mutex.owner_thread ||
(walk_state->thread !=
obj_desc->method.mutex->mutex.owner_thread)) {
!obj_desc->method.mutex->mutex.thread_id ||
(walk_state->thread->thread_id !=
obj_desc->method.mutex->mutex.thread_id)) {
/*
* Acquire the method mutex. This releases the interpreter if we
* block (and reacquires it before it returns)
Expand All @@ -254,8 +254,8 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
original_sync_level =
walk_state->thread->current_sync_level;

obj_desc->method.mutex->mutex.owner_thread =
walk_state->thread;
obj_desc->method.mutex->mutex.thread_id =
walk_state->thread->thread_id;
walk_state->thread->current_sync_level =
obj_desc->method.sync_level;
} else {
Expand Down Expand Up @@ -569,7 +569,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,

acpi_os_release_mutex(method_desc->method.mutex->mutex.
os_mutex);
method_desc->method.mutex->mutex.owner_thread = NULL;
method_desc->method.mutex->mutex.thread_id = 0;
}
}

Expand Down
11 changes: 6 additions & 5 deletions drivers/acpi/events/evmisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,8 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
* Only one thread can acquire the GL at a time, the global_lock_mutex
* enforces this. This interface releases the interpreter if we must wait.
*/
status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0);
status = acpi_ex_system_wait_mutex(
acpi_gbl_global_lock_mutex->mutex.os_mutex, 0);
if (status == AE_TIME) {
if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
acpi_ev_global_lock_acquired++;
Expand All @@ -448,9 +449,9 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
}

if (ACPI_FAILURE(status)) {
status =
acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex,
timeout);
status = acpi_ex_system_wait_mutex(
acpi_gbl_global_lock_mutex->mutex.os_mutex,
timeout);
}
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
Expand Down Expand Up @@ -555,7 +556,7 @@ acpi_status acpi_ev_release_global_lock(void)
/* Release the local GL mutex */
acpi_ev_global_lock_thread_id = NULL;
acpi_ev_global_lock_acquired = 0;
acpi_os_release_mutex(acpi_gbl_global_lock_mutex);
acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
return_ACPI_STATUS(status);
}

Expand Down
26 changes: 22 additions & 4 deletions drivers/acpi/events/evxface.c
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,12 @@ ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
*
* DESCRIPTION: Acquire the ACPI Global Lock
*
* Note: Allows callers with the same thread ID to acquire the global lock
* multiple times. In other words, externally, the behavior of the global lock
* is identical to an AML mutex. On the first acquire, a new handle is
* returned. On any subsequent calls to acquire by the same thread, the same
* handle is returned.
*
******************************************************************************/
acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
{
Expand All @@ -770,14 +776,26 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
/* Must lock interpreter to prevent race conditions */

acpi_ex_enter_interpreter();
status = acpi_ev_acquire_global_lock(timeout);
acpi_ex_exit_interpreter();

status = acpi_ex_acquire_mutex_object(timeout,
acpi_gbl_global_lock_mutex,
acpi_os_get_thread_id());

if (ACPI_SUCCESS(status)) {
acpi_gbl_global_lock_handle++;
/*
* If this was the first acquisition of the Global Lock by this thread,
* create a new handle. Otherwise, return the existing handle.
*/
if (acpi_gbl_global_lock_mutex->mutex.acquisition_depth == 1) {
acpi_gbl_global_lock_handle++;
}

/* Return the global lock handle */

*handle = acpi_gbl_global_lock_handle;
}

acpi_ex_exit_interpreter();
return (status);
}

Expand All @@ -802,7 +820,7 @@ acpi_status acpi_release_global_lock(u32 handle)
return (AE_NOT_ACQUIRED);
}

status = acpi_ev_release_global_lock();
status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
return (status);
}

Expand Down
24 changes: 8 additions & 16 deletions drivers/acpi/executer/exfield.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
union acpi_operand_object *buffer_desc;
acpi_size length;
void *buffer;
u8 locked;

ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc);

Expand Down Expand Up @@ -111,9 +110,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,

/* Lock entire transaction if requested */

locked =
acpi_ex_acquire_global_lock(obj_desc->common_field.
field_flags);
acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);

/*
* Perform the read.
Expand All @@ -125,7 +122,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
buffer.pointer),
ACPI_READ | (obj_desc->field.
attribute << 16));
acpi_ex_release_global_lock(locked);
acpi_ex_release_global_lock();
goto exit;
}

Expand Down Expand Up @@ -175,13 +172,12 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,

/* Lock entire transaction if requested */

locked =
acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);

/* Read from the field */

status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length);
acpi_ex_release_global_lock(locked);
acpi_ex_release_global_lock();

exit:
if (ACPI_FAILURE(status)) {
Expand Down Expand Up @@ -217,7 +213,6 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
u32 required_length;
void *buffer;
void *new_buffer;
u8 locked;
union acpi_operand_object *buffer_desc;

ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc);
Expand Down Expand Up @@ -278,9 +273,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,

/* Lock entire transaction if requested */

locked =
acpi_ex_acquire_global_lock(obj_desc->common_field.
field_flags);
acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);

/*
* Perform the write (returns status and perhaps data in the
Expand All @@ -291,7 +284,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
(acpi_integer *) buffer,
ACPI_WRITE | (obj_desc->field.
attribute << 16));
acpi_ex_release_global_lock(locked);
acpi_ex_release_global_lock();

*result_desc = buffer_desc;
return_ACPI_STATUS(status);
Expand Down Expand Up @@ -366,13 +359,12 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,

/* Lock entire transaction if requested */

locked =
acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);

/* Write to the field */

status = acpi_ex_insert_into_field(obj_desc, buffer, length);
acpi_ex_release_global_lock(locked);
acpi_ex_release_global_lock();

/* Free temporary buffer if we used one */

Expand Down
Loading

0 comments on commit ba886cd

Please sign in to comment.