aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorChen Gong <gong.chen@linux.intel.com>2009-12-13 20:42:28 -0500
committerLen Brown <len.brown@intel.com>2009-12-30 19:24:36 -0500
commit3b8cb427e9281790f36e847e46cb1d005a50cec0 (patch)
treea77f28a9f8ec39c0d2b026e7952b5a989b93ba72 /drivers/acpi
parent22763c5cf3690a681551162c15d34d935308c8d7 (diff)
acpi_pad: fix error checks
There are some fixes listed below: 1. When met a bogus BIOS, the return value of cpu number maybe is a negative value so that acpi_pad_pur get an unexpected result. 2. the return value of function acpi_pad_idle_cpus is useless. 3. enhance the process of create_power_saving_task/destroy_power_saving_task 4. Add more error checks when evaluating _PUR object. 5. one typo fix Signed-off-by: Chen Gong <gong.chen@linux.intel.com> Acked-by: Shaohua Li <shaohua.li@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/acpi_pad.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index 0d2cdb86158b..a7bd49f0f01f 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -207,7 +207,7 @@ static int power_saving_thread(void *data)
207 * the mechanism only works when all CPUs have RT task running, 207 * the mechanism only works when all CPUs have RT task running,
208 * as if one CPU hasn't RT task, RT task from other CPUs will 208 * as if one CPU hasn't RT task, RT task from other CPUs will
209 * borrow CPU time from this CPU and cause RT task use > 95% 209 * borrow CPU time from this CPU and cause RT task use > 95%
210 * CPU time. To make 'avoid staration' work, takes a nap here. 210 * CPU time. To make 'avoid starvation' work, takes a nap here.
211 */ 211 */
212 if (do_sleep) 212 if (do_sleep)
213 schedule_timeout_killable(HZ * idle_pct / 100); 213 schedule_timeout_killable(HZ * idle_pct / 100);
@@ -221,14 +221,18 @@ static struct task_struct *ps_tsks[NR_CPUS];
221static unsigned int ps_tsk_num; 221static unsigned int ps_tsk_num;
222static int create_power_saving_task(void) 222static int create_power_saving_task(void)
223{ 223{
224 int rc = -ENOMEM;
225
224 ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread, 226 ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread,
225 (void *)(unsigned long)ps_tsk_num, 227 (void *)(unsigned long)ps_tsk_num,
226 "power_saving/%d", ps_tsk_num); 228 "power_saving/%d", ps_tsk_num);
227 if (ps_tsks[ps_tsk_num]) { 229 rc = IS_ERR(ps_tsks[ps_tsk_num]) ? PTR_ERR(ps_tsks[ps_tsk_num]) : 0;
230 if (!rc)
228 ps_tsk_num++; 231 ps_tsk_num++;
229 return 0; 232 else
230 } 233 ps_tsks[ps_tsk_num] = NULL;
231 return -EINVAL; 234
235 return rc;
232} 236}
233 237
234static void destroy_power_saving_task(void) 238static void destroy_power_saving_task(void)
@@ -236,6 +240,7 @@ static void destroy_power_saving_task(void)
236 if (ps_tsk_num > 0) { 240 if (ps_tsk_num > 0) {
237 ps_tsk_num--; 241 ps_tsk_num--;
238 kthread_stop(ps_tsks[ps_tsk_num]); 242 kthread_stop(ps_tsks[ps_tsk_num]);
243 ps_tsks[ps_tsk_num] = NULL;
239 } 244 }
240} 245}
241 246
@@ -252,7 +257,7 @@ static void set_power_saving_task_num(unsigned int num)
252 } 257 }
253} 258}
254 259
255static int acpi_pad_idle_cpus(unsigned int num_cpus) 260static void acpi_pad_idle_cpus(unsigned int num_cpus)
256{ 261{
257 get_online_cpus(); 262 get_online_cpus();
258 263
@@ -260,7 +265,6 @@ static int acpi_pad_idle_cpus(unsigned int num_cpus)
260 set_power_saving_task_num(num_cpus); 265 set_power_saving_task_num(num_cpus);
261 266
262 put_online_cpus(); 267 put_online_cpus();
263 return 0;
264} 268}
265 269
266static uint32_t acpi_pad_idle_cpus_num(void) 270static uint32_t acpi_pad_idle_cpus_num(void)
@@ -368,19 +372,21 @@ static void acpi_pad_remove_sysfs(struct acpi_device *device)
368static int acpi_pad_pur(acpi_handle handle, int *num_cpus) 372static int acpi_pad_pur(acpi_handle handle, int *num_cpus)
369{ 373{
370 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; 374 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
371 acpi_status status;
372 union acpi_object *package; 375 union acpi_object *package;
373 int rev, num, ret = -EINVAL; 376 int rev, num, ret = -EINVAL;
374 377
375 status = acpi_evaluate_object(handle, "_PUR", NULL, &buffer); 378 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer)))
376 if (ACPI_FAILURE(status)) 379 return -EINVAL;
380
381 if (!buffer.length || !buffer.pointer)
377 return -EINVAL; 382 return -EINVAL;
383
378 package = buffer.pointer; 384 package = buffer.pointer;
379 if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2) 385 if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2)
380 goto out; 386 goto out;
381 rev = package->package.elements[0].integer.value; 387 rev = package->package.elements[0].integer.value;
382 num = package->package.elements[1].integer.value; 388 num = package->package.elements[1].integer.value;
383 if (rev != 1) 389 if (rev != 1 || num < 0)
384 goto out; 390 goto out;
385 *num_cpus = num; 391 *num_cpus = num;
386 ret = 0; 392 ret = 0;
@@ -409,7 +415,7 @@ static void acpi_pad_ost(acpi_handle handle, int stat,
409 415
410static void acpi_pad_handle_notify(acpi_handle handle) 416static void acpi_pad_handle_notify(acpi_handle handle)
411{ 417{
412 int num_cpus, ret; 418 int num_cpus;
413 uint32_t idle_cpus; 419 uint32_t idle_cpus;
414 420
415 mutex_lock(&isolated_cpus_lock); 421 mutex_lock(&isolated_cpus_lock);
@@ -417,12 +423,9 @@ static void acpi_pad_handle_notify(acpi_handle handle)
417 mutex_unlock(&isolated_cpus_lock); 423 mutex_unlock(&isolated_cpus_lock);
418 return; 424 return;
419 } 425 }
420 ret = acpi_pad_idle_cpus(num_cpus); 426 acpi_pad_idle_cpus(num_cpus);
421 idle_cpus = acpi_pad_idle_cpus_num(); 427 idle_cpus = acpi_pad_idle_cpus_num();
422 if (!ret) 428 acpi_pad_ost(handle, 0, idle_cpus);
423 acpi_pad_ost(handle, 0, idle_cpus);
424 else
425 acpi_pad_ost(handle, 1, 0);
426 mutex_unlock(&isolated_cpus_lock); 429 mutex_unlock(&isolated_cpus_lock);
427} 430}
428 431