Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Shilpasri G Bhat and committed by
Rafael J. Wysocki
96c4726f 6d167a44

+20 -3
+20 -3
drivers/cpufreq/powernv-cpufreq.c
··· 43 43 44 44 static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; 45 45 static bool rebooting, throttled, occ_reset; 46 + static unsigned int *core_to_chip_map; 46 47 47 48 static struct chip { 48 49 unsigned int id; ··· 314 313 static void powernv_cpufreq_throttle_check(void *data) 315 314 { 316 315 unsigned int cpu = smp_processor_id(); 316 + unsigned int chip_id = core_to_chip_map[cpu_core_index_of_thread(cpu)]; 317 317 unsigned long pmsr; 318 318 int pmsr_pmax, i; 319 319 320 320 pmsr = get_pmspr(SPRN_PMSR); 321 321 322 322 for (i = 0; i < nr_chips; i++) 323 - if (chips[i].id == cpu_to_chip_id(cpu)) 323 + if (chips[i].id == chip_id) 324 324 break; 325 325 326 326 /* Check for Pmax Capping */ ··· 561 559 unsigned int chip[256]; 562 560 unsigned int cpu, i; 563 561 unsigned int prev_chip_id = UINT_MAX; 562 + cpumask_t cpu_mask; 563 + int ret = -ENOMEM; 564 564 565 - for_each_possible_cpu(cpu) { 565 + core_to_chip_map = kcalloc(cpu_nr_cores(), sizeof(unsigned int), 566 + GFP_KERNEL); 567 + if (!core_to_chip_map) 568 + goto out; 569 + 570 + cpumask_copy(&cpu_mask, cpu_possible_mask); 571 + for_each_cpu(cpu, &cpu_mask) { 566 572 unsigned int id = cpu_to_chip_id(cpu); 567 573 568 574 if (prev_chip_id != id) { 569 575 prev_chip_id = id; 570 576 chip[nr_chips++] = id; 571 577 } 578 + core_to_chip_map[cpu_core_index_of_thread(cpu)] = id; 579 + cpumask_andnot(&cpu_mask, &cpu_mask, cpu_sibling_mask(cpu)); 572 580 } 573 581 574 582 chips = kmalloc_array(nr_chips, sizeof(struct chip), GFP_KERNEL); 575 583 if (!chips) 576 - return -ENOMEM; 584 + goto free_chip_map; 577 585 578 586 for (i = 0; i < nr_chips; i++) { 579 587 chips[i].id = chip[i]; ··· 594 582 } 595 583 596 584 return 0; 585 + free_chip_map: 586 + kfree(core_to_chip_map); 587 + out: 588 + return ret; 597 589 } 598 590 599 591 static int __init powernv_cpufreq_init(void) ··· 632 616 opal_message_notifier_unregister(OPAL_MSG_OCC, 633 617 &powernv_cpufreq_opal_nb); 634 618 kfree(chips); 619 + kfree(core_to_chip_map); 635 620 cpufreq_unregister_driver(&powernv_cpufreq_driver); 636 621 } 637 622 module_exit(powernv_cpufreq_exit);