[PATCH 13/13] hperf_hmp: cpufreq routines.
From: Arseniy Krasnov
Date: Fri Nov 06 2015 - 07:03:56 EST
Adds CPU frequency change notifier in fair scheduling class. Every time
when governor changes frequency, it calls callback from this patch. Frequency of
each CPU is used for imbalance calculation.
Signed-off-by: Tarek Dakhran <t.dakhran@xxxxxxxxxxx>
Signed-off-by: Sergey Dyasly <s.dyasly@xxxxxxxxxxx>
Signed-off-by: Dmitriy Safonov <d.safonov@xxxxxxxxxxxxxxxxxxx>
Signed-off-by: Arseniy Krasnov <a.krasnov@xxxxxxxxxxx>
Signed-off-by: Ilya Maximets <i.maximets@xxxxxxxxxxx>
---
kernel/sched/fair.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 06f6518..87dc0db 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -33,6 +33,10 @@
#include <trace/events/sched.h>
+#ifdef CONFIG_HPERF_HMP
+#include <linux/cpufreq.h>
+#endif
+
#include "sched.h"
/*
@@ -101,6 +105,11 @@ const_debug unsigned int sysctl_sched_migration_cost = 500000UL;
unsigned int __read_mostly sysctl_sched_shares_window = 10000000UL;
#ifdef CONFIG_HPERF_HMP
+/*
+ * Log level of hperf_hmp messages. Bigger means more messages.
+ * Maximum level is 3.
+ */
+unsigned int sysctl_sched_hperf_hmp_log_level;
extern void hmp_set_cpu_masks(struct cpumask *, struct cpumask *);
static atomic_t a15_nr_hmp_busy = ATOMIC_INIT(0);
static atomic_t a7_nr_hmp_busy = ATOMIC_INIT(0);
@@ -7229,6 +7238,73 @@ static int should_we_balance(struct lb_env *env)
return balance_cpu == env->dst_cpu;
}
#ifdef CONFIG_HPERF_HMP
+static void hperf_hmp_vprint(unsigned int log_level, const char *format,
+ va_list ap)
+{
+ if (sysctl_sched_hperf_hmp_log_level < log_level)
+ return;
+ vprintk(format, ap);
+}
+
+static void hperf_hmp_print(unsigned int log_level, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ hperf_hmp_vprint(log_level, format, ap);
+ va_end(ap);
+}
+
+/* Called when frequency is changed */
+static int hmp_cpufreq_callback(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct cpufreq_freqs *new_freq = data;
+
+ /* recount power only after change of frequency */
+ if (event != CPUFREQ_POSTCHANGE)
+ return NOTIFY_DONE;
+
+ if (!new_freq)
+ return NOTIFY_DONE;
+
+ freq_scale_cpu_power[new_freq->cpu] = (new_freq->new >> 10);
+
+ /* Apply slowdown coefficient of 1.9 for A7 CPUs */
+ if (!cpu_is_fastest(new_freq->cpu)) {
+ freq_scale_cpu_power[new_freq->cpu] *= 10;
+ freq_scale_cpu_power[new_freq->cpu] /= 19;
+ }
+
+ hperf_hmp_print(2, KERN_INFO "hperf_hmp: CPU#%i new frequency is: %u MHz\n",
+ new_freq->cpu, new_freq->new / 1000);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block cpufreq_notifier = {
+ .notifier_call = hmp_cpufreq_callback
+};
+
+static int __init register_sched_cpufreq_notifier(void)
+{
+ int err = 0;
+ int cpu;
+
+ for_each_online_cpu(cpu)
+ freq_scale_cpu_power[cpu] = capacity_of(cpu);
+
+ err = cpufreq_register_notifier(&cpufreq_notifier,
+ CPUFREQ_TRANSITION_NOTIFIER);
+ if (!err)
+ pr_info("hperf_hmp: registered cpufreq transition notifier\n");
+ else
+ pr_info("hperf_hmp: failed to register cpufreq notifier!\n");
+
+ return err;
+}
+core_initcall(register_sched_cpufreq_notifier);
+
/**
* is_hmp_imbalance(): Calculates imbalance between HMP domains.
* @sd: Current sched domain.
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/