Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 141859
b: refs/heads/master
c: 8a335a2
h: refs/heads/master
i:
  141857: 8d3a3ca
  141855: c35686f
v: v3
  • Loading branch information
Bob Moore authored and Len Brown committed Mar 27, 2009
1 parent f21ddb9 commit 5cf7ee1
Show file tree
Hide file tree
Showing 12 changed files with 304 additions and 34 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: aab61b676a024d3527f6201e2b31285a96f7a1d2
refs/heads/master: 8a335a2331c72e60c6b3ef09b2dedd3ba00da1b1
2 changes: 1 addition & 1 deletion trunk/drivers/acpi/acpica/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ obj-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o

obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
utstate.o utmutex.o utobject.o utresrc.o
utstate.o utmutex.o utobject.o utresrc.o utlock.o
4 changes: 4 additions & 0 deletions trunk/drivers/acpi/acpica/acglobal.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width;
ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;

/* Reader/Writer lock is used for namespace walk and dynamic table unload */

ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock;

/*****************************************************************************
*
* Mutual exlusion within ACPICA subsystem
Expand Down
8 changes: 8 additions & 0 deletions trunk/drivers/acpi/acpica/aclocal.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = {
#endif
#endif

/* Lock structure for reader/writer interfaces */

struct acpi_rw_lock {
acpi_mutex writer_mutex;
acpi_mutex reader_mutex;
u32 num_readers;
};

/*
* Predefined handles for spinlocks used within the subsystem.
* These spinlocks are created by acpi_ut_mutex_initialize
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/acpi/acpica/actables.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc);

void acpi_tb_terminate(void);

void acpi_tb_delete_namespace_by_owner(u32 table_index);
acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index);

acpi_status acpi_tb_allocate_owner_id(u32 table_index);

Expand Down
15 changes: 15 additions & 0 deletions trunk/drivers/acpi/acpica/acutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,21 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
acpi_status
acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest);

/*
* utlock - reader/writer locks
*/
acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock);

void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock);

acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock);

acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock);

acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock);

void acpi_ut_release_write_lock(struct acpi_rw_lock *lock);

/*
* utobject - internal object create/delete/cache routines
*/
Expand Down
16 changes: 14 additions & 2 deletions trunk/drivers/acpi/acpica/dsinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,23 @@ acpi_ds_initialize_objects(u32 table_index,

/* Walk entire namespace from the supplied root */

status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
acpi_ds_init_one_object, &info, NULL);
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}

/*
* We don't use acpi_walk_namespace since we do not want to acquire
* the namespace reader lock.
*/
status =
acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object,
&info, NULL);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
}
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);

status = acpi_get_table_by_index(table_index, &table);
if (ACPI_FAILURE(status)) {
Expand Down
13 changes: 7 additions & 6 deletions trunk/drivers/acpi/acpica/exconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,13 +520,14 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
}
}

/*
* Delete the entire namespace under this table Node
* (Offset contains the table_id)
*/
acpi_tb_delete_namespace_by_owner(table_index);
(void)acpi_tb_release_owner_id(table_index);
/* Delete the portion of the namespace owned by this table */

status = acpi_tb_delete_namespace_by_owner(table_index);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}

(void)acpi_tb_release_owner_id(table_index);
acpi_tb_set_table_loaded_flag(table_index, FALSE);

/* Table unloaded, remove a reference to the ddb_handle object */
Expand Down
33 changes: 26 additions & 7 deletions trunk/drivers/acpi/acpica/nsxfeval.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,21 +475,40 @@ acpi_walk_namespace(acpi_object_type type,
}

/*
* Lock the namespace around the walk.
* The namespace will be unlocked/locked around each call
* to the user function - since this function
* must be allowed to make Acpi calls itself.
* Need to acquire the namespace reader lock to prevent interference
* with any concurrent table unloads (which causes the deletion of
* namespace objects). We cannot allow the deletion of a namespace node
* while the user function is using it. The exception to this are the
* nodes created and deleted during control method execution -- these
* nodes are marked as temporary nodes and are ignored by the namespace
* walk. Thus, control methods can be executed while holding the
* namespace deletion lock (and the user function can execute control
* methods.)
*/
status = acpi_ut_acquire_read_lock(&acpi_gbl_namespace_rw_lock);
if (ACPI_FAILURE(status)) {
return status;
}

/*
* Lock the namespace around the walk. The namespace will be
* unlocked/locked around each call to the user function - since the user
* function must be allowed to make ACPICA calls itself (for example, it
* will typically execute control methods during device enumeration.)
*/
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
goto unlock_and_exit;
}

status = acpi_ns_walk_namespace(type, start_object, max_depth,
ACPI_NS_WALK_UNLOCK,
user_function, context, return_value);
ACPI_NS_WALK_UNLOCK, user_function,
context, return_value);

(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);

unlock_and_exit:
(void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock);
return_ACPI_STATUS(status);
}

Expand Down
45 changes: 37 additions & 8 deletions trunk/drivers/acpi/acpica/tbinstal.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,27 +434,56 @@ void acpi_tb_terminate(void)
*
* PARAMETERS: table_index - Table index
*
* RETURN: None
* RETURN: Status
*
* DESCRIPTION: Delete all namespace objects created when this table was loaded.
*
******************************************************************************/

void acpi_tb_delete_namespace_by_owner(u32 table_index)
acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
{
acpi_owner_id owner_id;
acpi_status status;

ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);

status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}

if (table_index >= acpi_gbl_root_table_list.count) {

/* The table index does not exist */

(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
if (table_index < acpi_gbl_root_table_list.count) {
owner_id =
acpi_gbl_root_table_list.tables[table_index].owner_id;
} else {
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
return;
return_ACPI_STATUS(AE_NOT_EXIST);
}

/* Get the owner ID for this table, used to delete namespace nodes */

owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);

/*
* Need to acquire the namespace writer lock to prevent interference
* with any concurrent namespace walks. The interpreter must be
* released during the deletion since the acquisition of the deletion
* lock may block, and also since the execution of a namespace walk
* must be allowed to use the interpreter.
*/
acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);

acpi_ns_delete_namespace_by_owner(owner_id);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}

acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);

status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
return_ACPI_STATUS(status);
}

/*******************************************************************************
Expand Down
Loading

0 comments on commit 5cf7ee1

Please sign in to comment.