aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2016-03-21 12:54:52 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-03-21 20:08:55 -0400
commit3e5963bc343b3fb4ca045e9d1c14cb9ce89234b8 (patch)
tree216fb97bcf417def706207afe7e44f77fb6d8c53
parented72662a84771fec1337dd8b187e070af6fd3890 (diff)
cpufreq: powernv: Define per_cpu chip pointer to optimize hot-path
Commit 96c4726f01cd "cpufreq: powernv: Remove cpu_to_chip_id() from hot-path" introduced a 'core_to_chip_map' array to cache the chip-ids of all cores. Replace this with a per-CPU variable that stores the pointer to the chip-array. This removes the linear lookup and provides a neater and simpler solution. Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/cpufreq/powernv-cpufreq.c50
1 files changed, 17 insertions, 33 deletions
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
index 50bf12033bbc..a00bcc2cef09 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -44,7 +44,6 @@
44 44
45static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; 45static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1];
46static bool rebooting, throttled, occ_reset; 46static bool rebooting, throttled, occ_reset;
47static unsigned int *core_to_chip_map;
48 47
49static const char * const throttle_reason[] = { 48static const char * const throttle_reason[] = {
50 "No throttling", 49 "No throttling",
@@ -65,6 +64,7 @@ static struct chip {
65} *chips; 64} *chips;
66 65
67static int nr_chips; 66static int nr_chips;
67static DEFINE_PER_CPU(struct chip *, chip_info);
68 68
69/* 69/*
70 * Note: The set of pstates consists of contiguous integers, the 70 * Note: The set of pstates consists of contiguous integers, the
@@ -324,34 +324,31 @@ static inline unsigned int get_nominal_index(void)
324 324
325static void powernv_cpufreq_throttle_check(void *data) 325static void powernv_cpufreq_throttle_check(void *data)
326{ 326{
327 struct chip *chip;
327 unsigned int cpu = smp_processor_id(); 328 unsigned int cpu = smp_processor_id();
328 unsigned int chip_id = core_to_chip_map[cpu_core_index_of_thread(cpu)];
329 unsigned long pmsr; 329 unsigned long pmsr;
330 int pmsr_pmax, i; 330 int pmsr_pmax;
331 331
332 pmsr = get_pmspr(SPRN_PMSR); 332 pmsr = get_pmspr(SPRN_PMSR);
333 333 chip = this_cpu_read(chip_info);
334 for (i = 0; i < nr_chips; i++)
335 if (chips[i].id == chip_id)
336 break;
337 334
338 /* Check for Pmax Capping */ 335 /* Check for Pmax Capping */
339 pmsr_pmax = (s8)PMSR_MAX(pmsr); 336 pmsr_pmax = (s8)PMSR_MAX(pmsr);
340 if (pmsr_pmax != powernv_pstate_info.max) { 337 if (pmsr_pmax != powernv_pstate_info.max) {
341 if (chips[i].throttled) 338 if (chip->throttled)
342 goto next; 339 goto next;
343 chips[i].throttled = true; 340 chip->throttled = true;
344 if (pmsr_pmax < powernv_pstate_info.nominal) 341 if (pmsr_pmax < powernv_pstate_info.nominal)
345 pr_warn_once("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n", 342 pr_warn_once("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n",
346 cpu, chips[i].id, pmsr_pmax, 343 cpu, chip->id, pmsr_pmax,
347 powernv_pstate_info.nominal); 344 powernv_pstate_info.nominal);
348 trace_powernv_throttle(chips[i].id, 345 trace_powernv_throttle(chip->id,
349 throttle_reason[chips[i].throttle_reason], 346 throttle_reason[chip->throttle_reason],
350 pmsr_pmax); 347 pmsr_pmax);
351 } else if (chips[i].throttled) { 348 } else if (chip->throttled) {
352 chips[i].throttled = false; 349 chip->throttled = false;
353 trace_powernv_throttle(chips[i].id, 350 trace_powernv_throttle(chip->id,
354 throttle_reason[chips[i].throttle_reason], 351 throttle_reason[chip->throttle_reason],
355 pmsr_pmax); 352 pmsr_pmax);
356 } 353 }
357 354
@@ -558,47 +555,34 @@ static int init_chip_info(void)
558 unsigned int chip[256]; 555 unsigned int chip[256];
559 unsigned int cpu, i; 556 unsigned int cpu, i;
560 unsigned int prev_chip_id = UINT_MAX; 557 unsigned int prev_chip_id = UINT_MAX;
561 cpumask_t cpu_mask;
562 int ret = -ENOMEM;
563
564 core_to_chip_map = kcalloc(cpu_nr_cores(), sizeof(unsigned int),
565 GFP_KERNEL);
566 if (!core_to_chip_map)
567 goto out;
568 558
569 cpumask_copy(&cpu_mask, cpu_possible_mask); 559 for_each_possible_cpu(cpu) {
570 for_each_cpu(cpu, &cpu_mask) {
571 unsigned int id = cpu_to_chip_id(cpu); 560 unsigned int id = cpu_to_chip_id(cpu);
572 561
573 if (prev_chip_id != id) { 562 if (prev_chip_id != id) {
574 prev_chip_id = id; 563 prev_chip_id = id;
575 chip[nr_chips++] = id; 564 chip[nr_chips++] = id;
576 } 565 }
577 core_to_chip_map[cpu_core_index_of_thread(cpu)] = id;
578 cpumask_andnot(&cpu_mask, &cpu_mask, cpu_sibling_mask(cpu));
579 } 566 }
580 567
581 chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL); 568 chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL);
582 if (!chips) 569 if (!chips)
583 goto free_chip_map; 570 return -ENOMEM;
584 571
585 for (i = 0; i < nr_chips; i++) { 572 for (i = 0; i < nr_chips; i++) {
586 chips[i].id = chip[i]; 573 chips[i].id = chip[i];
587 cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i])); 574 cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i]));
588 INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn); 575 INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn);
576 for_each_cpu(cpu, &chips[i].mask)
577 per_cpu(chip_info, cpu) = &chips[i];
589 } 578 }
590 579
591 return 0; 580 return 0;
592free_chip_map:
593 kfree(core_to_chip_map);
594out:
595 return ret;
596} 581}
597 582
598static inline void clean_chip_info(void) 583static inline void clean_chip_info(void)
599{ 584{
600 kfree(chips); 585 kfree(chips);
601 kfree(core_to_chip_map);
602} 586}
603 587
604static inline void unregister_all_notifiers(void) 588static inline void unregister_all_notifiers(void)