diff options
author | Bob Moore <robert.moore@intel.com> | 2007-02-02 11:48:20 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-02-02 21:14:24 -0500 |
commit | 1ba753acb372c2955a4843302e92e49ce82e2fea (patch) | |
tree | 13dbe3af585f835c7d9cdf41fae505a7df4e8620 /drivers/acpi/executer | |
parent | 95befdb398e0112ede80529f6770644ecfa5a82e (diff) |
ACPICA: Re-implement interpreters' "serialized mode"
Enhanced the implementation of the interpreters'
serialized mode (boot with "acpi_serialize" to set
acpi_glb_all_methods_serialized flag.)
When this mode is specified, instead of creating a serialization
semaphore per control method, the interpreter lock is
simply no longer released before a blocking operation
during control method execution. This effectively makes
the AML Interpreter single-threaded. The overhead of a
semaphore per-method is eliminated.
Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/executer')
-rw-r--r-- | drivers/acpi/executer/excreate.c | 5 | ||||
-rw-r--r-- | drivers/acpi/executer/exsystem.c | 30 | ||||
-rw-r--r-- | drivers/acpi/executer/exutils.c | 108 |
3 files changed, 95 insertions, 48 deletions
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c index a4d29b2d086f..c665aa776f83 100644 --- a/drivers/acpi/executer/excreate.c +++ b/drivers/acpi/executer/excreate.c | |||
@@ -583,10 +583,7 @@ acpi_ex_create_method(u8 * aml_start, | |||
583 | * Get the sync_level. If method is serialized, a mutex will be | 583 | * Get the sync_level. If method is serialized, a mutex will be |
584 | * created for this method when it is parsed. | 584 | * created for this method when it is parsed. |
585 | */ | 585 | */ |
586 | if (acpi_gbl_all_methods_serialized) { | 586 | if (method_flags & AML_METHOD_SERIALIZED) { |
587 | obj_desc->method.sync_level = 0; | ||
588 | obj_desc->method.method_flags |= AML_METHOD_SERIALIZED; | ||
589 | } else if (method_flags & AML_METHOD_SERIALIZED) { | ||
590 | /* | 587 | /* |
591 | * ACPI 1.0: sync_level = 0 | 588 | * ACPI 1.0: sync_level = 0 |
592 | * ACPI 2.0: sync_level = sync_level in method declaration | 589 | * ACPI 2.0: sync_level = sync_level in method declaration |
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c index 3b9736a3e1b7..7e5aeb17cdc6 100644 --- a/drivers/acpi/executer/exsystem.c +++ b/drivers/acpi/executer/exsystem.c | |||
@@ -66,7 +66,6 @@ ACPI_MODULE_NAME("exsystem") | |||
66 | acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) | 66 | acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) |
67 | { | 67 | { |
68 | acpi_status status; | 68 | acpi_status status; |
69 | acpi_status status2; | ||
70 | 69 | ||
71 | ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); | 70 | ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); |
72 | 71 | ||
@@ -79,7 +78,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) | |||
79 | 78 | ||
80 | /* We must wait, so unlock the interpreter */ | 79 | /* We must wait, so unlock the interpreter */ |
81 | 80 | ||
82 | acpi_ex_exit_interpreter(); | 81 | acpi_ex_relinquish_interpreter(); |
83 | 82 | ||
84 | status = acpi_os_wait_semaphore(semaphore, 1, timeout); | 83 | status = acpi_os_wait_semaphore(semaphore, 1, timeout); |
85 | 84 | ||
@@ -89,13 +88,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) | |||
89 | 88 | ||
90 | /* Reacquire the interpreter */ | 89 | /* Reacquire the interpreter */ |
91 | 90 | ||
92 | status2 = acpi_ex_enter_interpreter(); | 91 | acpi_ex_reacquire_interpreter(); |
93 | if (ACPI_FAILURE(status2)) { | ||
94 | |||
95 | /* Report fatal error, could not acquire interpreter */ | ||
96 | |||
97 | return_ACPI_STATUS(status2); | ||
98 | } | ||
99 | } | 92 | } |
100 | 93 | ||
101 | return_ACPI_STATUS(status); | 94 | return_ACPI_STATUS(status); |
@@ -119,7 +112,6 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) | |||
119 | acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) | 112 | acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) |
120 | { | 113 | { |
121 | acpi_status status; | 114 | acpi_status status; |
122 | acpi_status status2; | ||
123 | 115 | ||
124 | ACPI_FUNCTION_TRACE(ex_system_wait_mutex); | 116 | ACPI_FUNCTION_TRACE(ex_system_wait_mutex); |
125 | 117 | ||
@@ -132,7 +124,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) | |||
132 | 124 | ||
133 | /* We must wait, so unlock the interpreter */ | 125 | /* We must wait, so unlock the interpreter */ |
134 | 126 | ||
135 | acpi_ex_exit_interpreter(); | 127 | acpi_ex_relinquish_interpreter(); |
136 | 128 | ||
137 | status = acpi_os_acquire_mutex(mutex, timeout); | 129 | status = acpi_os_acquire_mutex(mutex, timeout); |
138 | 130 | ||
@@ -142,13 +134,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) | |||
142 | 134 | ||
143 | /* Reacquire the interpreter */ | 135 | /* Reacquire the interpreter */ |
144 | 136 | ||
145 | status2 = acpi_ex_enter_interpreter(); | 137 | acpi_ex_reacquire_interpreter(); |
146 | if (ACPI_FAILURE(status2)) { | ||
147 | |||
148 | /* Report fatal error, could not acquire interpreter */ | ||
149 | |||
150 | return_ACPI_STATUS(status2); | ||
151 | } | ||
152 | } | 138 | } |
153 | 139 | ||
154 | return_ACPI_STATUS(status); | 140 | return_ACPI_STATUS(status); |
@@ -209,20 +195,18 @@ acpi_status acpi_ex_system_do_stall(u32 how_long) | |||
209 | 195 | ||
210 | acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) | 196 | acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) |
211 | { | 197 | { |
212 | acpi_status status; | ||
213 | |||
214 | ACPI_FUNCTION_ENTRY(); | 198 | ACPI_FUNCTION_ENTRY(); |
215 | 199 | ||
216 | /* Since this thread will sleep, we must release the interpreter */ | 200 | /* Since this thread will sleep, we must release the interpreter */ |
217 | 201 | ||
218 | acpi_ex_exit_interpreter(); | 202 | acpi_ex_relinquish_interpreter(); |
219 | 203 | ||
220 | acpi_os_sleep(how_long); | 204 | acpi_os_sleep(how_long); |
221 | 205 | ||
222 | /* And now we must get the interpreter again */ | 206 | /* And now we must get the interpreter again */ |
223 | 207 | ||
224 | status = acpi_ex_enter_interpreter(); | 208 | acpi_ex_reacquire_interpreter(); |
225 | return (status); | 209 | return (AE_OK); |
226 | } | 210 | } |
227 | 211 | ||
228 | /******************************************************************************* | 212 | /******************************************************************************* |
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c index 982c8b65876f..72adcf44afbb 100644 --- a/drivers/acpi/executer/exutils.c +++ b/drivers/acpi/executer/exutils.c | |||
@@ -76,46 +76,72 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base); | |||
76 | * | 76 | * |
77 | * PARAMETERS: None | 77 | * PARAMETERS: None |
78 | * | 78 | * |
79 | * RETURN: Status | 79 | * RETURN: None |
80 | * | 80 | * |
81 | * DESCRIPTION: Enter the interpreter execution region. Failure to enter | 81 | * DESCRIPTION: Enter the interpreter execution region. Failure to enter |
82 | * the interpreter region is a fatal system error | 82 | * the interpreter region is a fatal system error. Used in |
83 | * conjunction with exit_interpreter. | ||
83 | * | 84 | * |
84 | ******************************************************************************/ | 85 | ******************************************************************************/ |
85 | 86 | ||
86 | acpi_status acpi_ex_enter_interpreter(void) | 87 | void acpi_ex_enter_interpreter(void) |
87 | { | 88 | { |
88 | acpi_status status; | 89 | acpi_status status; |
89 | 90 | ||
90 | ACPI_FUNCTION_TRACE(ex_enter_interpreter); | 91 | ACPI_FUNCTION_TRACE(ex_reacquire_interpreter); |
91 | 92 | ||
92 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | 93 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); |
93 | if (ACPI_FAILURE(status)) { | 94 | if (ACPI_FAILURE(status)) { |
94 | ACPI_ERROR((AE_INFO, "Could not acquire interpreter mutex")); | 95 | ACPI_ERROR((AE_INFO, |
96 | "Could not acquire AML Interpreter mutex")); | ||
95 | } | 97 | } |
96 | 98 | ||
97 | return_ACPI_STATUS(status); | 99 | return_VOID; |
98 | } | 100 | } |
99 | 101 | ||
100 | /******************************************************************************* | 102 | /******************************************************************************* |
101 | * | 103 | * |
102 | * FUNCTION: acpi_ex_exit_interpreter | 104 | * FUNCTION: acpi_ex_reacquire_interpreter |
103 | * | 105 | * |
104 | * PARAMETERS: None | 106 | * PARAMETERS: None |
105 | * | 107 | * |
106 | * RETURN: None | 108 | * RETURN: None |
107 | * | 109 | * |
108 | * DESCRIPTION: Exit the interpreter execution region | 110 | * DESCRIPTION: Reacquire the interpreter execution region from within the |
111 | * interpreter code. Failure to enter the interpreter region is a | ||
112 | * fatal system error. Used in conjuction with | ||
113 | * relinquish_interpreter | ||
114 | * | ||
115 | ******************************************************************************/ | ||
116 | |||
117 | void acpi_ex_reacquire_interpreter(void) | ||
118 | { | ||
119 | |||
120 | ACPI_FUNCTION_TRACE(ex_reacquire_interpreter); | ||
121 | |||
122 | /* | ||
123 | * If the global serialized flag is set, do not release the interpreter, | ||
124 | * since it was not actually released by acpi_ex_relinquish_interpreter. | ||
125 | * This forces the interpreter to be single threaded. | ||
126 | */ | ||
127 | if (!acpi_gbl_all_methods_serialized) { | ||
128 | acpi_ex_enter_interpreter(); | ||
129 | } | ||
130 | |||
131 | return_VOID; | ||
132 | } | ||
133 | |||
134 | /******************************************************************************* | ||
135 | * | ||
136 | * FUNCTION: acpi_ex_exit_interpreter | ||
137 | * | ||
138 | * PARAMETERS: None | ||
139 | * | ||
140 | * RETURN: None | ||
109 | * | 141 | * |
110 | * Cases where the interpreter is unlocked: | 142 | * DESCRIPTION: Exit the interpreter execution region. This is the top level |
111 | * 1) Completion of the execution of a control method | 143 | * routine used to exit the interpreter when all processing has |
112 | * 2) Method blocked on a Sleep() AML opcode | 144 | * been completed. |
113 | * 3) Method blocked on an Acquire() AML opcode | ||
114 | * 4) Method blocked on a Wait() AML opcode | ||
115 | * 5) Method blocked to acquire the global lock | ||
116 | * 6) Method blocked to execute a serialized control method that is | ||
117 | * already executing | ||
118 | * 7) About to invoke a user-installed opregion handler | ||
119 | * | 145 | * |
120 | ******************************************************************************/ | 146 | ******************************************************************************/ |
121 | 147 | ||
@@ -127,7 +153,47 @@ void acpi_ex_exit_interpreter(void) | |||
127 | 153 | ||
128 | status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | 154 | status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); |
129 | if (ACPI_FAILURE(status)) { | 155 | if (ACPI_FAILURE(status)) { |
130 | ACPI_ERROR((AE_INFO, "Could not release interpreter mutex")); | 156 | ACPI_ERROR((AE_INFO, |
157 | "Could not release AML Interpreter mutex")); | ||
158 | } | ||
159 | |||
160 | return_VOID; | ||
161 | } | ||
162 | |||
163 | /******************************************************************************* | ||
164 | * | ||
165 | * FUNCTION: acpi_ex_relinquish_interpreter | ||
166 | * | ||
167 | * PARAMETERS: None | ||
168 | * | ||
169 | * RETURN: None | ||
170 | * | ||
171 | * DESCRIPTION: Exit the interpreter execution region, from within the | ||
172 | * interpreter - before attempting an operation that will possibly | ||
173 | * block the running thread. | ||
174 | * | ||
175 | * Cases where the interpreter is unlocked internally | ||
176 | * 1) Method to be blocked on a Sleep() AML opcode | ||
177 | * 2) Method to be blocked on an Acquire() AML opcode | ||
178 | * 3) Method to be blocked on a Wait() AML opcode | ||
179 | * 4) Method to be blocked to acquire the global lock | ||
180 | * 5) Method to be blocked waiting to execute a serialized control method | ||
181 | * that is currently executing | ||
182 | * 6) About to invoke a user-installed opregion handler | ||
183 | * | ||
184 | ******************************************************************************/ | ||
185 | |||
186 | void acpi_ex_relinquish_interpreter(void) | ||
187 | { | ||
188 | |||
189 | ACPI_FUNCTION_TRACE(ex_relinquish_interpreter); | ||
190 | |||
191 | /* | ||
192 | * If the global serialized flag is set, do not release the interpreter. | ||
193 | * This forces the interpreter to be single threaded. | ||
194 | */ | ||
195 | if (!acpi_gbl_all_methods_serialized) { | ||
196 | acpi_ex_exit_interpreter(); | ||
131 | } | 197 | } |
132 | 198 | ||
133 | return_VOID; | 199 | return_VOID; |
@@ -141,8 +207,8 @@ void acpi_ex_exit_interpreter(void) | |||
141 | * | 207 | * |
142 | * RETURN: none | 208 | * RETURN: none |
143 | * | 209 | * |
144 | * DESCRIPTION: Truncate a number to 32-bits if the currently executing method | 210 | * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is |
145 | * belongs to a 32-bit ACPI table. | 211 | * 32-bit, as determined by the revision of the DSDT. |
146 | * | 212 | * |
147 | ******************************************************************************/ | 213 | ******************************************************************************/ |
148 | 214 | ||