···231231 * Obtain the method mutex if necessary. Do not acquire mutex for a232232 * recursive call.233233 */234234- if (acpi_os_get_thread_id() !=235235- obj_desc->method.mutex->mutex.owner_thread_id) {234234+ if (!walk_state ||235235+ !obj_desc->method.mutex->mutex.owner_thread ||236236+ (walk_state->thread !=237237+ obj_desc->method.mutex->mutex.owner_thread)) {236238 /*237239 * Acquire the method mutex. This releases the interpreter if we238240 * block (and reacquires it before it returns)···248246 }249247250248 /* Update the mutex and walk info and save the original sync_level */251251- obj_desc->method.mutex->mutex.owner_thread_id =252252- acpi_os_get_thread_id();253249254250 if (walk_state) {255251 obj_desc->method.mutex->mutex.256252 original_sync_level =257253 walk_state->thread->current_sync_level;258254255255+ obj_desc->method.mutex->mutex.owner_thread =256256+ walk_state->thread;259257 walk_state->thread->current_sync_level =260258 obj_desc->method.sync_level;261259 } else {···569567570568 acpi_os_release_mutex(method_desc->method.mutex->mutex.571569 os_mutex);572572- method_desc->method.mutex->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;570570+ method_desc->method.mutex->mutex.owner_thread = NULL;573571 }574572 }575573
+4-7
drivers/acpi/events/evmisc.c
···196196 notify_info->notify.value = (u16) notify_value;197197 notify_info->notify.handler_obj = handler_obj;198198199199- acpi_ex_exit_interpreter();200200-201201- acpi_ev_notify_dispatch(notify_info);202202-203203- status = acpi_ex_enter_interpreter();199199+ status =200200+ acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch,201201+ notify_info);204202 if (ACPI_FAILURE(status)) {205205- return_ACPI_STATUS(status);203203+ acpi_ut_delete_generic_state(notify_info);206204 }207207-208205 }209206210207 if (!handler_obj) {
+4-11
drivers/acpi/events/evregion.c
···291291 u32 bit_width, acpi_integer * value)292292{293293 acpi_status status;294294- acpi_status status2;295294 acpi_adr_space_handler handler;296295 acpi_adr_space_setup region_setup;297296 union acpi_operand_object *handler_desc;···344345 * setup will potentially execute control methods345346 * (e.g., _REG method for this region)346347 */347347- acpi_ex_exit_interpreter();348348+ acpi_ex_relinquish_interpreter();348349349350 status = region_setup(region_obj, ACPI_REGION_ACTIVATE,350351 handler_desc->address_space.context,···352353353354 /* Re-enter the interpreter */354355355355- status2 = acpi_ex_enter_interpreter();356356- if (ACPI_FAILURE(status2)) {357357- return_ACPI_STATUS(status2);358358- }356356+ acpi_ex_reacquire_interpreter();359357360358 /* Check for failure of the Region Setup */361359···405409 * exit the interpreter because the handler *might* block -- we don't406410 * know what it will do, so we can't hold the lock on the intepreter.407411 */408408- acpi_ex_exit_interpreter();412412+ acpi_ex_relinquish_interpreter();409413 }410414411415 /* Call the handler */···426430 * We just returned from a non-default handler, we must re-enter the427431 * interpreter428432 */429429- status2 = acpi_ex_enter_interpreter();430430- if (ACPI_FAILURE(status2)) {431431- return_ACPI_STATUS(status2);432432- }433433+ acpi_ex_reacquire_interpreter();433434 }434435435436 return_ACPI_STATUS(status);
+2-4
drivers/acpi/events/evxface.c
···768768 return (AE_BAD_PARAMETER);769769 }770770771771- status = acpi_ex_enter_interpreter();772772- if (ACPI_FAILURE(status)) {773773- return (status);774774- }771771+ /* Must lock interpreter to prevent race conditions */775772773773+ acpi_ex_enter_interpreter();776774 status = acpi_ev_acquire_global_lock(timeout);777775 acpi_ex_exit_interpreter();778776
+1-4
drivers/acpi/executer/excreate.c
···583583 * Get the sync_level. If method is serialized, a mutex will be584584 * created for this method when it is parsed.585585 */586586- if (acpi_gbl_all_methods_serialized) {587587- obj_desc->method.sync_level = 0;588588- obj_desc->method.method_flags |= AML_METHOD_SERIALIZED;589589- } else if (method_flags & AML_METHOD_SERIALIZED) {586586+ if (method_flags & AML_METHOD_SERIALIZED) {590587 /*591588 * ACPI 1.0: sync_level = 0592589 * ACPI 2.0: sync_level = sync_level in method declaration
···6666 *6767 ******************************************************************************/68686969-void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc,7070- struct acpi_thread_state *thread)6969+void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc)7170{7171+ struct acpi_thread_state *thread = obj_desc->mutex.owner_thread;7272+7273 if (!thread) {7374 return;7475 }···174173175174 /* Support for multiple acquires by the owning thread */176175177177- if (obj_desc->mutex.owner_thread_id == acpi_os_get_thread_id()) {178178- /*179179- * The mutex is already owned by this thread, just increment the180180- * acquisition depth181181- */182182- obj_desc->mutex.acquisition_depth++;183183- return_ACPI_STATUS(AE_OK);176176+ if (obj_desc->mutex.owner_thread) {177177+ if (obj_desc->mutex.owner_thread->thread_id ==178178+ walk_state->thread->thread_id) {179179+ /*180180+ * The mutex is already owned by this thread, just increment the181181+ * acquisition depth182182+ */183183+ obj_desc->mutex.acquisition_depth++;184184+ return_ACPI_STATUS(AE_OK);185185+ }184186 }185187186188 /* Acquire the mutex, wait if necessary. Special case for Global Lock */···206202207203 /* Have the mutex: update mutex and walk info and save the sync_level */208204209209- obj_desc->mutex.owner_thread_id = acpi_os_get_thread_id();205205+ obj_desc->mutex.owner_thread = walk_state->thread;210206 obj_desc->mutex.acquisition_depth = 1;211207 obj_desc->mutex.original_sync_level =212208 walk_state->thread->current_sync_level;···246242247243 /* The mutex must have been previously acquired in order to release it */248244249249- if (!obj_desc->mutex.owner_thread_id) {245245+ if (!obj_desc->mutex.owner_thread) {250246 ACPI_ERROR((AE_INFO,251247 "Cannot release Mutex [%4.4s], not acquired",252248 acpi_ut_get_node_name(obj_desc->mutex.node)));···266262 * The Mutex is owned, but this thread must be the owner.267263 * Special case for Global Lock, any thread can release268264 */269269- if ((obj_desc->mutex.owner_thread_id !=265265+ if ((obj_desc->mutex.owner_thread->thread_id !=270266 walk_state->thread->thread_id)271267 && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) {272268 ACPI_ERROR((AE_INFO,273269 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",274270 (unsigned long)walk_state->thread->thread_id,275271 acpi_ut_get_node_name(obj_desc->mutex.node),276276- (unsigned long)obj_desc->mutex.owner_thread_id));272272+ (unsigned long)obj_desc->mutex.owner_thread->thread_id));277273 return_ACPI_STATUS(AE_AML_NOT_OWNER);278274 }279275···300296301297 /* Unlink the mutex from the owner's list */302298303303- acpi_ex_unlink_mutex(obj_desc, walk_state->thread);299299+ acpi_ex_unlink_mutex(obj_desc);304300305301 /* Release the mutex, special case for Global Lock */306302···312308313309 /* Update the mutex and restore sync_level */314310315315- obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;311311+ obj_desc->mutex.owner_thread = NULL;316312 walk_state->thread->current_sync_level =317313 obj_desc->mutex.original_sync_level;318314···367363368364 /* Mark mutex unowned */369365370370- obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;366366+ obj_desc->mutex.owner_thread = NULL;371367372368 /* Update Thread sync_level (Last mutex is the important one) */373369
+7-23
drivers/acpi/executer/exsystem.c
···6666acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)6767{6868 acpi_status status;6969- acpi_status status2;70697170 ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);7271···78797980 /* We must wait, so unlock the interpreter */80818181- acpi_ex_exit_interpreter();8282+ acpi_ex_relinquish_interpreter();82838384 status = acpi_os_wait_semaphore(semaphore, 1, timeout);8485···88898990 /* Reacquire the interpreter */90919191- status2 = acpi_ex_enter_interpreter();9292- if (ACPI_FAILURE(status2)) {9393-9494- /* Report fatal error, could not acquire interpreter */9595-9696- return_ACPI_STATUS(status2);9797- }9292+ acpi_ex_reacquire_interpreter();9893 }999410095 return_ACPI_STATUS(status);···112119acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)113120{114121 acpi_status status;115115- acpi_status status2;116122117123 ACPI_FUNCTION_TRACE(ex_system_wait_mutex);118124···124132125133 /* We must wait, so unlock the interpreter */126134127127- acpi_ex_exit_interpreter();135135+ acpi_ex_relinquish_interpreter();128136129137 status = acpi_os_acquire_mutex(mutex, timeout);130138···134142135143 /* Reacquire the interpreter */136144137137- status2 = acpi_ex_enter_interpreter();138138- if (ACPI_FAILURE(status2)) {139139-140140- /* Report fatal error, could not acquire interpreter */141141-142142- return_ACPI_STATUS(status2);143143- }145145+ acpi_ex_reacquire_interpreter();144146 }145147146148 return_ACPI_STATUS(status);···195209196210acpi_status acpi_ex_system_do_suspend(acpi_integer how_long)197211{198198- acpi_status status;199199-200212 ACPI_FUNCTION_ENTRY();201213202214 /* Since this thread will sleep, we must release the interpreter */203215204204- acpi_ex_exit_interpreter();216216+ acpi_ex_relinquish_interpreter();205217206218 acpi_os_sleep(how_long);207219208220 /* And now we must get the interpreter again */209221210210- status = acpi_ex_enter_interpreter();211211- return (status);222222+ acpi_ex_reacquire_interpreter();223223+ return (AE_OK);212224}213225214226/*******************************************************************************
+84-20
drivers/acpi/executer/exutils.c
···7676 *7777 * PARAMETERS: None7878 *7979- * RETURN: Status7979+ * RETURN: None8080 *8181- * DESCRIPTION: Enter the interpreter execution region. Failure to enter8282- * the interpreter region is a fatal system error8181+ * DESCRIPTION: Enter the interpreter execution region. Failure to enter8282+ * the interpreter region is a fatal system error. Used in8383+ * conjunction with exit_interpreter.8384 *8485 ******************************************************************************/85868686-acpi_status acpi_ex_enter_interpreter(void)8787+void acpi_ex_enter_interpreter(void)8788{8889 acpi_status status;8990···92919392 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);9493 if (ACPI_FAILURE(status)) {9595- ACPI_ERROR((AE_INFO, "Could not acquire interpreter mutex"));9494+ ACPI_ERROR((AE_INFO,9595+ "Could not acquire AML Interpreter mutex"));9696 }97979898- return_ACPI_STATUS(status);9898+ return_VOID;9999+}100100+101101+/*******************************************************************************102102+ *103103+ * FUNCTION: acpi_ex_reacquire_interpreter104104+ *105105+ * PARAMETERS: None106106+ *107107+ * RETURN: None108108+ *109109+ * DESCRIPTION: Reacquire the interpreter execution region from within the110110+ * interpreter code. Failure to enter the interpreter region is a111111+ * fatal system error. Used in conjuction with112112+ * relinquish_interpreter113113+ *114114+ ******************************************************************************/115115+116116+void acpi_ex_reacquire_interpreter(void)117117+{118118+ ACPI_FUNCTION_TRACE(ex_reacquire_interpreter);119119+120120+ /*121121+ * If the global serialized flag is set, do not release the interpreter,122122+ * since it was not actually released by acpi_ex_relinquish_interpreter.123123+ * This forces the interpreter to be single threaded.124124+ */125125+ if (!acpi_gbl_all_methods_serialized) {126126+ acpi_ex_enter_interpreter();127127+ }128128+129129+ return_VOID;99130}100131101132/*******************************************************************************···138105 *139106 * RETURN: None140107 *141141- * DESCRIPTION: Exit the interpreter execution region142142- *143143- * Cases where the interpreter is unlocked:144144- * 1) Completion of the execution of a control method145145- * 2) Method blocked on a Sleep() AML opcode146146- * 3) Method blocked on an Acquire() AML opcode147147- * 4) Method blocked on a Wait() AML opcode148148- * 5) Method blocked to acquire the global lock149149- * 6) Method blocked to execute a serialized control method that is150150- * already executing151151- * 7) About to invoke a user-installed opregion handler108108+ * DESCRIPTION: Exit the interpreter execution region. This is the top level109109+ * routine used to exit the interpreter when all processing has110110+ * been completed.152111 *153112 ******************************************************************************/154113···152127153128 status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);154129 if (ACPI_FAILURE(status)) {155155- ACPI_ERROR((AE_INFO, "Could not release interpreter mutex"));130130+ ACPI_ERROR((AE_INFO,131131+ "Could not release AML Interpreter mutex"));132132+ }133133+134134+ return_VOID;135135+}136136+137137+/*******************************************************************************138138+ *139139+ * FUNCTION: acpi_ex_relinquish_interpreter140140+ *141141+ * PARAMETERS: None142142+ *143143+ * RETURN: None144144+ *145145+ * DESCRIPTION: Exit the interpreter execution region, from within the146146+ * interpreter - before attempting an operation that will possibly147147+ * block the running thread.148148+ *149149+ * Cases where the interpreter is unlocked internally150150+ * 1) Method to be blocked on a Sleep() AML opcode151151+ * 2) Method to be blocked on an Acquire() AML opcode152152+ * 3) Method to be blocked on a Wait() AML opcode153153+ * 4) Method to be blocked to acquire the global lock154154+ * 5) Method to be blocked waiting to execute a serialized control method155155+ * that is currently executing156156+ * 6) About to invoke a user-installed opregion handler157157+ *158158+ ******************************************************************************/159159+160160+void acpi_ex_relinquish_interpreter(void)161161+{162162+ ACPI_FUNCTION_TRACE(ex_relinquish_interpreter);163163+164164+ /*165165+ * If the global serialized flag is set, do not release the interpreter.166166+ * This forces the interpreter to be single threaded.167167+ */168168+ if (!acpi_gbl_all_methods_serialized) {169169+ acpi_ex_exit_interpreter();156170 }157171158172 return_VOID;···205141 *206142 * RETURN: none207143 *208208- * DESCRIPTION: Truncate a number to 32-bits if the currently executing method209209- * belongs to a 32-bit ACPI table.144144+ * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is145145+ * 32-bit, as determined by the revision of the DSDT.210146 *211147 ******************************************************************************/212148
+2-9
drivers/acpi/namespace/nseval.c
···154154 * Execute the method via the interpreter. The interpreter is locked155155 * here before calling into the AML parser156156 */157157- status = acpi_ex_enter_interpreter();158158- if (ACPI_FAILURE(status)) {159159- return_ACPI_STATUS(status);160160- }161161-157157+ acpi_ex_enter_interpreter();162158 status = acpi_ps_execute_method(info);163159 acpi_ex_exit_interpreter();164160 } else {···178182 * resolution, we must lock it because we could access an opregion.179183 * The opregion access code assumes that the interpreter is locked.180184 */181181- status = acpi_ex_enter_interpreter();182182- if (ACPI_FAILURE(status)) {183183- return_ACPI_STATUS(status);184184- }185185+ acpi_ex_enter_interpreter();185186186187 /* Function has a strange interface */187188
+2-5
drivers/acpi/namespace/nsinit.c
···214214 u32 level, void *context, void **return_value)215215{216216 acpi_object_type type;217217- acpi_status status;217217+ acpi_status status = AE_OK;218218 struct acpi_init_walk_info *info =219219 (struct acpi_init_walk_info *)context;220220 struct acpi_namespace_node *node =···268268 /*269269 * Must lock the interpreter before executing AML code270270 */271271- status = acpi_ex_enter_interpreter();272272- if (ACPI_FAILURE(status)) {273273- return (status);274274- }271271+ acpi_ex_enter_interpreter();275272276273 /*277274 * Each of these types can contain executable AML code within the
+4-7
drivers/acpi/namespace/nsxfeval.c
···170170 struct acpi_buffer *return_buffer)171171{172172 acpi_status status;173173- acpi_status status2;174173 struct acpi_evaluate_info *info;175174 acpi_size buffer_space_needed;176175 u32 i;···328329 * Delete the internal return object. NOTE: Interpreter must be329330 * locked to avoid race condition.330331 */331331- status2 = acpi_ex_enter_interpreter();332332- if (ACPI_SUCCESS(status2)) {332332+ acpi_ex_enter_interpreter();333333334334- /* Remove one reference on the return object (should delete it) */334334+ /* Remove one reference on the return object (should delete it) */335335336336- acpi_ut_remove_reference(info->return_object);337337- acpi_ex_exit_interpreter();338338- }336336+ acpi_ut_remove_reference(info->return_object);337337+ acpi_ex_exit_interpreter();339338 }340339341340 cleanup:
+35-10
drivers/acpi/osl.c
···7171static acpi_osd_handler acpi_irq_handler;7272static void *acpi_irq_context;7373static struct workqueue_struct *kacpid_wq;7474+static struct workqueue_struct *kacpi_notify_wq;74757576static void __init acpi_request_region (struct acpi_generic_address *addr,7677 unsigned int length, char *desc)···138137 return AE_NULL_ENTRY;139138 }140139 kacpid_wq = create_singlethread_workqueue("kacpid");140140+ kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");141141 BUG_ON(!kacpid_wq);142142-142142+ BUG_ON(!kacpi_notify_wq);143143 return AE_OK;144144}145145···152150 }153151154152 destroy_workqueue(kacpid_wq);153153+ destroy_workqueue(kacpi_notify_wq);155154156155 return AE_OK;157156}···606603static void acpi_os_execute_deferred(struct work_struct *work)607604{608605 struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);606606+ if (!dpc) {607607+ printk(KERN_ERR PREFIX "Invalid (NULL) context\n");608608+ return;609609+ }610610+611611+ dpc->function(dpc->context);612612+ kfree(dpc);613613+614614+ /* Yield cpu to notify thread */615615+ cond_resched();616616+617617+ return;618618+}619619+620620+static void acpi_os_execute_notify(struct work_struct *work)621621+{622622+ struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);609623610624 if (!dpc) {611625 printk(KERN_ERR PREFIX "Invalid (NULL) context\n");···657637 acpi_status status = AE_OK;658638 struct acpi_os_dpc *dpc;659639660660- ACPI_FUNCTION_TRACE("os_queue_for_execution");661661-662640 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,663641 "Scheduling function [%p(%p)] for deferred execution.\n",664642 function, context));665643666644 if (!function)667667- return_ACPI_STATUS(AE_BAD_PARAMETER);645645+ return AE_BAD_PARAMETER;668646669647 /*670648 * Allocate/initialize DPC structure. Note that this memory will be···680662 dpc->function = function;681663 dpc->context = context;682664683683- INIT_WORK(&dpc->work, acpi_os_execute_deferred);684684- if (!queue_work(kacpid_wq, &dpc->work)) {685685- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,665665+ if (type == OSL_NOTIFY_HANDLER) {666666+ INIT_WORK(&dpc->work, acpi_os_execute_notify);667667+ if (!queue_work(kacpi_notify_wq, &dpc->work)) {668668+ status = AE_ERROR;669669+ kfree(dpc);670670+ }671671+ } else {672672+ INIT_WORK(&dpc->work, acpi_os_execute_deferred);673673+ if (!queue_work(kacpid_wq, &dpc->work)) {674674+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,686675 "Call to queue_work() failed.\n"));687687- kfree(dpc);688688- status = AE_ERROR;676676+ status = AE_ERROR;677677+ kfree(dpc);678678+ }689679 }690690-691680 return_ACPI_STATUS(status);692681}693682
···155155struct acpi_object_mutex {156156 ACPI_OBJECT_COMMON_HEADER u8 sync_level; /* 0-15, specified in Mutex() call */157157 u16 acquisition_depth; /* Allow multiple Acquires, same thread */158158- acpi_thread_id owner_thread_id; /* Current owner of the mutex */158158+ struct acpi_thread_state *owner_thread; /* Current owner of the mutex */159159 acpi_mutex os_mutex; /* Actual OS synchronization object */160160 union acpi_operand_object *prev; /* Link for list of acquired mutexes */161161 union acpi_operand_object *next; /* Link for list of acquired mutexes */