aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/tbinstal.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2009-03-09 04:31:04 -0400
committerLen Brown <len.brown@intel.com>2009-03-27 12:11:02 -0400
commit8a335a2331c72e60c6b3ef09b2dedd3ba00da1b1 (patch)
treef538a4f68499dab0d59e253bc55a5cf4aff66ec1 /drivers/acpi/acpica/tbinstal.c
parentaab61b676a024d3527f6201e2b31285a96f7a1d2 (diff)
ACPICA: Fix AcpiWalkNamespace race condition with table unload
Added a reader/writer locking mechanism to allow multiple concurrent namespace walks (readers), but a dynamic table unload will have exclusive access to the namespace. This fixes a problem where a table unload could delete the portion of the namespace that is currently being examined by a walk. Adds a new file, utlock.c that implements the reader/writer lock mechanism. ACPICA BZ 749. http://www.acpica.org/bugzilla/show_bug.cgi?id=749 Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/tbinstal.c')
-rw-r--r--drivers/acpi/acpica/tbinstal.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index c37993003f2c..f865d5a096de 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -434,27 +434,56 @@ void acpi_tb_terminate(void)
434 * 434 *
435 * PARAMETERS: table_index - Table index 435 * PARAMETERS: table_index - Table index
436 * 436 *
437 * RETURN: None 437 * RETURN: Status
438 * 438 *
439 * DESCRIPTION: Delete all namespace objects created when this table was loaded. 439 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
440 * 440 *
441 ******************************************************************************/ 441 ******************************************************************************/
442 442
443void acpi_tb_delete_namespace_by_owner(u32 table_index) 443acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
444{ 444{
445 acpi_owner_id owner_id; 445 acpi_owner_id owner_id;
446 acpi_status status;
447
448 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
449
450 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
451 if (ACPI_FAILURE(status)) {
452 return_ACPI_STATUS(status);
453 }
454
455 if (table_index >= acpi_gbl_root_table_list.count) {
456
457 /* The table index does not exist */
446 458
447 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
448 if (table_index < acpi_gbl_root_table_list.count) {
449 owner_id =
450 acpi_gbl_root_table_list.tables[table_index].owner_id;
451 } else {
452 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 459 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
453 return; 460 return_ACPI_STATUS(AE_NOT_EXIST);
454 } 461 }
455 462
463 /* Get the owner ID for this table, used to delete namespace nodes */
464
465 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
456 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 466 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
467
468 /*
469 * Need to acquire the namespace writer lock to prevent interference
470 * with any concurrent namespace walks. The interpreter must be
471 * released during the deletion since the acquisition of the deletion
472 * lock may block, and also since the execution of a namespace walk
473 * must be allowed to use the interpreter.
474 */
475 acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
476 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
477
457 acpi_ns_delete_namespace_by_owner(owner_id); 478 acpi_ns_delete_namespace_by_owner(owner_id);
479 if (ACPI_FAILURE(status)) {
480 return_ACPI_STATUS(status);
481 }
482
483 acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
484
485 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
486 return_ACPI_STATUS(status);
458} 487}
459 488
460/******************************************************************************* 489/*******************************************************************************