summaryrefslogtreecommitdiffstats
path: root/meta-eas/recipes-kernel/linux/linux-renesas/0069-arm64-Cpu-invariant-scheduler-load-tracking-and-capa.patch
blob: 50d6766be02bc4f04ac91f74f631ae835a853e5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
From 4e480c5d43dc3cee5c0b7664d0ee394d1206d994 Mon Sep 17 00:00:00 2001
From: Juri Lelli <juri.lelli@arm.com>
Date: Thu, 30 Apr 2015 11:53:48 +0100
Subject: [PATCH 69/92] arm64: Cpu invariant scheduler load-tracking and
 capacity support

Provides the scheduler with a cpu scaling correction factor for more
accurate load-tracking and cpu capacity handling.

The Energy Model (EM) (in fact the capacity value of the last element
of the capacity states vector of the core (MC) level sched_group_energy
structure) is used as the source for this cpu scaling factor.

The cpu capacity value depends on the micro-architecture and the
maximum frequency of the cpu.

The maximum frequency part should not be confused with the frequency
invariant scheduler load-tracking support which deals with frequency
related scaling due to DFVS functionality.

Signed-off-by: Juri Lelli <juri.lelli@arm.com>
Signed-off-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
(cherry picked from commit ea98c1ac6d9b31033caa1f29ed1b8b707f437ae8)
Signed-off-by: Gaku Inami <gaku.inami.xw@bp.renesas.com>
---
 arch/arm64/kernel/topology.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index a75db2b..761fcb6 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -172,12 +172,17 @@ static void __init parse_cpu_capacity(struct device_node *cpu_node, int cpu)
 	}
 }
 
+static const struct sched_group_energy * const cpu_core_energy(int cpu);
+
 static void normalize_cpu_capacity(void)
 {
 	u64 capacity;
 	int cpu;
 	bool asym = false;
 
+	if (cpu_core_energy(0))
+		return;
+
 	if (!raw_capacity || cap_parsing_failed)
 		return;
 
@@ -667,6 +672,26 @@ static int cpu_coregroup_flags(void)
 	return mc_flags;
 }
 
+static void update_cpu_capacity(unsigned int cpu)
+{
+	unsigned long capacity;
+	int max_cap_idx;
+
+	if (!cpu_core_energy(cpu))
+		return;
+
+	max_cap_idx = cpu_core_energy(cpu)->nr_cap_states - 1;
+	capacity = cpu_core_energy(cpu)->cap_states[max_cap_idx].cap;
+
+	set_capacity_scale(cpu, capacity);
+
+	if (capacity < SCHED_CAPACITY_SCALE)
+		asym_cpucap = true;
+
+	pr_info("CPU%d: update cpu_capacity %lu\n",
+		cpu, arch_scale_cpu_capacity(NULL, cpu));
+}
+
 static void update_siblings_masks(unsigned int cpuid)
 {
 	struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
@@ -728,6 +753,7 @@ void store_cpu_topology(unsigned int cpuid)
 
 topology_populated:
 	update_siblings_masks(cpuid);
+	update_cpu_capacity(cpuid);
 }
 
 static void __init reset_cpu_topology(void)
-- 
1.9.1