aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/exconfig.c
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2016-09-07 02:07:24 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-09-09 20:43:03 -0400
commitac0f06ebb815dabe42f2b2886ee9f879a2170ce4 (patch)
tree59cd81530337d1b16b388dadf0586aeb36bd8e48 /drivers/acpi/acpica/exconfig.c
parent441ad11d078f35093ceaf510742df423c2d89a3b (diff)
ACPICA: Tables: Tune table mutex to be a leaf lock
ACPICA commit f564d57c6501b97a2871f0b4c048e79910f71783 This patch tunes MTX_TABLES into a leaf lock by always ensuring it is released before holding other locks. This patch also collects all table loading related functions into acpi_tb_load_table() (invoked by load_table opcode) and acpi_tb_install_and_load_table() (invoked by Load opcode and acpi_load_table()) so that we can have lock tuning code collected at the boundary of these 2 functions. Lv Zheng. Link: https://github.com/acpica/acpica/commit/f564d57c Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com> Tested-by: Dutch Guy <lucht_piloot@gmx.net> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/exconfig.c')
-rw-r--r--drivers/acpi/acpica/exconfig.c105
1 files changed, 21 insertions, 84 deletions
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index 578d5c832325..421836a7a5b9 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -55,9 +55,7 @@ ACPI_MODULE_NAME("exconfig")
55 55
56/* Local prototypes */ 56/* Local prototypes */
57static acpi_status 57static acpi_status
58acpi_ex_add_table(u32 table_index, 58acpi_ex_add_table(u32 table_index, union acpi_operand_object **ddb_handle);
59 struct acpi_namespace_node *parent_node,
60 union acpi_operand_object **ddb_handle);
61 59
62static acpi_status 60static acpi_status
63acpi_ex_region_read(union acpi_operand_object *obj_desc, 61acpi_ex_region_read(union acpi_operand_object *obj_desc,
@@ -79,13 +77,9 @@ acpi_ex_region_read(union acpi_operand_object *obj_desc,
79 ******************************************************************************/ 77 ******************************************************************************/
80 78
81static acpi_status 79static acpi_status
82acpi_ex_add_table(u32 table_index, 80acpi_ex_add_table(u32 table_index, union acpi_operand_object **ddb_handle)
83 struct acpi_namespace_node *parent_node,
84 union acpi_operand_object **ddb_handle)
85{ 81{
86 union acpi_operand_object *obj_desc; 82 union acpi_operand_object *obj_desc;
87 acpi_status status;
88 acpi_owner_id owner_id;
89 83
90 ACPI_FUNCTION_TRACE(ex_add_table); 84 ACPI_FUNCTION_TRACE(ex_add_table);
91 85
@@ -100,40 +94,8 @@ acpi_ex_add_table(u32 table_index,
100 94
101 obj_desc->common.flags |= AOPOBJ_DATA_VALID; 95 obj_desc->common.flags |= AOPOBJ_DATA_VALID;
102 obj_desc->reference.class = ACPI_REFCLASS_TABLE; 96 obj_desc->reference.class = ACPI_REFCLASS_TABLE;
103 *ddb_handle = obj_desc;
104
105 /* Install the new table into the local data structures */
106
107 obj_desc->reference.value = table_index; 97 obj_desc->reference.value = table_index;
108 98 *ddb_handle = obj_desc;
109 /* Add the table to the namespace */
110
111 status = acpi_ns_load_table(table_index, parent_node);
112 if (ACPI_FAILURE(status)) {
113 acpi_ut_remove_reference(obj_desc);
114 *ddb_handle = NULL;
115 return_ACPI_STATUS(status);
116 }
117
118 /* Execute any module-level code that was found in the table */
119
120 acpi_ex_exit_interpreter();
121 if (!acpi_gbl_parse_table_as_term_list
122 && acpi_gbl_group_module_level_code) {
123 acpi_ns_exec_module_code_list();
124 }
125 acpi_ex_enter_interpreter();
126
127 /*
128 * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
129 * responsible for discovering any new wake GPEs by running _PRW methods
130 * that may have been loaded by this table.
131 */
132 status = acpi_tb_get_owner_id(table_index, &owner_id);
133 if (ACPI_SUCCESS(status)) {
134 acpi_ev_update_gpes(owner_id);
135 }
136
137 return_ACPI_STATUS(AE_OK); 99 return_ACPI_STATUS(AE_OK);
138} 100}
139 101
@@ -160,16 +122,17 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
160 struct acpi_namespace_node *start_node; 122 struct acpi_namespace_node *start_node;
161 struct acpi_namespace_node *parameter_node = NULL; 123 struct acpi_namespace_node *parameter_node = NULL;
162 union acpi_operand_object *ddb_handle; 124 union acpi_operand_object *ddb_handle;
163 struct acpi_table_header *table;
164 u32 table_index; 125 u32 table_index;
165 126
166 ACPI_FUNCTION_TRACE(ex_load_table_op); 127 ACPI_FUNCTION_TRACE(ex_load_table_op);
167 128
168 /* Find the ACPI table in the RSDT/XSDT */ 129 /* Find the ACPI table in the RSDT/XSDT */
169 130
131 acpi_ex_exit_interpreter();
170 status = acpi_tb_find_table(operand[0]->string.pointer, 132 status = acpi_tb_find_table(operand[0]->string.pointer,
171 operand[1]->string.pointer, 133 operand[1]->string.pointer,
172 operand[2]->string.pointer, &table_index); 134 operand[2]->string.pointer, &table_index);
135 acpi_ex_enter_interpreter();
173 if (ACPI_FAILURE(status)) { 136 if (ACPI_FAILURE(status)) {
174 if (status != AE_NOT_FOUND) { 137 if (status != AE_NOT_FOUND) {
175 return_ACPI_STATUS(status); 138 return_ACPI_STATUS(status);
@@ -232,7 +195,15 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
232 195
233 /* Load the table into the namespace */ 196 /* Load the table into the namespace */
234 197
235 status = acpi_ex_add_table(table_index, parent_node, &ddb_handle); 198 ACPI_INFO(("Dynamic OEM Table Load:"));
199 acpi_ex_exit_interpreter();
200 status = acpi_tb_load_table(table_index, parent_node);
201 acpi_ex_enter_interpreter();
202 if (ACPI_FAILURE(status)) {
203 return_ACPI_STATUS(status);
204 }
205
206 status = acpi_ex_add_table(table_index, &ddb_handle);
236 if (ACPI_FAILURE(status)) { 207 if (ACPI_FAILURE(status)) {
237 return_ACPI_STATUS(status); 208 return_ACPI_STATUS(status);
238 } 209 }
@@ -255,19 +226,6 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
255 } 226 }
256 } 227 }
257 228
258 status = acpi_get_table_by_index(table_index, &table);
259 if (ACPI_SUCCESS(status)) {
260 ACPI_INFO(("Dynamic OEM Table Load:"));
261 acpi_tb_print_table_header(0, table);
262 }
263
264 /* Invoke table handler if present */
265
266 if (acpi_gbl_table_handler) {
267 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
268 acpi_gbl_table_handler_context);
269 }
270
271 *return_desc = ddb_handle; 229 *return_desc = ddb_handle;
272 return_ACPI_STATUS(status); 230 return_ACPI_STATUS(status);
273} 231}
@@ -478,13 +436,12 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
478 /* Install the new table into the local data structures */ 436 /* Install the new table into the local data structures */
479 437
480 ACPI_INFO(("Dynamic OEM Table Load:")); 438 ACPI_INFO(("Dynamic OEM Table Load:"));
481 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 439 acpi_ex_exit_interpreter();
482 440 status =
483 status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table), 441 acpi_tb_install_and_load_table(table, ACPI_PTR_TO_PHYSADDR(table),
484 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, 442 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
485 TRUE, TRUE, &table_index); 443 TRUE, &table_index);
486 444 acpi_ex_enter_interpreter();
487 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
488 if (ACPI_FAILURE(status)) { 445 if (ACPI_FAILURE(status)) {
489 446
490 /* Delete allocated table buffer */ 447 /* Delete allocated table buffer */
@@ -494,25 +451,13 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
494 } 451 }
495 452
496 /* 453 /*
497 * Note: Now table is "INSTALLED", it must be validated before
498 * loading.
499 */
500 status =
501 acpi_tb_validate_table(&acpi_gbl_root_table_list.
502 tables[table_index]);
503 if (ACPI_FAILURE(status)) {
504 return_ACPI_STATUS(status);
505 }
506
507 /*
508 * Add the table to the namespace. 454 * Add the table to the namespace.
509 * 455 *
510 * Note: Load the table objects relative to the root of the namespace. 456 * Note: Load the table objects relative to the root of the namespace.
511 * This appears to go against the ACPI specification, but we do it for 457 * This appears to go against the ACPI specification, but we do it for
512 * compatibility with other ACPI implementations. 458 * compatibility with other ACPI implementations.
513 */ 459 */
514 status = 460 status = acpi_ex_add_table(table_index, &ddb_handle);
515 acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle);
516 if (ACPI_FAILURE(status)) { 461 if (ACPI_FAILURE(status)) {
517 462
518 /* On error, table_ptr was deallocated above */ 463 /* On error, table_ptr was deallocated above */
@@ -535,14 +480,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
535 /* Remove the reference by added by acpi_ex_store above */ 480 /* Remove the reference by added by acpi_ex_store above */
536 481
537 acpi_ut_remove_reference(ddb_handle); 482 acpi_ut_remove_reference(ddb_handle);
538
539 /* Invoke table handler if present */
540
541 if (acpi_gbl_table_handler) {
542 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
543 acpi_gbl_table_handler_context);
544 }
545
546 return_ACPI_STATUS(status); 483 return_ACPI_STATUS(status);
547} 484}
548 485