spi: fsl-espi: improve return value handling in fsl_espi_probe
[cascardo/linux.git] / arch / arm64 / mm / numa.c
1 /*
2  * NUMA support, based on the x86 implementation.
3  *
4  * Copyright (C) 2015 Cavium Inc.
5  * Author: Ganapatrao Kulkarni <gkulkarni@cavium.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <linux/acpi.h>
21 #include <linux/bootmem.h>
22 #include <linux/memblock.h>
23 #include <linux/module.h>
24 #include <linux/of.h>
25
26 struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
27 EXPORT_SYMBOL(node_data);
28 nodemask_t numa_nodes_parsed __initdata;
29 static int cpu_to_node_map[NR_CPUS] = { [0 ... NR_CPUS-1] = NUMA_NO_NODE };
30
31 static int numa_distance_cnt;
32 static u8 *numa_distance;
33 static bool numa_off;
34
35 static __init int numa_parse_early_param(char *opt)
36 {
37         if (!opt)
38                 return -EINVAL;
39         if (!strncmp(opt, "off", 3)) {
40                 pr_info("%s\n", "NUMA turned off");
41                 numa_off = true;
42         }
43         return 0;
44 }
45 early_param("numa", numa_parse_early_param);
46
47 cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
48 EXPORT_SYMBOL(node_to_cpumask_map);
49
50 #ifdef CONFIG_DEBUG_PER_CPU_MAPS
51
52 /*
53  * Returns a pointer to the bitmask of CPUs on Node 'node'.
54  */
55 const struct cpumask *cpumask_of_node(int node)
56 {
57         if (WARN_ON(node >= nr_node_ids))
58                 return cpu_none_mask;
59
60         if (WARN_ON(node_to_cpumask_map[node] == NULL))
61                 return cpu_online_mask;
62
63         return node_to_cpumask_map[node];
64 }
65 EXPORT_SYMBOL(cpumask_of_node);
66
67 #endif
68
69 static void map_cpu_to_node(unsigned int cpu, int nid)
70 {
71         set_cpu_numa_node(cpu, nid);
72         if (nid >= 0)
73                 cpumask_set_cpu(cpu, node_to_cpumask_map[nid]);
74 }
75
76 void numa_clear_node(unsigned int cpu)
77 {
78         int nid = cpu_to_node(cpu);
79
80         if (nid >= 0)
81                 cpumask_clear_cpu(cpu, node_to_cpumask_map[nid]);
82         set_cpu_numa_node(cpu, NUMA_NO_NODE);
83 }
84
85 /*
86  * Allocate node_to_cpumask_map based on number of available nodes
87  * Requires node_possible_map to be valid.
88  *
89  * Note: cpumask_of_node() is not valid until after this is done.
90  * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
91  */
92 static void __init setup_node_to_cpumask_map(void)
93 {
94         unsigned int cpu;
95         int node;
96
97         /* setup nr_node_ids if not done yet */
98         if (nr_node_ids == MAX_NUMNODES)
99                 setup_nr_node_ids();
100
101         /* allocate and clear the mapping */
102         for (node = 0; node < nr_node_ids; node++) {
103                 alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
104                 cpumask_clear(node_to_cpumask_map[node]);
105         }
106
107         for_each_possible_cpu(cpu)
108                 set_cpu_numa_node(cpu, NUMA_NO_NODE);
109
110         /* cpumask_of_node() will now work */
111         pr_debug("NUMA: Node to cpumask map for %d nodes\n", nr_node_ids);
112 }
113
114 /*
115  *  Set the cpu to node and mem mapping
116  */
117 void numa_store_cpu_info(unsigned int cpu)
118 {
119         map_cpu_to_node(cpu, numa_off ? 0 : cpu_to_node_map[cpu]);
120 }
121
122 void __init early_map_cpu_to_node(unsigned int cpu, int nid)
123 {
124         /* fallback to node 0 */
125         if (nid < 0 || nid >= MAX_NUMNODES)
126                 nid = 0;
127
128         cpu_to_node_map[cpu] = nid;
129 }
130
131 /**
132  * numa_add_memblk - Set node id to memblk
133  * @nid: NUMA node ID of the new memblk
134  * @start: Start address of the new memblk
135  * @end:  End address of the new memblk
136  *
137  * RETURNS:
138  * 0 on success, -errno on failure.
139  */
140 int __init numa_add_memblk(int nid, u64 start, u64 end)
141 {
142         int ret;
143
144         ret = memblock_set_node(start, (end - start), &memblock.memory, nid);
145         if (ret < 0) {
146                 pr_err("NUMA: memblock [0x%llx - 0x%llx] failed to add on node %d\n",
147                         start, (end - 1), nid);
148                 return ret;
149         }
150
151         node_set(nid, numa_nodes_parsed);
152         pr_info("NUMA: Adding memblock [0x%llx - 0x%llx] on node %d\n",
153                         start, (end - 1), nid);
154         return ret;
155 }
156
157 /**
158  * Initialize NODE_DATA for a node on the local memory
159  */
160 static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
161 {
162         const size_t nd_size = roundup(sizeof(pg_data_t), SMP_CACHE_BYTES);
163         u64 nd_pa;
164         void *nd;
165         int tnid;
166
167         pr_info("NUMA: Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
168                         nid, start_pfn << PAGE_SHIFT,
169                         (end_pfn << PAGE_SHIFT) - 1);
170
171         nd_pa = memblock_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid);
172         nd = __va(nd_pa);
173
174         /* report and initialize */
175         pr_info("NUMA: NODE_DATA [mem %#010Lx-%#010Lx]\n",
176                 nd_pa, nd_pa + nd_size - 1);
177         tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
178         if (tnid != nid)
179                 pr_info("NUMA: NODE_DATA(%d) on node %d\n", nid, tnid);
180
181         node_data[nid] = nd;
182         memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
183         NODE_DATA(nid)->node_id = nid;
184         NODE_DATA(nid)->node_start_pfn = start_pfn;
185         NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
186 }
187
188 /**
189  * numa_free_distance
190  *
191  * The current table is freed.
192  */
193 void __init numa_free_distance(void)
194 {
195         size_t size;
196
197         if (!numa_distance)
198                 return;
199
200         size = numa_distance_cnt * numa_distance_cnt *
201                 sizeof(numa_distance[0]);
202
203         memblock_free(__pa(numa_distance), size);
204         numa_distance_cnt = 0;
205         numa_distance = NULL;
206 }
207
208 /**
209  *
210  * Create a new NUMA distance table.
211  *
212  */
213 static int __init numa_alloc_distance(void)
214 {
215         size_t size;
216         u64 phys;
217         int i, j;
218
219         size = nr_node_ids * nr_node_ids * sizeof(numa_distance[0]);
220         phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
221                                       size, PAGE_SIZE);
222         if (WARN_ON(!phys))
223                 return -ENOMEM;
224
225         memblock_reserve(phys, size);
226
227         numa_distance = __va(phys);
228         numa_distance_cnt = nr_node_ids;
229
230         /* fill with the default distances */
231         for (i = 0; i < numa_distance_cnt; i++)
232                 for (j = 0; j < numa_distance_cnt; j++)
233                         numa_distance[i * numa_distance_cnt + j] = i == j ?
234                                 LOCAL_DISTANCE : REMOTE_DISTANCE;
235
236         pr_debug("NUMA: Initialized distance table, cnt=%d\n",
237                         numa_distance_cnt);
238
239         return 0;
240 }
241
242 /**
243  * numa_set_distance - Set inter node NUMA distance from node to node.
244  * @from: the 'from' node to set distance
245  * @to: the 'to'  node to set distance
246  * @distance: NUMA distance
247  *
248  * Set the distance from node @from to @to to @distance.
249  * If distance table doesn't exist, a warning is printed.
250  *
251  * If @from or @to is higher than the highest known node or lower than zero
252  * or @distance doesn't make sense, the call is ignored.
253  *
254  */
255 void __init numa_set_distance(int from, int to, int distance)
256 {
257         if (!numa_distance) {
258                 pr_warn_once("NUMA: Warning: distance table not allocated yet\n");
259                 return;
260         }
261
262         if (from >= numa_distance_cnt || to >= numa_distance_cnt ||
263                         from < 0 || to < 0) {
264                 pr_warn_once("NUMA: Warning: node ids are out of bound, from=%d to=%d distance=%d\n",
265                             from, to, distance);
266                 return;
267         }
268
269         if ((u8)distance != distance ||
270             (from == to && distance != LOCAL_DISTANCE)) {
271                 pr_warn_once("NUMA: Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
272                              from, to, distance);
273                 return;
274         }
275
276         numa_distance[from * numa_distance_cnt + to] = distance;
277 }
278
279 /**
280  * Return NUMA distance @from to @to
281  */
282 int __node_distance(int from, int to)
283 {
284         if (from >= numa_distance_cnt || to >= numa_distance_cnt)
285                 return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
286         return numa_distance[from * numa_distance_cnt + to];
287 }
288 EXPORT_SYMBOL(__node_distance);
289
290 static int __init numa_register_nodes(void)
291 {
292         int nid;
293         struct memblock_region *mblk;
294
295         /* Check that valid nid is set to memblks */
296         for_each_memblock(memory, mblk)
297                 if (mblk->nid == NUMA_NO_NODE || mblk->nid >= MAX_NUMNODES) {
298                         pr_warn("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
299                                 mblk->nid, mblk->base,
300                                 mblk->base + mblk->size - 1);
301                         return -EINVAL;
302                 }
303
304         /* Finally register nodes. */
305         for_each_node_mask(nid, numa_nodes_parsed) {
306                 unsigned long start_pfn, end_pfn;
307
308                 get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
309                 setup_node_data(nid, start_pfn, end_pfn);
310                 node_set_online(nid);
311         }
312
313         /* Setup online nodes to actual nodes*/
314         node_possible_map = numa_nodes_parsed;
315
316         return 0;
317 }
318
319 static int __init numa_init(int (*init_func)(void))
320 {
321         int ret;
322
323         nodes_clear(numa_nodes_parsed);
324         nodes_clear(node_possible_map);
325         nodes_clear(node_online_map);
326         numa_free_distance();
327
328         ret = numa_alloc_distance();
329         if (ret < 0)
330                 return ret;
331
332         ret = init_func();
333         if (ret < 0)
334                 return ret;
335
336         if (nodes_empty(numa_nodes_parsed))
337                 return -EINVAL;
338
339         ret = numa_register_nodes();
340         if (ret < 0)
341                 return ret;
342
343         setup_node_to_cpumask_map();
344
345         /* init boot processor */
346         cpu_to_node_map[0] = 0;
347         map_cpu_to_node(0, 0);
348
349         return 0;
350 }
351
352 /**
353  * dummy_numa_init - Fallback dummy NUMA init
354  *
355  * Used if there's no underlying NUMA architecture, NUMA initialization
356  * fails, or NUMA is disabled on the command line.
357  *
358  * Must online at least one node (node 0) and add memory blocks that cover all
359  * allowed memory. It is unlikely that this function fails.
360  */
361 static int __init dummy_numa_init(void)
362 {
363         int ret;
364         struct memblock_region *mblk;
365
366         if (numa_off)
367                 pr_info("NUMA disabled\n"); /* Forced off on command line. */
368         else
369                 pr_info("No NUMA configuration found\n");
370         pr_info("NUMA: Faking a node at [mem %#018Lx-%#018Lx]\n",
371                0LLU, PFN_PHYS(max_pfn) - 1);
372
373         for_each_memblock(memory, mblk) {
374                 ret = numa_add_memblk(0, mblk->base, mblk->base + mblk->size);
375                 if (!ret)
376                         continue;
377
378                 pr_err("NUMA init failed\n");
379                 return ret;
380         }
381
382         numa_off = true;
383         return 0;
384 }
385
386 /**
387  * arm64_numa_init - Initialize NUMA
388  *
389  * Try each configured NUMA initialization method until one succeeds.  The
390  * last fallback is dummy single node config encomapssing whole memory.
391  */
392 void __init arm64_numa_init(void)
393 {
394         if (!numa_off) {
395                 if (!acpi_disabled && !numa_init(arm64_acpi_numa_init))
396                         return;
397                 if (acpi_disabled && !numa_init(of_numa_init))
398                         return;
399         }
400
401         numa_init(dummy_numa_init);
402 }