12
12
#include <linux/memblock.h>
13
13
#include <linux/module.h>
14
14
#include <linux/of.h>
15
+ #include <linux/numa_memblks.h>
15
16
16
17
#include <asm/sections.h>
17
18
18
- nodemask_t numa_nodes_parsed __initdata ;
19
19
static int cpu_to_node_map [NR_CPUS ] = { [0 ... NR_CPUS - 1 ] = NUMA_NO_NODE };
20
20
21
- static int numa_distance_cnt ;
22
- static u8 * numa_distance ;
23
21
bool numa_off ;
24
22
25
23
static __init int numa_parse_early_param (char * opt )
@@ -28,6 +26,8 @@ static __init int numa_parse_early_param(char *opt)
28
26
return - EINVAL ;
29
27
if (str_has_prefix (opt , "off" ))
30
28
numa_off = true;
29
+ if (!strncmp (opt , "fake=" , 5 ))
30
+ return numa_emu_cmdline (opt + 5 );
31
31
32
32
return 0 ;
33
33
}
@@ -59,6 +59,7 @@ EXPORT_SYMBOL(cpumask_of_node);
59
59
60
60
#endif
61
61
62
+ #ifndef CONFIG_NUMA_EMU
62
63
static void numa_update_cpu (unsigned int cpu , bool remove )
63
64
{
64
65
int nid = cpu_to_node (cpu );
@@ -81,6 +82,7 @@ void numa_remove_cpu(unsigned int cpu)
81
82
{
82
83
numa_update_cpu (cpu , true);
83
84
}
85
+ #endif
84
86
85
87
void numa_clear_node (unsigned int cpu )
86
88
{
@@ -142,7 +144,7 @@ void __init early_map_cpu_to_node(unsigned int cpu, int nid)
142
144
unsigned long __per_cpu_offset [NR_CPUS ] __read_mostly ;
143
145
EXPORT_SYMBOL (__per_cpu_offset );
144
146
145
- int __init early_cpu_to_node (int cpu )
147
+ int early_cpu_to_node (int cpu )
146
148
{
147
149
return cpu_to_node_map [cpu ];
148
150
}
@@ -187,30 +189,6 @@ void __init setup_per_cpu_areas(void)
187
189
}
188
190
#endif
189
191
190
- /**
191
- * numa_add_memblk() - Set node id to memblk
192
- * @nid: NUMA node ID of the new memblk
193
- * @start: Start address of the new memblk
194
- * @end: End address of the new memblk
195
- *
196
- * RETURNS:
197
- * 0 on success, -errno on failure.
198
- */
199
- int __init numa_add_memblk (int nid , u64 start , u64 end )
200
- {
201
- int ret ;
202
-
203
- ret = memblock_set_node (start , (end - start ), & memblock .memory , nid );
204
- if (ret < 0 ) {
205
- pr_err ("memblock [0x%llx - 0x%llx] failed to add on node %d\n" ,
206
- start , (end - 1 ), nid );
207
- return ret ;
208
- }
209
-
210
- node_set (nid , numa_nodes_parsed );
211
- return ret ;
212
- }
213
-
214
192
/*
215
193
* Initialize NODE_DATA for a node on the local memory
216
194
*/
@@ -226,116 +204,9 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
226
204
NODE_DATA (nid )-> node_spanned_pages = end_pfn - start_pfn ;
227
205
}
228
206
229
- /*
230
- * numa_free_distance
231
- *
232
- * The current table is freed.
233
- */
234
- void __init numa_free_distance (void )
235
- {
236
- size_t size ;
237
-
238
- if (!numa_distance )
239
- return ;
240
-
241
- size = numa_distance_cnt * numa_distance_cnt *
242
- sizeof (numa_distance [0 ]);
243
-
244
- memblock_free (numa_distance , size );
245
- numa_distance_cnt = 0 ;
246
- numa_distance = NULL ;
247
- }
248
-
249
- /*
250
- * Create a new NUMA distance table.
251
- */
252
- static int __init numa_alloc_distance (void )
253
- {
254
- size_t size ;
255
- int i , j ;
256
-
257
- size = nr_node_ids * nr_node_ids * sizeof (numa_distance [0 ]);
258
- numa_distance = memblock_alloc (size , PAGE_SIZE );
259
- if (WARN_ON (!numa_distance ))
260
- return - ENOMEM ;
261
-
262
- numa_distance_cnt = nr_node_ids ;
263
-
264
- /* fill with the default distances */
265
- for (i = 0 ; i < numa_distance_cnt ; i ++ )
266
- for (j = 0 ; j < numa_distance_cnt ; j ++ )
267
- numa_distance [i * numa_distance_cnt + j ] = i == j ?
268
- LOCAL_DISTANCE : REMOTE_DISTANCE ;
269
-
270
- pr_debug ("Initialized distance table, cnt=%d\n" , numa_distance_cnt );
271
-
272
- return 0 ;
273
- }
274
-
275
- /**
276
- * numa_set_distance() - Set inter node NUMA distance from node to node.
277
- * @from: the 'from' node to set distance
278
- * @to: the 'to' node to set distance
279
- * @distance: NUMA distance
280
- *
281
- * Set the distance from node @from to @to to @distance.
282
- * If distance table doesn't exist, a warning is printed.
283
- *
284
- * If @from or @to is higher than the highest known node or lower than zero
285
- * or @distance doesn't make sense, the call is ignored.
286
- */
287
- void __init numa_set_distance (int from , int to , int distance )
288
- {
289
- if (!numa_distance ) {
290
- pr_warn_once ("Warning: distance table not allocated yet\n" );
291
- return ;
292
- }
293
-
294
- if (from >= numa_distance_cnt || to >= numa_distance_cnt ||
295
- from < 0 || to < 0 ) {
296
- pr_warn_once ("Warning: node ids are out of bound, from=%d to=%d distance=%d\n" ,
297
- from , to , distance );
298
- return ;
299
- }
300
-
301
- if ((u8 )distance != distance ||
302
- (from == to && distance != LOCAL_DISTANCE )) {
303
- pr_warn_once ("Warning: invalid distance parameter, from=%d to=%d distance=%d\n" ,
304
- from , to , distance );
305
- return ;
306
- }
307
-
308
- numa_distance [from * numa_distance_cnt + to ] = distance ;
309
- }
310
-
311
- /*
312
- * Return NUMA distance @from to @to
313
- */
314
- int __node_distance (int from , int to )
315
- {
316
- if (from >= numa_distance_cnt || to >= numa_distance_cnt )
317
- return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE ;
318
- return numa_distance [from * numa_distance_cnt + to ];
319
- }
320
- EXPORT_SYMBOL (__node_distance );
321
-
322
207
static int __init numa_register_nodes (void )
323
208
{
324
209
int nid ;
325
- struct memblock_region * mblk ;
326
-
327
- /* Check that valid nid is set to memblks */
328
- for_each_mem_region (mblk ) {
329
- int mblk_nid = memblock_get_region_node (mblk );
330
- phys_addr_t start = mblk -> base ;
331
- phys_addr_t end = mblk -> base + mblk -> size - 1 ;
332
-
333
- if (mblk_nid == NUMA_NO_NODE || mblk_nid >= MAX_NUMNODES ) {
334
- pr_warn ("Warning: invalid memblk node %d [mem %pap-%pap]\n" ,
335
- mblk_nid , & start , & end );
336
- return - EINVAL ;
337
- }
338
- }
339
210
340
211
/* Finally register nodes. */
341
212
for_each_node_mask (nid , numa_nodes_parsed ) {
@@ -360,11 +231,7 @@ static int __init numa_init(int (*init_func)(void))
360
231
nodes_clear (node_possible_map );
361
232
nodes_clear (node_online_map );
362
233
363
- ret = numa_alloc_distance ();
364
- if (ret < 0 )
365
- return ret ;
366
-
367
- ret = init_func ();
234
+ ret = numa_memblks_init (init_func , /* memblock_force_top_down */ false);
368
235
if (ret < 0 )
369
236
goto out_free_distance ;
370
237
@@ -382,7 +249,7 @@ static int __init numa_init(int (*init_func)(void))
382
249
383
250
return 0 ;
384
251
out_free_distance :
385
- numa_free_distance ();
252
+ numa_reset_distance ();
386
253
return ret ;
387
254
}
388
255
@@ -412,6 +279,7 @@ static int __init dummy_numa_init(void)
412
279
pr_err ("NUMA init failed\n" );
413
280
return ret ;
414
281
}
282
+ node_set (0 , numa_nodes_parsed );
415
283
416
284
numa_off = true;
417
285
return 0 ;
@@ -454,3 +322,54 @@ void __init arch_numa_init(void)
454
322
455
323
numa_init (dummy_numa_init );
456
324
}
325
+
326
+ #ifdef CONFIG_NUMA_EMU
327
+ void __init numa_emu_update_cpu_to_node (int * emu_nid_to_phys ,
328
+ unsigned int nr_emu_nids )
329
+ {
330
+ int i , j ;
331
+
332
+ /*
333
+ * Transform cpu_to_node_map table to use emulated nids by
334
+ * reverse-mapping phys_nid. The maps should always exist but fall
335
+ * back to zero just in case.
336
+ */
337
+ for (i = 0 ; i < ARRAY_SIZE (cpu_to_node_map ); i ++ ) {
338
+ if (cpu_to_node_map [i ] == NUMA_NO_NODE )
339
+ continue ;
340
+ for (j = 0 ; j < nr_emu_nids ; j ++ )
341
+ if (cpu_to_node_map [i ] == emu_nid_to_phys [j ])
342
+ break ;
343
+ cpu_to_node_map [i ] = j < nr_emu_nids ? j : 0 ;
344
+ }
345
+ }
346
+
347
+ u64 __init numa_emu_dma_end (void )
348
+ {
349
+ return memblock_start_of_DRAM () + SZ_4G ;
350
+ }
351
+
352
+ void debug_cpumask_set_cpu (unsigned int cpu , int node , bool enable )
353
+ {
354
+ struct cpumask * mask ;
355
+
356
+ if (node == NUMA_NO_NODE )
357
+ return ;
358
+
359
+ mask = node_to_cpumask_map [node ];
360
+ if (!cpumask_available (mask )) {
361
+ pr_err ("node_to_cpumask_map[%i] NULL\n" , node );
362
+ dump_stack ();
363
+ return ;
364
+ }
365
+
366
+ if (enable )
367
+ cpumask_set_cpu (cpu , mask );
368
+ else
369
+ cpumask_clear_cpu (cpu , mask );
370
+
371
+ pr_debug ("%s cpu %d node %d: mask now %*pbl\n" ,
372
+ enable ? "numa_add_cpu" : "numa_remove_cpu" ,
373
+ cpu , node , cpumask_pr_args (mask ));
374
+ }
375
+ #endif /* CONFIG_NUMA_EMU */
0 commit comments