Merge branch 'pm-cpufreq'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 13 Nov 2017 00:34:49 +0000 (01:34 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 13 Nov 2017 00:34:49 +0000 (01:34 +0100)
* pm-cpufreq: (22 commits)
  cpufreq: stats: Handle the case when trans_table goes beyond PAGE_SIZE
  cpufreq: arm_big_little: make cpufreq_arm_bL_ops structures const
  cpufreq: arm_big_little: make function arguments and structure pointer const
  cpufreq: pxa: convert to clock API
  cpufreq: speedstep-lib: mark expected switch fall-through
  cpufreq: ti-cpufreq: add missing of_node_put()
  cpufreq: dt: Remove support for Exynos4212 SoCs
  cpufreq: imx6q: Move speed grading check to cpufreq driver
  cpufreq: ti-cpufreq: kfree opp_data when failure
  cpufreq: SPEAr: pr_err() strings should end with newlines
  cpufreq: powernow-k8: pr_err() strings should end with newlines
  cpufreq: dt-platdev: drop socionext,uniphier-ld6b from whitelist
  arm64: wire cpu-invariant accounting support up to the task scheduler
  arm64: wire frequency-invariant accounting support up to the task scheduler
  arm: wire cpu-invariant accounting support up to the task scheduler
  arm: wire frequency-invariant accounting support up to the task scheduler
  drivers base/arch_topology: allow inlining cpu-invariant accounting support
  drivers base/arch_topology: provide frequency-invariant accounting support
  cpufreq: dt: invoke frequency-invariance setter function
  cpufreq: arm_big_little: invoke frequency-invariance setter function
  ...

1  2 
arch/arm/include/asm/topology.h
arch/arm64/include/asm/topology.h
drivers/base/arch_topology.c
include/linux/arch_topology.h

index f59ab9bcbaf956b8cac5568e62c54de17a7cd648,b713e7223bc47b32d2ad97e0bed0f20bf05f8981..5d88d2f22b2cc5d62ccc883cded7693605134084
@@@ -1,4 -1,3 +1,4 @@@
 +/* SPDX-License-Identifier: GPL-2.0 */
  #ifndef _ASM_ARM_TOPOLOGY_H
  #define _ASM_ARM_TOPOLOGY_H
  
@@@ -25,6 -24,14 +25,14 @@@ void init_cpu_topology(void)
  void store_cpu_topology(unsigned int cpuid);
  const struct cpumask *cpu_coregroup_mask(int cpu);
  
+ #include <linux/arch_topology.h>
+ /* Replace task scheduler's default frequency-invariant accounting */
+ #define arch_scale_freq_capacity topology_get_freq_scale
+ /* Replace task scheduler's default cpu-invariant accounting */
+ #define arch_scale_cpu_capacity topology_get_cpu_scale
  #else
  
  static inline void init_cpu_topology(void) { }
index b3202284568b2e86708b6bc59800053995aa739b,e313eeb10756f491d337ea9942cf798a02ed3cc4..c4f2d50491eb113fad8894b6df20cca4083e0858
@@@ -1,4 -1,3 +1,4 @@@
 +/* SPDX-License-Identifier: GPL-2.0 */
  #ifndef __ASM_TOPOLOGY_H
  #define __ASM_TOPOLOGY_H
  
@@@ -33,6 -32,14 +33,14 @@@ int pcibus_to_node(struct pci_bus *bus)
  
  #endif /* CONFIG_NUMA */
  
+ #include <linux/arch_topology.h>
+ /* Replace task scheduler's default frequency-invariant accounting */
+ #define arch_scale_freq_capacity topology_get_freq_scale
+ /* Replace task scheduler's default cpu-invariant accounting */
+ #define arch_scale_cpu_capacity topology_get_cpu_scale
  #include <asm-generic/topology.h>
  
  #endif /* _ASM_ARM_TOPOLOGY_H */
index 6df7d6676a48104267b5e739c6e58b85a00724e1,aea0b9d521f6e832648255d72a12fd99aef4c313..0739c5b953bf8ab1b1f48d8df9a14cc9fcb76731
  #include <linux/string.h>
  #include <linux/sched/topology.h>
  
- static DEFINE_MUTEX(cpu_scale_mutex);
- static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE;
+ DEFINE_PER_CPU(unsigned long, freq_scale) = SCHED_CAPACITY_SCALE;
  
- unsigned long topology_get_cpu_scale(struct sched_domain *sd, int cpu)
+ void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq,
+                        unsigned long max_freq)
  {
-       return per_cpu(cpu_scale, cpu);
+       unsigned long scale;
+       int i;
+       scale = (cur_freq << SCHED_CAPACITY_SHIFT) / max_freq;
+       for_each_cpu(i, cpus)
+               per_cpu(freq_scale, i) = scale;
  }
  
+ static DEFINE_MUTEX(cpu_scale_mutex);
+ DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE;
  void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity)
  {
        per_cpu(cpu_scale, cpu) = capacity;
@@@ -166,11 -175,11 +175,11 @@@ bool __init topology_parse_cpu_capacity
  }
  
  #ifdef CONFIG_CPU_FREQ
 -static cpumask_var_t cpus_to_visit;
 -static void parsing_done_workfn(struct work_struct *work);
 -static DECLARE_WORK(parsing_done_work, parsing_done_workfn);
 +static cpumask_var_t cpus_to_visit __initdata;
 +static void __init parsing_done_workfn(struct work_struct *work);
 +static __initdata DECLARE_WORK(parsing_done_work, parsing_done_workfn);
  
 -static int
 +static int __init
  init_cpu_capacity_callback(struct notifier_block *nb,
                           unsigned long val,
                           void *data)
        return 0;
  }
  
 -static struct notifier_block init_cpu_capacity_notifier = {
 +static struct notifier_block init_cpu_capacity_notifier __initdata = {
        .notifier_call = init_cpu_capacity_callback,
  };
  
  static int __init register_cpufreq_notifier(void)
  {
+       int ret;
        /*
         * on ACPI-based systems we need to use the default cpu capacity
         * until we have the necessary code to parse the cpu capacity, so
  
        cpumask_copy(cpus_to_visit, cpu_possible_mask);
  
-       return cpufreq_register_notifier(&init_cpu_capacity_notifier,
-                                        CPUFREQ_POLICY_NOTIFIER);
+       ret = cpufreq_register_notifier(&init_cpu_capacity_notifier,
+                                       CPUFREQ_POLICY_NOTIFIER);
+       if (ret)
+               free_cpumask_var(cpus_to_visit);
+       return ret;
  }
  core_initcall(register_cpufreq_notifier);
  
 -static void parsing_done_workfn(struct work_struct *work)
 +static void __init parsing_done_workfn(struct work_struct *work)
  {
        cpufreq_unregister_notifier(&init_cpu_capacity_notifier,
                                         CPUFREQ_POLICY_NOTIFIER);
+       free_cpumask_var(cpus_to_visit);
  }
  
  #else
index d4fcb0efb896c3e4a40cb527c4da531bc58b3831,c189de3ef5dfa976cf6c4bf490f86aee9956bc50..304511267c823d0fb398839a977d5b31f1f037e6
@@@ -1,4 -1,3 +1,4 @@@
 +/* SPDX-License-Identifier: GPL-2.0 */
  /*
   * include/linux/arch_topology.h - arch specific cpu topology information
   */
@@@ -6,15 -5,30 +6,30 @@@
  #define _LINUX_ARCH_TOPOLOGY_H_
  
  #include <linux/types.h>
+ #include <linux/percpu.h>
  
  void topology_normalize_cpu_scale(void);
  
  struct device_node;
  bool topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu);
  
+ DECLARE_PER_CPU(unsigned long, cpu_scale);
  struct sched_domain;
- unsigned long topology_get_cpu_scale(struct sched_domain *sd, int cpu);
+ static inline
+ unsigned long topology_get_cpu_scale(struct sched_domain *sd, int cpu)
+ {
+       return per_cpu(cpu_scale, cpu);
+ }
  
  void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity);
  
+ DECLARE_PER_CPU(unsigned long, freq_scale);
+ static inline
+ unsigned long topology_get_freq_scale(struct sched_domain *sd, int cpu)
+ {
+       return per_cpu(freq_scale, cpu);
+ }
  #endif /* _LINUX_ARCH_TOPOLOGY_H_ */