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
|