Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Revert "ACPICA: fix AML mutex re-entrancy"

This reverts commit c0d127b56937c3e72c2b1819161d2f6718eee877.

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: Len Brown <len.brown@intel.com>

Len Brown 262a7a28 40d07080

+31 -25
+7 -5
drivers/acpi/dispatcher/dsmethod.c
··· 231 231 * Obtain the method mutex if necessary. Do not acquire mutex for a 232 232 * recursive call. 233 233 */ 234 - if (acpi_os_get_thread_id() != 235 - obj_desc->method.mutex->mutex.owner_thread_id) { 234 + if (!walk_state || 235 + !obj_desc->method.mutex->mutex.owner_thread || 236 + (walk_state->thread != 237 + obj_desc->method.mutex->mutex.owner_thread)) { 236 238 /* 237 239 * Acquire the method mutex. This releases the interpreter if we 238 240 * block (and reacquires it before it returns) ··· 248 246 } 249 247 250 248 /* Update the mutex and walk info and save the original sync_level */ 251 - obj_desc->method.mutex->mutex.owner_thread_id = 252 - acpi_os_get_thread_id(); 253 249 254 250 if (walk_state) { 255 251 obj_desc->method.mutex->mutex. 256 252 original_sync_level = 257 253 walk_state->thread->current_sync_level; 258 254 255 + obj_desc->method.mutex->mutex.owner_thread = 256 + walk_state->thread; 259 257 walk_state->thread->current_sync_level = 260 258 obj_desc->method.sync_level; 261 259 } else { ··· 569 567 570 568 acpi_os_release_mutex(method_desc->method.mutex->mutex. 571 569 os_mutex); 572 - method_desc->method.mutex->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED; 570 + method_desc->method.mutex->mutex.owner_thread = NULL; 573 571 } 574 572 } 575 573
+1 -1
drivers/acpi/executer/exdump.c
··· 134 134 static struct acpi_exdump_info acpi_ex_dump_mutex[5] = { 135 135 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, 136 136 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, 137 - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread_id), "Owner Thread"}, 137 + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, 138 138 {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), 139 139 "Acquire Depth"}, 140 140 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.os_mutex), "OsMutex"}
+20 -16
drivers/acpi/executer/exmutex.c
··· 66 66 * 67 67 ******************************************************************************/ 68 68 69 - void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc, 70 - struct acpi_thread_state *thread) 69 + void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc) 71 70 { 71 + struct acpi_thread_state *thread = obj_desc->mutex.owner_thread; 72 + 72 73 if (!thread) { 73 74 return; 74 75 } ··· 174 173 175 174 /* Support for multiple acquires by the owning thread */ 176 175 177 - if (obj_desc->mutex.owner_thread_id == acpi_os_get_thread_id()) { 178 - /* 179 - * The mutex is already owned by this thread, just increment the 180 - * acquisition depth 181 - */ 182 - obj_desc->mutex.acquisition_depth++; 183 - return_ACPI_STATUS(AE_OK); 176 + if (obj_desc->mutex.owner_thread) { 177 + if (obj_desc->mutex.owner_thread->thread_id == 178 + walk_state->thread->thread_id) { 179 + /* 180 + * The mutex is already owned by this thread, just increment the 181 + * acquisition depth 182 + */ 183 + obj_desc->mutex.acquisition_depth++; 184 + return_ACPI_STATUS(AE_OK); 185 + } 184 186 } 185 187 186 188 /* Acquire the mutex, wait if necessary. Special case for Global Lock */ ··· 206 202 207 203 /* Have the mutex: update mutex and walk info and save the sync_level */ 208 204 209 - obj_desc->mutex.owner_thread_id = acpi_os_get_thread_id(); 205 + obj_desc->mutex.owner_thread = walk_state->thread; 210 206 obj_desc->mutex.acquisition_depth = 1; 211 207 obj_desc->mutex.original_sync_level = 212 208 walk_state->thread->current_sync_level; ··· 246 242 247 243 /* The mutex must have been previously acquired in order to release it */ 248 244 249 - if (!obj_desc->mutex.owner_thread_id) { 245 + if (!obj_desc->mutex.owner_thread) { 250 246 ACPI_ERROR((AE_INFO, 251 247 "Cannot release Mutex [%4.4s], not acquired", 252 248 acpi_ut_get_node_name(obj_desc->mutex.node))); ··· 266 262 * The Mutex is owned, but this thread must be the owner. 267 263 * Special case for Global Lock, any thread can release 268 264 */ 269 - if ((obj_desc->mutex.owner_thread_id != 265 + if ((obj_desc->mutex.owner_thread->thread_id != 270 266 walk_state->thread->thread_id) 271 267 && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) { 272 268 ACPI_ERROR((AE_INFO, 273 269 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", 274 270 (unsigned long)walk_state->thread->thread_id, 275 271 acpi_ut_get_node_name(obj_desc->mutex.node), 276 - (unsigned long)obj_desc->mutex.owner_thread_id)); 272 + (unsigned long)obj_desc->mutex.owner_thread->thread_id)); 277 273 return_ACPI_STATUS(AE_AML_NOT_OWNER); 278 274 } 279 275 ··· 300 296 301 297 /* Unlink the mutex from the owner's list */ 302 298 303 - acpi_ex_unlink_mutex(obj_desc, walk_state->thread); 299 + acpi_ex_unlink_mutex(obj_desc); 304 300 305 301 /* Release the mutex, special case for Global Lock */ 306 302 ··· 312 308 313 309 /* Update the mutex and restore sync_level */ 314 310 315 - obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED; 311 + obj_desc->mutex.owner_thread = NULL; 316 312 walk_state->thread->current_sync_level = 317 313 obj_desc->mutex.original_sync_level; 318 314 ··· 367 363 368 364 /* Mark mutex unowned */ 369 365 370 - obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED; 366 + obj_desc->mutex.owner_thread = NULL; 371 367 372 368 /* Update Thread sync_level (Last mutex is the important one) */ 373 369
+1
drivers/acpi/utilities/utdelete.c
··· 170 170 acpi_os_delete_mutex(object->mutex.os_mutex); 171 171 acpi_gbl_global_lock_mutex = NULL; 172 172 } else { 173 + acpi_ex_unlink_mutex(object); 173 174 acpi_os_delete_mutex(object->mutex.os_mutex); 174 175 } 175 176 break;
+1 -2
include/acpi/acinterp.h
··· 253 253 254 254 void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread); 255 255 256 - void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc, 257 - struct acpi_thread_state *thread); 256 + void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc); 258 257 259 258 /* 260 259 * exprep - ACPI AML execution - prep utilities
+1 -1
include/acpi/acobject.h
··· 155 155 struct acpi_object_mutex { 156 156 ACPI_OBJECT_COMMON_HEADER u8 sync_level; /* 0-15, specified in Mutex() call */ 157 157 u16 acquisition_depth; /* Allow multiple Acquires, same thread */ 158 - acpi_thread_id owner_thread_id; /* Current owner of the mutex */ 158 + struct acpi_thread_state *owner_thread; /* Current owner of the mutex */ 159 159 acpi_mutex os_mutex; /* Actual OS synchronization object */ 160 160 union acpi_operand_object *prev; /* Link for list of acquired mutexes */ 161 161 union acpi_operand_object *next; /* Link for list of acquired mutexes */