diff options
author | Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> | 2016-02-02 14:41:39 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-02-04 20:38:02 -0500 |
commit | 96c4726f01cdbf53acf74cf2394e287d74bf40a3 (patch) | |
tree | 65370c8647c10d1e32d14ba3ecb14db0bd875e50 /drivers/cpufreq/powernv-cpufreq.c | |
parent | 6d167a44e6c8da3316e037b788585fcf96112bea (diff) |
cpufreq: powernv: Remove cpu_to_chip_id() from hot-path
cpu_to_chip_id() does a DT walk through to find out the chip id by
taking a contended device tree lock. This adds an unnecessary overhead
in a hot path. So instead of calling cpu_to_chip_id() everytime cache
the chip ids for all cores in the array 'core_to_chip_map' and use it
in the hotpath.
Reported-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
Reviewed-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/powernv-cpufreq.c')
-rw-r--r-- | drivers/cpufreq/powernv-cpufreq.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index a271b0fbe8b9..c670314053af 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c | |||
@@ -43,6 +43,7 @@ | |||
43 | 43 | ||
44 | static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; | 44 | static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; |
45 | static bool rebooting, throttled, occ_reset; | 45 | static bool rebooting, throttled, occ_reset; |
46 | static unsigned int *core_to_chip_map; | ||
46 | 47 | ||
47 | static struct chip { | 48 | static struct chip { |
48 | unsigned int id; | 49 | unsigned int id; |
@@ -313,13 +314,14 @@ static inline unsigned int get_nominal_index(void) | |||
313 | static void powernv_cpufreq_throttle_check(void *data) | 314 | static void powernv_cpufreq_throttle_check(void *data) |
314 | { | 315 | { |
315 | unsigned int cpu = smp_processor_id(); | 316 | unsigned int cpu = smp_processor_id(); |
317 | unsigned int chip_id = core_to_chip_map[cpu_core_index_of_thread(cpu)]; | ||
316 | unsigned long pmsr; | 318 | unsigned long pmsr; |
317 | int pmsr_pmax, i; | 319 | int pmsr_pmax, i; |
318 | 320 | ||
319 | pmsr = get_pmspr(SPRN_PMSR); | 321 | pmsr = get_pmspr(SPRN_PMSR); |
320 | 322 | ||
321 | for (i = 0; i < nr_chips; i++) | 323 | for (i = 0; i < nr_chips; i++) |
322 | if (chips[i].id == cpu_to_chip_id(cpu)) | 324 | if (chips[i].id == chip_id) |
323 | break; | 325 | break; |
324 | 326 | ||
325 | /* Check for Pmax Capping */ | 327 | /* Check for Pmax Capping */ |
@@ -559,19 +561,29 @@ static int init_chip_info(void) | |||
559 | unsigned int chip[256]; | 561 | unsigned int chip[256]; |
560 | unsigned int cpu, i; | 562 | unsigned int cpu, i; |
561 | unsigned int prev_chip_id = UINT_MAX; | 563 | unsigned int prev_chip_id = UINT_MAX; |
564 | cpumask_t cpu_mask; | ||
565 | int ret = -ENOMEM; | ||
562 | 566 | ||
563 | for_each_possible_cpu(cpu) { | 567 | core_to_chip_map = kcalloc(cpu_nr_cores(), sizeof(unsigned int), |
568 | GFP_KERNEL); | ||
569 | if (!core_to_chip_map) | ||
570 | goto out; | ||
571 | |||
572 | cpumask_copy(&cpu_mask, cpu_possible_mask); | ||
573 | for_each_cpu(cpu, &cpu_mask) { | ||
564 | unsigned int id = cpu_to_chip_id(cpu); | 574 | unsigned int id = cpu_to_chip_id(cpu); |
565 | 575 | ||
566 | if (prev_chip_id != id) { | 576 | if (prev_chip_id != id) { |
567 | prev_chip_id = id; | 577 | prev_chip_id = id; |
568 | chip[nr_chips++] = id; | 578 | chip[nr_chips++] = id; |
569 | } | 579 | } |
580 | core_to_chip_map[cpu_core_index_of_thread(cpu)] = id; | ||
581 | cpumask_andnot(&cpu_mask, &cpu_mask, cpu_sibling_mask(cpu)); | ||
570 | } | 582 | } |
571 | 583 | ||
572 | chips = kmalloc_array(nr_chips, sizeof(struct chip), GFP_KERNEL); | 584 | chips = kmalloc_array(nr_chips, sizeof(struct chip), GFP_KERNEL); |
573 | if (!chips) | 585 | if (!chips) |
574 | return -ENOMEM; | 586 | goto free_chip_map; |
575 | 587 | ||
576 | for (i = 0; i < nr_chips; i++) { | 588 | for (i = 0; i < nr_chips; i++) { |
577 | chips[i].id = chip[i]; | 589 | chips[i].id = chip[i]; |
@@ -582,6 +594,10 @@ static int init_chip_info(void) | |||
582 | } | 594 | } |
583 | 595 | ||
584 | return 0; | 596 | return 0; |
597 | free_chip_map: | ||
598 | kfree(core_to_chip_map); | ||
599 | out: | ||
600 | return ret; | ||
585 | } | 601 | } |
586 | 602 | ||
587 | static int __init powernv_cpufreq_init(void) | 603 | static int __init powernv_cpufreq_init(void) |
@@ -616,6 +632,7 @@ static void __exit powernv_cpufreq_exit(void) | |||
616 | opal_message_notifier_unregister(OPAL_MSG_OCC, | 632 | opal_message_notifier_unregister(OPAL_MSG_OCC, |
617 | &powernv_cpufreq_opal_nb); | 633 | &powernv_cpufreq_opal_nb); |
618 | kfree(chips); | 634 | kfree(chips); |
635 | kfree(core_to_chip_map); | ||
619 | cpufreq_unregister_driver(&powernv_cpufreq_driver); | 636 | cpufreq_unregister_driver(&powernv_cpufreq_driver); |
620 | } | 637 | } |
621 | module_exit(powernv_cpufreq_exit); | 638 | module_exit(powernv_cpufreq_exit); |