diff options
author | Wen Congyang <wency@cn.fujitsu.com> | 2012-12-11 19:00:56 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-11 20:22:23 -0500 |
commit | 8732794b166196cc501c2ddd9e7c97cf45ab64c5 (patch) | |
tree | f9a3f04d08054de5d296e0104f61d4a1b13fbfb6 /drivers/base/node.c | |
parent | 97d0da2204ed9e34d9d42c2024c5bea5543f13c6 (diff) |
numa: convert static memory to dynamically allocated memory for per node device
We use a static array to store struct node. In many cases, we don't have
too many nodes, and some memory will be unused. Convert it to per-device
dynamically allocated memory.
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Jiang Liu <liuj97@gmail.com>
Cc: Minchan Kim <minchan.kim@gmail.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/base/node.c')
-rw-r--r-- | drivers/base/node.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/drivers/base/node.c b/drivers/base/node.c index af1a177216f1..28216ce74b3d 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -306,7 +306,7 @@ void unregister_node(struct node *node) | |||
306 | device_unregister(&node->dev); | 306 | device_unregister(&node->dev); |
307 | } | 307 | } |
308 | 308 | ||
309 | struct node node_devices[MAX_NUMNODES]; | 309 | struct node *node_devices[MAX_NUMNODES]; |
310 | 310 | ||
311 | /* | 311 | /* |
312 | * register cpu under node | 312 | * register cpu under node |
@@ -323,15 +323,15 @@ int register_cpu_under_node(unsigned int cpu, unsigned int nid) | |||
323 | if (!obj) | 323 | if (!obj) |
324 | return 0; | 324 | return 0; |
325 | 325 | ||
326 | ret = sysfs_create_link(&node_devices[nid].dev.kobj, | 326 | ret = sysfs_create_link(&node_devices[nid]->dev.kobj, |
327 | &obj->kobj, | 327 | &obj->kobj, |
328 | kobject_name(&obj->kobj)); | 328 | kobject_name(&obj->kobj)); |
329 | if (ret) | 329 | if (ret) |
330 | return ret; | 330 | return ret; |
331 | 331 | ||
332 | return sysfs_create_link(&obj->kobj, | 332 | return sysfs_create_link(&obj->kobj, |
333 | &node_devices[nid].dev.kobj, | 333 | &node_devices[nid]->dev.kobj, |
334 | kobject_name(&node_devices[nid].dev.kobj)); | 334 | kobject_name(&node_devices[nid]->dev.kobj)); |
335 | } | 335 | } |
336 | 336 | ||
337 | int unregister_cpu_under_node(unsigned int cpu, unsigned int nid) | 337 | int unregister_cpu_under_node(unsigned int cpu, unsigned int nid) |
@@ -345,10 +345,10 @@ int unregister_cpu_under_node(unsigned int cpu, unsigned int nid) | |||
345 | if (!obj) | 345 | if (!obj) |
346 | return 0; | 346 | return 0; |
347 | 347 | ||
348 | sysfs_remove_link(&node_devices[nid].dev.kobj, | 348 | sysfs_remove_link(&node_devices[nid]->dev.kobj, |
349 | kobject_name(&obj->kobj)); | 349 | kobject_name(&obj->kobj)); |
350 | sysfs_remove_link(&obj->kobj, | 350 | sysfs_remove_link(&obj->kobj, |
351 | kobject_name(&node_devices[nid].dev.kobj)); | 351 | kobject_name(&node_devices[nid]->dev.kobj)); |
352 | 352 | ||
353 | return 0; | 353 | return 0; |
354 | } | 354 | } |
@@ -390,15 +390,15 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, int nid) | |||
390 | continue; | 390 | continue; |
391 | if (page_nid != nid) | 391 | if (page_nid != nid) |
392 | continue; | 392 | continue; |
393 | ret = sysfs_create_link_nowarn(&node_devices[nid].dev.kobj, | 393 | ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj, |
394 | &mem_blk->dev.kobj, | 394 | &mem_blk->dev.kobj, |
395 | kobject_name(&mem_blk->dev.kobj)); | 395 | kobject_name(&mem_blk->dev.kobj)); |
396 | if (ret) | 396 | if (ret) |
397 | return ret; | 397 | return ret; |
398 | 398 | ||
399 | return sysfs_create_link_nowarn(&mem_blk->dev.kobj, | 399 | return sysfs_create_link_nowarn(&mem_blk->dev.kobj, |
400 | &node_devices[nid].dev.kobj, | 400 | &node_devices[nid]->dev.kobj, |
401 | kobject_name(&node_devices[nid].dev.kobj)); | 401 | kobject_name(&node_devices[nid]->dev.kobj)); |
402 | } | 402 | } |
403 | /* mem section does not span the specified node */ | 403 | /* mem section does not span the specified node */ |
404 | return 0; | 404 | return 0; |
@@ -431,10 +431,10 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, | |||
431 | continue; | 431 | continue; |
432 | if (node_test_and_set(nid, *unlinked_nodes)) | 432 | if (node_test_and_set(nid, *unlinked_nodes)) |
433 | continue; | 433 | continue; |
434 | sysfs_remove_link(&node_devices[nid].dev.kobj, | 434 | sysfs_remove_link(&node_devices[nid]->dev.kobj, |
435 | kobject_name(&mem_blk->dev.kobj)); | 435 | kobject_name(&mem_blk->dev.kobj)); |
436 | sysfs_remove_link(&mem_blk->dev.kobj, | 436 | sysfs_remove_link(&mem_blk->dev.kobj, |
437 | kobject_name(&node_devices[nid].dev.kobj)); | 437 | kobject_name(&node_devices[nid]->dev.kobj)); |
438 | } | 438 | } |
439 | NODEMASK_FREE(unlinked_nodes); | 439 | NODEMASK_FREE(unlinked_nodes); |
440 | return 0; | 440 | return 0; |
@@ -500,7 +500,7 @@ static void node_hugetlb_work(struct work_struct *work) | |||
500 | 500 | ||
501 | static void init_node_hugetlb_work(int nid) | 501 | static void init_node_hugetlb_work(int nid) |
502 | { | 502 | { |
503 | INIT_WORK(&node_devices[nid].node_work, node_hugetlb_work); | 503 | INIT_WORK(&node_devices[nid]->node_work, node_hugetlb_work); |
504 | } | 504 | } |
505 | 505 | ||
506 | static int node_memory_callback(struct notifier_block *self, | 506 | static int node_memory_callback(struct notifier_block *self, |
@@ -517,7 +517,7 @@ static int node_memory_callback(struct notifier_block *self, | |||
517 | * when transitioning to/from memoryless state. | 517 | * when transitioning to/from memoryless state. |
518 | */ | 518 | */ |
519 | if (nid != NUMA_NO_NODE) | 519 | if (nid != NUMA_NO_NODE) |
520 | schedule_work(&node_devices[nid].node_work); | 520 | schedule_work(&node_devices[nid]->node_work); |
521 | break; | 521 | break; |
522 | 522 | ||
523 | case MEM_GOING_ONLINE: | 523 | case MEM_GOING_ONLINE: |
@@ -558,9 +558,13 @@ int register_one_node(int nid) | |||
558 | struct node *parent = NULL; | 558 | struct node *parent = NULL; |
559 | 559 | ||
560 | if (p_node != nid) | 560 | if (p_node != nid) |
561 | parent = &node_devices[p_node]; | 561 | parent = node_devices[p_node]; |
562 | 562 | ||
563 | error = register_node(&node_devices[nid], nid, parent); | 563 | node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL); |
564 | if (!node_devices[nid]) | ||
565 | return -ENOMEM; | ||
566 | |||
567 | error = register_node(node_devices[nid], nid, parent); | ||
564 | 568 | ||
565 | /* link cpu under this node */ | 569 | /* link cpu under this node */ |
566 | for_each_present_cpu(cpu) { | 570 | for_each_present_cpu(cpu) { |
@@ -581,7 +585,9 @@ int register_one_node(int nid) | |||
581 | 585 | ||
582 | void unregister_one_node(int nid) | 586 | void unregister_one_node(int nid) |
583 | { | 587 | { |
584 | unregister_node(&node_devices[nid]); | 588 | unregister_node(node_devices[nid]); |
589 | kfree(node_devices[nid]); | ||
590 | node_devices[nid] = NULL; | ||
585 | } | 591 | } |
586 | 592 | ||
587 | /* | 593 | /* |