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 /drivers | |
parent | 77cff3b0d6349cc0212056238108b827b3cc353b (diff) | |
parent | 5a344a505093dd65f82f338ffdb7208321b3630e (diff) |
Merge branch 'throttling' into release
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/processor_driver.c | 5 | ||||
-rw-r--r-- | drivers/acpi/processor_throttling.c | 76 |
2 files changed, 78 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; |