aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/node.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/node.c')
-rw-r--r--drivers/base/node.c86
1 files changed, 58 insertions, 28 deletions
diff --git a/drivers/base/node.c b/drivers/base/node.c
index af1a177216f1..fac124a7e1c5 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -227,7 +227,7 @@ static node_registration_func_t __hugetlb_unregister_node;
227static inline bool hugetlb_register_node(struct node *node) 227static inline bool hugetlb_register_node(struct node *node)
228{ 228{
229 if (__hugetlb_register_node && 229 if (__hugetlb_register_node &&
230 node_state(node->dev.id, N_HIGH_MEMORY)) { 230 node_state(node->dev.id, N_MEMORY)) {
231 __hugetlb_register_node(node); 231 __hugetlb_register_node(node);
232 return true; 232 return true;
233 } 233 }
@@ -252,6 +252,24 @@ static inline void hugetlb_register_node(struct node *node) {}
252static inline void hugetlb_unregister_node(struct node *node) {} 252static inline void hugetlb_unregister_node(struct node *node) {}
253#endif 253#endif
254 254
255static void node_device_release(struct device *dev)
256{
257 struct node *node = to_node(dev);
258
259#if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_HUGETLBFS)
260 /*
261 * We schedule the work only when a memory section is
262 * onlined/offlined on this node. When we come here,
263 * all the memory on this node has been offlined,
264 * so we won't enqueue new work to this work.
265 *
266 * The work is using node->node_work, so we should
267 * flush work before freeing the memory.
268 */
269 flush_work(&node->node_work);
270#endif
271 kfree(node);
272}
255 273
256/* 274/*
257 * register_node - Setup a sysfs device for a node. 275 * register_node - Setup a sysfs device for a node.
@@ -259,12 +277,13 @@ static inline void hugetlb_unregister_node(struct node *node) {}
259 * 277 *
260 * Initialize and register the node device. 278 * Initialize and register the node device.
261 */ 279 */
262int register_node(struct node *node, int num, struct node *parent) 280static int register_node(struct node *node, int num, struct node *parent)
263{ 281{
264 int error; 282 int error;
265 283
266 node->dev.id = num; 284 node->dev.id = num;
267 node->dev.bus = &node_subsys; 285 node->dev.bus = &node_subsys;
286 node->dev.release = node_device_release;
268 error = device_register(&node->dev); 287 error = device_register(&node->dev);
269 288
270 if (!error){ 289 if (!error){
@@ -306,7 +325,7 @@ void unregister_node(struct node *node)
306 device_unregister(&node->dev); 325 device_unregister(&node->dev);
307} 326}
308 327
309struct node node_devices[MAX_NUMNODES]; 328struct node *node_devices[MAX_NUMNODES];
310 329
311/* 330/*
312 * register cpu under node 331 * register cpu under node
@@ -323,15 +342,15 @@ int register_cpu_under_node(unsigned int cpu, unsigned int nid)
323 if (!obj) 342 if (!obj)
324 return 0; 343 return 0;
325 344
326 ret = sysfs_create_link(&node_devices[nid].dev.kobj, 345 ret = sysfs_create_link(&node_devices[nid]->dev.kobj,
327 &obj->kobj, 346 &obj->kobj,
328 kobject_name(&obj->kobj)); 347 kobject_name(&obj->kobj));
329 if (ret) 348 if (ret)
330 return ret; 349 return ret;
331 350
332 return sysfs_create_link(&obj->kobj, 351 return sysfs_create_link(&obj->kobj,
333 &node_devices[nid].dev.kobj, 352 &node_devices[nid]->dev.kobj,
334 kobject_name(&node_devices[nid].dev.kobj)); 353 kobject_name(&node_devices[nid]->dev.kobj));
335} 354}
336 355
337int unregister_cpu_under_node(unsigned int cpu, unsigned int nid) 356int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
@@ -345,10 +364,10 @@ int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
345 if (!obj) 364 if (!obj)
346 return 0; 365 return 0;
347 366
348 sysfs_remove_link(&node_devices[nid].dev.kobj, 367 sysfs_remove_link(&node_devices[nid]->dev.kobj,
349 kobject_name(&obj->kobj)); 368 kobject_name(&obj->kobj));
350 sysfs_remove_link(&obj->kobj, 369 sysfs_remove_link(&obj->kobj,
351 kobject_name(&node_devices[nid].dev.kobj)); 370 kobject_name(&node_devices[nid]->dev.kobj));
352 371
353 return 0; 372 return 0;
354} 373}
@@ -390,15 +409,15 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, int nid)
390 continue; 409 continue;
391 if (page_nid != nid) 410 if (page_nid != nid)
392 continue; 411 continue;
393 ret = sysfs_create_link_nowarn(&node_devices[nid].dev.kobj, 412 ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj,
394 &mem_blk->dev.kobj, 413 &mem_blk->dev.kobj,
395 kobject_name(&mem_blk->dev.kobj)); 414 kobject_name(&mem_blk->dev.kobj));
396 if (ret) 415 if (ret)
397 return ret; 416 return ret;
398 417
399 return sysfs_create_link_nowarn(&mem_blk->dev.kobj, 418 return sysfs_create_link_nowarn(&mem_blk->dev.kobj,
400 &node_devices[nid].dev.kobj, 419 &node_devices[nid]->dev.kobj,
401 kobject_name(&node_devices[nid].dev.kobj)); 420 kobject_name(&node_devices[nid]->dev.kobj));
402 } 421 }
403 /* mem section does not span the specified node */ 422 /* mem section does not span the specified node */
404 return 0; 423 return 0;
@@ -431,10 +450,10 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
431 continue; 450 continue;
432 if (node_test_and_set(nid, *unlinked_nodes)) 451 if (node_test_and_set(nid, *unlinked_nodes))
433 continue; 452 continue;
434 sysfs_remove_link(&node_devices[nid].dev.kobj, 453 sysfs_remove_link(&node_devices[nid]->dev.kobj,
435 kobject_name(&mem_blk->dev.kobj)); 454 kobject_name(&mem_blk->dev.kobj));
436 sysfs_remove_link(&mem_blk->dev.kobj, 455 sysfs_remove_link(&mem_blk->dev.kobj,
437 kobject_name(&node_devices[nid].dev.kobj)); 456 kobject_name(&node_devices[nid]->dev.kobj));
438 } 457 }
439 NODEMASK_FREE(unlinked_nodes); 458 NODEMASK_FREE(unlinked_nodes);
440 return 0; 459 return 0;
@@ -500,7 +519,7 @@ static void node_hugetlb_work(struct work_struct *work)
500 519
501static void init_node_hugetlb_work(int nid) 520static void init_node_hugetlb_work(int nid)
502{ 521{
503 INIT_WORK(&node_devices[nid].node_work, node_hugetlb_work); 522 INIT_WORK(&node_devices[nid]->node_work, node_hugetlb_work);
504} 523}
505 524
506static int node_memory_callback(struct notifier_block *self, 525static int node_memory_callback(struct notifier_block *self,
@@ -517,7 +536,7 @@ static int node_memory_callback(struct notifier_block *self,
517 * when transitioning to/from memoryless state. 536 * when transitioning to/from memoryless state.
518 */ 537 */
519 if (nid != NUMA_NO_NODE) 538 if (nid != NUMA_NO_NODE)
520 schedule_work(&node_devices[nid].node_work); 539 schedule_work(&node_devices[nid]->node_work);
521 break; 540 break;
522 541
523 case MEM_GOING_ONLINE: 542 case MEM_GOING_ONLINE:
@@ -558,9 +577,13 @@ int register_one_node(int nid)
558 struct node *parent = NULL; 577 struct node *parent = NULL;
559 578
560 if (p_node != nid) 579 if (p_node != nid)
561 parent = &node_devices[p_node]; 580 parent = node_devices[p_node];
581
582 node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL);
583 if (!node_devices[nid])
584 return -ENOMEM;
562 585
563 error = register_node(&node_devices[nid], nid, parent); 586 error = register_node(node_devices[nid], nid, parent);
564 587
565 /* link cpu under this node */ 588 /* link cpu under this node */
566 for_each_present_cpu(cpu) { 589 for_each_present_cpu(cpu) {
@@ -581,7 +604,8 @@ int register_one_node(int nid)
581 604
582void unregister_one_node(int nid) 605void unregister_one_node(int nid)
583{ 606{
584 unregister_node(&node_devices[nid]); 607 unregister_node(node_devices[nid]);
608 node_devices[nid] = NULL;
585} 609}
586 610
587/* 611/*
@@ -614,23 +638,29 @@ static ssize_t show_node_state(struct device *dev,
614 { __ATTR(name, 0444, show_node_state, NULL), state } 638 { __ATTR(name, 0444, show_node_state, NULL), state }
615 639
616static struct node_attr node_state_attr[] = { 640static struct node_attr node_state_attr[] = {
617 _NODE_ATTR(possible, N_POSSIBLE), 641 [N_POSSIBLE] = _NODE_ATTR(possible, N_POSSIBLE),
618 _NODE_ATTR(online, N_ONLINE), 642 [N_ONLINE] = _NODE_ATTR(online, N_ONLINE),
619 _NODE_ATTR(has_normal_memory, N_NORMAL_MEMORY), 643 [N_NORMAL_MEMORY] = _NODE_ATTR(has_normal_memory, N_NORMAL_MEMORY),
620 _NODE_ATTR(has_cpu, N_CPU),
621#ifdef CONFIG_HIGHMEM 644#ifdef CONFIG_HIGHMEM
622 _NODE_ATTR(has_high_memory, N_HIGH_MEMORY), 645 [N_HIGH_MEMORY] = _NODE_ATTR(has_high_memory, N_HIGH_MEMORY),
623#endif 646#endif
647#ifdef CONFIG_MOVABLE_NODE
648 [N_MEMORY] = _NODE_ATTR(has_memory, N_MEMORY),
649#endif
650 [N_CPU] = _NODE_ATTR(has_cpu, N_CPU),
624}; 651};
625 652
626static struct attribute *node_state_attrs[] = { 653static struct attribute *node_state_attrs[] = {
627 &node_state_attr[0].attr.attr, 654 &node_state_attr[N_POSSIBLE].attr.attr,
628 &node_state_attr[1].attr.attr, 655 &node_state_attr[N_ONLINE].attr.attr,
629 &node_state_attr[2].attr.attr, 656 &node_state_attr[N_NORMAL_MEMORY].attr.attr,
630 &node_state_attr[3].attr.attr,
631#ifdef CONFIG_HIGHMEM 657#ifdef CONFIG_HIGHMEM
632 &node_state_attr[4].attr.attr, 658 &node_state_attr[N_HIGH_MEMORY].attr.attr,
659#endif
660#ifdef CONFIG_MOVABLE_NODE
661 &node_state_attr[N_MEMORY].attr.attr,
633#endif 662#endif
663 &node_state_attr[N_CPU].attr.attr,
634 NULL 664 NULL
635}; 665};
636 666