Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 262a7a28 authored by Len Brown's avatar Len Brown
Browse files

Revert "ACPICA: fix AML mutex re-entrancy"



This reverts commit c0d127b5.

These changes to AML locking were made to allow
Notify handlers to be called on the stack
and not deadlock.  However, that scheme turns
out to be flawed and was reverted by the previous commit,
so this commit restores the locking to it previous design.

Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 40d07080
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -231,8 +231,10 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
		 * Obtain the method mutex if necessary. Do not acquire mutex for a
		 * recursive call.
		 */
		if (acpi_os_get_thread_id() !=
		    obj_desc->method.mutex->mutex.owner_thread_id) {
		if (!walk_state ||
		    !obj_desc->method.mutex->mutex.owner_thread ||
		    (walk_state->thread !=
		     obj_desc->method.mutex->mutex.owner_thread)) {
			/*
			 * Acquire the method mutex. This releases the interpreter if we
			 * block (and reacquires it before it returns)
@@ -246,14 +248,14 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
			}

			/* Update the mutex and walk info and save the original sync_level */
			obj_desc->method.mutex->mutex.owner_thread_id =
				acpi_os_get_thread_id();

			if (walk_state) {
				obj_desc->method.mutex->mutex.
				    original_sync_level =
				    walk_state->thread->current_sync_level;

				obj_desc->method.mutex->mutex.owner_thread =
				    walk_state->thread;
				walk_state->thread->current_sync_level =
				    obj_desc->method.sync_level;
			} else {
@@ -567,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_id = ACPI_MUTEX_NOT_ACQUIRED;
			method_desc->method.mutex->mutex.owner_thread = NULL;
		}
	}

+1 −1
Original line number Diff line number Diff line
@@ -134,7 +134,7 @@ static struct acpi_exdump_info acpi_ex_dump_method[8] = {
static struct acpi_exdump_info acpi_ex_dump_mutex[5] = {
	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL},
	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"},
	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread_id), "Owner Thread"},
	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"},
	{ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth),
	 "Acquire Depth"},
	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.os_mutex), "OsMutex"}
+20 −16
Original line number Diff line number Diff line
@@ -66,9 +66,10 @@ acpi_ex_link_mutex(union acpi_operand_object *obj_desc,
 *
 ******************************************************************************/

void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc,
			  struct acpi_thread_state *thread)
void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc)
{
	struct acpi_thread_state *thread = obj_desc->mutex.owner_thread;

	if (!thread) {
		return;
	}
@@ -173,7 +174,9 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,

	/* Support for multiple acquires by the owning thread */

	if (obj_desc->mutex.owner_thread_id == acpi_os_get_thread_id()) {
	if (obj_desc->mutex.owner_thread) {
		if (obj_desc->mutex.owner_thread->thread_id ==
		    walk_state->thread->thread_id) {
			/*
			 * The mutex is already owned by this thread, just increment the
			 * acquisition depth
@@ -181,6 +184,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
			obj_desc->mutex.acquisition_depth++;
			return_ACPI_STATUS(AE_OK);
		}
	}

	/* Acquire the mutex, wait if necessary. Special case for Global Lock */

@@ -202,7 +206,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,

	/* Have the mutex: update mutex and walk info and save the sync_level */

	obj_desc->mutex.owner_thread_id = acpi_os_get_thread_id();
	obj_desc->mutex.owner_thread = walk_state->thread;
	obj_desc->mutex.acquisition_depth = 1;
	obj_desc->mutex.original_sync_level =
	    walk_state->thread->current_sync_level;
@@ -242,7 +246,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,

	/* The mutex must have been previously acquired in order to release it */

	if (!obj_desc->mutex.owner_thread_id) {
	if (!obj_desc->mutex.owner_thread) {
		ACPI_ERROR((AE_INFO,
			    "Cannot release Mutex [%4.4s], not acquired",
			    acpi_ut_get_node_name(obj_desc->mutex.node)));
@@ -262,14 +266,14 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
	 * The Mutex is owned, but this thread must be the owner.
	 * Special case for Global Lock, any thread can release
	 */
	if ((obj_desc->mutex.owner_thread_id !=
	if ((obj_desc->mutex.owner_thread->thread_id !=
	     walk_state->thread->thread_id)
	    && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) {
		ACPI_ERROR((AE_INFO,
			    "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
			    (unsigned long)walk_state->thread->thread_id,
			    acpi_ut_get_node_name(obj_desc->mutex.node),
			    (unsigned long)obj_desc->mutex.owner_thread_id));
			    (unsigned long)obj_desc->mutex.owner_thread->thread_id));
		return_ACPI_STATUS(AE_AML_NOT_OWNER);
	}

@@ -296,7 +300,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,

	/* Unlink the mutex from the owner's list */

	acpi_ex_unlink_mutex(obj_desc, walk_state->thread);
	acpi_ex_unlink_mutex(obj_desc);

	/* Release the mutex, special case for Global Lock */

@@ -308,7 +312,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,

	/* Update the mutex and restore sync_level */

	obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;
	obj_desc->mutex.owner_thread = NULL;
	walk_state->thread->current_sync_level =
	    obj_desc->mutex.original_sync_level;

@@ -363,7 +367,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)

		/* Mark mutex unowned */

		obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;
		obj_desc->mutex.owner_thread = NULL;

		/* Update Thread sync_level (Last mutex is the important one) */

+1 −0
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
			acpi_os_delete_mutex(object->mutex.os_mutex);
			acpi_gbl_global_lock_mutex = NULL;
		} else {
			acpi_ex_unlink_mutex(object);
			acpi_os_delete_mutex(object->mutex.os_mutex);
		}
		break;
+1 −2
Original line number Diff line number Diff line
@@ -253,8 +253,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,

void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread);

void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc,
			  struct acpi_thread_state *thread);
void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc);

/*
 * exprep - ACPI AML execution - prep utilities
Loading