]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.111/powerpc-pseries-perform-full-re-add-of-cpu-for-topol.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.14.111 / powerpc-pseries-perform-full-re-add-of-cpu-for-topol.patch
1 From aaf7322e6c38527d098e566665c888b2d0c0774f Mon Sep 17 00:00:00 2001
2 From: Nathan Fontenot <nfont@linux.vnet.ibm.com>
3 Date: Mon, 29 Oct 2018 13:43:36 -0500
4 Subject: powerpc/pseries: Perform full re-add of CPU for topology update
5 post-migration
6
7 [ Upstream commit 81b61324922c67f73813d8a9c175f3c153f6a1c6 ]
8
9 On pseries systems, performing a partition migration can result in
10 altering the nodes a CPU is assigned to on the destination system. For
11 exampl, pre-migration on the source system CPUs are in node 1 and 3,
12 post-migration on the destination system CPUs are in nodes 2 and 3.
13
14 Handling the node change for a CPU can cause corruption in the slab
15 cache if we hit a timing where a CPUs node is changed while cache_reap()
16 is invoked. The corruption occurs because the slab cache code appears
17 to rely on the CPU and slab cache pages being on the same node.
18
19 The current dynamic updating of a CPUs node done in arch/powerpc/mm/numa.c
20 does not prevent us from hitting this scenario.
21
22 Changing the device tree property update notification handler that
23 recognizes an affinity change for a CPU to do a full DLPAR remove and
24 add of the CPU instead of dynamically changing its node resolves this
25 issue.
26
27 Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
28 Signed-off-by: Michael W. Bringmann <mwb@linux.vnet.ibm.com>
29 Tested-by: Michael W. Bringmann <mwb@linux.vnet.ibm.com>
30 Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
31 Signed-off-by: Sasha Levin <sashal@kernel.org>
32 ---
33 arch/powerpc/include/asm/topology.h | 2 ++
34 arch/powerpc/mm/numa.c | 9 +--------
35 arch/powerpc/platforms/pseries/hotplug-cpu.c | 19 +++++++++++++++++++
36 3 files changed, 22 insertions(+), 8 deletions(-)
37
38 diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
39 index 66c72b356ac0..e6b185b4b3b1 100644
40 --- a/arch/powerpc/include/asm/topology.h
41 +++ b/arch/powerpc/include/asm/topology.h
42 @@ -117,6 +117,8 @@ static inline int prrn_is_enabled(void)
43 #define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
44 #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
45 #define topology_core_id(cpu) (cpu_to_core_id(cpu))
46 +
47 +int dlpar_cpu_readd(int cpu);
48 #endif
49 #endif
50
51 diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
52 index 40fb9a8835fe..0a02c73a27b3 100644
53 --- a/arch/powerpc/mm/numa.c
54 +++ b/arch/powerpc/mm/numa.c
55 @@ -1527,13 +1527,6 @@ static void reset_topology_timer(void)
56
57 #ifdef CONFIG_SMP
58
59 -static void stage_topology_update(int core_id)
60 -{
61 - cpumask_or(&cpu_associativity_changes_mask,
62 - &cpu_associativity_changes_mask, cpu_sibling_mask(core_id));
63 - reset_topology_timer();
64 -}
65 -
66 static int dt_update_callback(struct notifier_block *nb,
67 unsigned long action, void *data)
68 {
69 @@ -1546,7 +1539,7 @@ static int dt_update_callback(struct notifier_block *nb,
70 !of_prop_cmp(update->prop->name, "ibm,associativity")) {
71 u32 core_id;
72 of_property_read_u32(update->dn, "reg", &core_id);
73 - stage_topology_update(core_id);
74 + rc = dlpar_cpu_readd(core_id);
75 rc = NOTIFY_OK;
76 }
77 break;
78 diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
79 index b1ac8ac38434..0baaaa6b0929 100644
80 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
81 +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
82 @@ -799,6 +799,25 @@ static int dlpar_cpu_add_by_count(u32 cpus_to_add)
83 return rc;
84 }
85
86 +int dlpar_cpu_readd(int cpu)
87 +{
88 + struct device_node *dn;
89 + struct device *dev;
90 + u32 drc_index;
91 + int rc;
92 +
93 + dev = get_cpu_device(cpu);
94 + dn = dev->of_node;
95 +
96 + rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index);
97 +
98 + rc = dlpar_cpu_remove_by_index(drc_index);
99 + if (!rc)
100 + rc = dlpar_cpu_add(drc_index);
101 +
102 + return rc;
103 +}
104 +
105 int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
106 {
107 u32 count, drc_index;
108 --
109 2.19.1
110