aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2011-01-12 05:01:08 -0500
committerLen Brown <len.brown@intel.com>2011-01-12 05:01:08 -0500
commitfe3ded5078e957d80c43837e1966429cf0029c10 (patch)
tree3d119165a177c5aef9490defde861c4e733191e6
parent77cff3b0d6349cc0212056238108b827b3cc353b (diff)
parent5a344a505093dd65f82f338ffdb7208321b3630e (diff)
Merge branch 'throttling' into release
-rw-r--r--drivers/acpi/processor_driver.c5
-rw-r--r--drivers/acpi/processor_throttling.c76
-rw-r--r--include/acpi/processor.h6
3 files changed, 84 insertions, 3 deletions
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 29572debc65d..360a74e6add0 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -427,8 +427,13 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
427 if (action == CPU_ONLINE && pr) { 427 if (action == CPU_ONLINE && pr) {
428 acpi_processor_ppc_has_changed(pr, 0); 428 acpi_processor_ppc_has_changed(pr, 0);
429 acpi_processor_cst_has_changed(pr); 429 acpi_processor_cst_has_changed(pr);
430 acpi_processor_reevaluate_tstate(pr, action);
430 acpi_processor_tstate_has_changed(pr); 431 acpi_processor_tstate_has_changed(pr);
431 } 432 }
433 if (action == CPU_DEAD && pr) {
434 /* invalidate the flag.throttling after one CPU is offline */
435 acpi_processor_reevaluate_tstate(pr, action);
436 }
432 return NOTIFY_OK; 437 return NOTIFY_OK;
433} 438}
434 439
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 4a0eec5dd24a..fa84e9744330 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -366,6 +366,58 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
366} 366}
367 367
368/* 368/*
369 * This function is used to reevaluate whether the T-state is valid
370 * after one CPU is onlined/offlined.
371 * It is noted that it won't reevaluate the following properties for
372 * the T-state.
373 * 1. Control method.
374 * 2. the number of supported T-state
375 * 3. TSD domain
376 */
377void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
378 unsigned long action)
379{
380 int result = 0;
381
382 if (action == CPU_DEAD) {
383 /* When one CPU is offline, the T-state throttling
384 * will be invalidated.
385 */
386 pr->flags.throttling = 0;
387 return;
388 }
389 /* the following is to recheck whether the T-state is valid for
390 * the online CPU
391 */
392 if (!pr->throttling.state_count) {
393 /* If the number of T-state is invalid, it is
394 * invalidated.
395 */
396 pr->flags.throttling = 0;
397 return;
398 }
399 pr->flags.throttling = 1;
400
401 /* Disable throttling (if enabled). We'll let subsequent
402 * policy (e.g.thermal) decide to lower performance if it
403 * so chooses, but for now we'll crank up the speed.
404 */
405
406 result = acpi_processor_get_throttling(pr);
407 if (result)
408 goto end;
409
410 if (pr->throttling.state) {
411 result = acpi_processor_set_throttling(pr, 0, false);
412 if (result)
413 goto end;
414 }
415
416end:
417 if (result)
418 pr->flags.throttling = 0;
419}
420/*
369 * _PTC - Processor Throttling Control (and status) register location 421 * _PTC - Processor Throttling Control (and status) register location
370 */ 422 */
371static int acpi_processor_get_throttling_control(struct acpi_processor *pr) 423static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
@@ -872,7 +924,11 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr)
872 */ 924 */
873 cpumask_copy(saved_mask, &current->cpus_allowed); 925 cpumask_copy(saved_mask, &current->cpus_allowed);
874 /* FIXME: use work_on_cpu() */ 926 /* FIXME: use work_on_cpu() */
875 set_cpus_allowed_ptr(current, cpumask_of(pr->id)); 927 if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
928 /* Can't migrate to the target pr->id CPU. Exit */
929 free_cpumask_var(saved_mask);
930 return -ENODEV;
931 }
876 ret = pr->throttling.acpi_processor_get_throttling(pr); 932 ret = pr->throttling.acpi_processor_get_throttling(pr);
877 /* restore the previous state */ 933 /* restore the previous state */
878 set_cpus_allowed_ptr(current, saved_mask); 934 set_cpus_allowed_ptr(current, saved_mask);
@@ -1047,6 +1103,14 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
1047 return -ENOMEM; 1103 return -ENOMEM;
1048 } 1104 }
1049 1105
1106 if (cpu_is_offline(pr->id)) {
1107 /*
1108 * the cpu pointed by pr->id is offline. Unnecessary to change
1109 * the throttling state any more.
1110 */
1111 return -ENODEV;
1112 }
1113
1050 cpumask_copy(saved_mask, &current->cpus_allowed); 1114 cpumask_copy(saved_mask, &current->cpus_allowed);
1051 t_state.target_state = state; 1115 t_state.target_state = state;
1052 p_throttling = &(pr->throttling); 1116 p_throttling = &(pr->throttling);
@@ -1070,7 +1134,11 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
1070 */ 1134 */
1071 if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) { 1135 if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) {
1072 /* FIXME: use work_on_cpu() */ 1136 /* FIXME: use work_on_cpu() */
1073 set_cpus_allowed_ptr(current, cpumask_of(pr->id)); 1137 if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
1138 /* Can't migrate to the pr->id CPU. Exit */
1139 ret = -ENODEV;
1140 goto exit;
1141 }
1074 ret = p_throttling->acpi_processor_set_throttling(pr, 1142 ret = p_throttling->acpi_processor_set_throttling(pr,
1075 t_state.target_state, force); 1143 t_state.target_state, force);
1076 } else { 1144 } else {
@@ -1102,7 +1170,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
1102 } 1170 }
1103 t_state.cpu = i; 1171 t_state.cpu = i;
1104 /* FIXME: use work_on_cpu() */ 1172 /* FIXME: use work_on_cpu() */
1105 set_cpus_allowed_ptr(current, cpumask_of(i)); 1173 if (set_cpus_allowed_ptr(current, cpumask_of(i)))
1174 continue;
1106 ret = match_pr->throttling. 1175 ret = match_pr->throttling.
1107 acpi_processor_set_throttling( 1176 acpi_processor_set_throttling(
1108 match_pr, t_state.target_state, force); 1177 match_pr, t_state.target_state, force);
@@ -1122,6 +1191,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
1122 /* restore the previous state */ 1191 /* restore the previous state */
1123 /* FIXME: use work_on_cpu() */ 1192 /* FIXME: use work_on_cpu() */
1124 set_cpus_allowed_ptr(current, saved_mask); 1193 set_cpus_allowed_ptr(current, saved_mask);
1194exit:
1125 free_cpumask_var(online_throttling_cpus); 1195 free_cpumask_var(online_throttling_cpus);
1126 free_cpumask_var(saved_mask); 1196 free_cpumask_var(saved_mask);
1127 return ret; 1197 return ret;
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 1b62102fbb67..55192ac0cede 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -324,6 +324,12 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
324int acpi_processor_get_throttling_info(struct acpi_processor *pr); 324int acpi_processor_get_throttling_info(struct acpi_processor *pr);
325extern int acpi_processor_set_throttling(struct acpi_processor *pr, 325extern int acpi_processor_set_throttling(struct acpi_processor *pr,
326 int state, bool force); 326 int state, bool force);
327/*
328 * Reevaluate whether the T-state is invalid after one cpu is
329 * onlined/offlined. In such case the flags.throttling will be updated.
330 */
331extern void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
332 unsigned long action);
327extern const struct file_operations acpi_processor_throttling_fops; 333extern const struct file_operations acpi_processor_throttling_fops;
328extern void acpi_processor_throttling_init(void); 334extern void acpi_processor_throttling_init(void);
329/* in processor_idle.c */ 335/* in processor_idle.c */