diff options
| author | Len Brown <len.brown@intel.com> | 2011-01-12 05:01:08 -0500 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2011-01-12 05:01:08 -0500 |
| commit | fe3ded5078e957d80c43837e1966429cf0029c10 (patch) | |
| tree | 3d119165a177c5aef9490defde861c4e733191e6 | |
| parent | 77cff3b0d6349cc0212056238108b827b3cc353b (diff) | |
| parent | 5a344a505093dd65f82f338ffdb7208321b3630e (diff) | |
Merge branch 'throttling' into release
| -rw-r--r-- | drivers/acpi/processor_driver.c | 5 | ||||
| -rw-r--r-- | drivers/acpi/processor_throttling.c | 76 | ||||
| -rw-r--r-- | include/acpi/processor.h | 6 |
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 | */ | ||
| 377 | void 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 | |||
| 416 | end: | ||
| 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 | */ |
| 371 | static int acpi_processor_get_throttling_control(struct acpi_processor *pr) | 423 | static 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, ¤t->cpus_allowed); | 925 | cpumask_copy(saved_mask, ¤t->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, ¤t->cpus_allowed); | 1114 | cpumask_copy(saved_mask, ¤t->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); |
| 1194 | exit: | ||
| 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); | |||
| 324 | int acpi_processor_get_throttling_info(struct acpi_processor *pr); | 324 | int acpi_processor_get_throttling_info(struct acpi_processor *pr); |
| 325 | extern int acpi_processor_set_throttling(struct acpi_processor *pr, | 325 | extern 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 | */ | ||
| 331 | extern void acpi_processor_reevaluate_tstate(struct acpi_processor *pr, | ||
| 332 | unsigned long action); | ||
| 327 | extern const struct file_operations acpi_processor_throttling_fops; | 333 | extern const struct file_operations acpi_processor_throttling_fops; |
| 328 | extern void acpi_processor_throttling_init(void); | 334 | extern void acpi_processor_throttling_init(void); |
| 329 | /* in processor_idle.c */ | 335 | /* in processor_idle.c */ |
