linux/drivers/base/node.c
<<
>>
Prefs
   1/*
   2 * Basic Node interface support
   3 */
   4
   5#include <linux/module.h>
   6#include <linux/init.h>
   7#include <linux/mm.h>
   8#include <linux/memory.h>
   9#include <linux/vmstat.h>
  10#include <linux/node.h>
  11#include <linux/hugetlb.h>
  12#include <linux/compaction.h>
  13#include <linux/cpumask.h>
  14#include <linux/topology.h>
  15#include <linux/nodemask.h>
  16#include <linux/cpu.h>
  17#include <linux/device.h>
  18#include <linux/swap.h>
  19#include <linux/slab.h>
  20
  21static struct bus_type node_subsys = {
  22        .name = "node",
  23        .dev_name = "node",
  24};
  25
  26
  27static ssize_t node_read_cpumap(struct device *dev, int type, char *buf)
  28{
  29        struct node *node_dev = to_node(dev);
  30        const struct cpumask *mask = cpumask_of_node(node_dev->dev.id);
  31        int len;
  32
  33        /* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */
  34        BUILD_BUG_ON((NR_CPUS/32 * 9) > (PAGE_SIZE-1));
  35
  36        len = type?
  37                cpulist_scnprintf(buf, PAGE_SIZE-2, mask) :
  38                cpumask_scnprintf(buf, PAGE_SIZE-2, mask);
  39        buf[len++] = '\n';
  40        buf[len] = '\0';
  41        return len;
  42}
  43
  44static inline ssize_t node_read_cpumask(struct device *dev,
  45                                struct device_attribute *attr, char *buf)
  46{
  47        return node_read_cpumap(dev, 0, buf);
  48}
  49static inline ssize_t node_read_cpulist(struct device *dev,
  50                                struct device_attribute *attr, char *buf)
  51{
  52        return node_read_cpumap(dev, 1, buf);
  53}
  54
  55static DEVICE_ATTR(cpumap,  S_IRUGO, node_read_cpumask, NULL);
  56static DEVICE_ATTR(cpulist, S_IRUGO, node_read_cpulist, NULL);
  57
  58#define K(x) ((x) << (PAGE_SHIFT - 10))
  59static ssize_t node_read_meminfo(struct device *dev,
  60                        struct device_attribute *attr, char *buf)
  61{
  62        int n;
  63        int nid = dev->id;
  64        struct sysinfo i;
  65
  66        si_meminfo_node(&i, nid);
  67        n = sprintf(buf,
  68                       "Node %d MemTotal:       %8lu kB\n"
  69                       "Node %d MemFree:        %8lu kB\n"
  70                       "Node %d MemUsed:        %8lu kB\n"
  71                       "Node %d Active:         %8lu kB\n"
  72                       "Node %d Inactive:       %8lu kB\n"
  73                       "Node %d Active(anon):   %8lu kB\n"
  74                       "Node %d Inactive(anon): %8lu kB\n"
  75                       "Node %d Active(file):   %8lu kB\n"
  76                       "Node %d Inactive(file): %8lu kB\n"
  77                       "Node %d Unevictable:    %8lu kB\n"
  78                       "Node %d Mlocked:        %8lu kB\n",
  79                       nid, K(i.totalram),
  80                       nid, K(i.freeram),
  81                       nid, K(i.totalram - i.freeram),
  82                       nid, K(node_page_state(nid, NR_ACTIVE_ANON) +
  83                                node_page_state(nid, NR_ACTIVE_FILE)),
  84                       nid, K(node_page_state(nid, NR_INACTIVE_ANON) +
  85                                node_page_state(nid, NR_INACTIVE_FILE)),
  86                       nid, K(node_page_state(nid, NR_ACTIVE_ANON)),
  87                       nid, K(node_page_state(nid, NR_INACTIVE_ANON)),
  88                       nid, K(node_page_state(nid, NR_ACTIVE_FILE)),
  89                       nid, K(node_page_state(nid, NR_INACTIVE_FILE)),
  90                       nid, K(node_page_state(nid, NR_UNEVICTABLE)),
  91                       nid, K(node_page_state(nid, NR_MLOCK)));
  92
  93#ifdef CONFIG_HIGHMEM
  94        n += sprintf(buf + n,
  95                       "Node %d HighTotal:      %8lu kB\n"
  96                       "Node %d HighFree:       %8lu kB\n"
  97                       "Node %d LowTotal:       %8lu kB\n"
  98                       "Node %d LowFree:        %8lu kB\n",
  99                       nid, K(i.totalhigh),
 100                       nid, K(i.freehigh),
 101                       nid, K(i.totalram - i.totalhigh),
 102                       nid, K(i.freeram - i.freehigh));
 103#endif
 104        n += sprintf(buf + n,
 105                       "Node %d Dirty:          %8lu kB\n"
 106                       "Node %d Writeback:      %8lu kB\n"
 107                       "Node %d FilePages:      %8lu kB\n"
 108                       "Node %d Mapped:         %8lu kB\n"
 109                       "Node %d AnonPages:      %8lu kB\n"
 110                       "Node %d Shmem:          %8lu kB\n"
 111                       "Node %d KernelStack:    %8lu kB\n"
 112                       "Node %d PageTables:     %8lu kB\n"
 113                       "Node %d NFS_Unstable:   %8lu kB\n"
 114                       "Node %d Bounce:         %8lu kB\n"
 115                       "Node %d WritebackTmp:   %8lu kB\n"
 116                       "Node %d Slab:           %8lu kB\n"
 117                       "Node %d SReclaimable:   %8lu kB\n"
 118                       "Node %d SUnreclaim:     %8lu kB\n"
 119#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 120                       "Node %d AnonHugePages:  %8lu kB\n"
 121#endif
 122                        ,
 123                       nid, K(node_page_state(nid, NR_FILE_DIRTY)),
 124                       nid, K(node_page_state(nid, NR_WRITEBACK)),
 125                       nid, K(node_page_state(nid, NR_FILE_PAGES)),
 126                       nid, K(node_page_state(nid, NR_FILE_MAPPED)),
 127#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 128                       nid, K(node_page_state(nid, NR_ANON_PAGES)
 129                        + node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) *
 130                        HPAGE_PMD_NR),
 131#else
 132                       nid, K(node_page_state(nid, NR_ANON_PAGES)),
 133#endif
 134                       nid, K(node_page_state(nid, NR_SHMEM)),
 135                       nid, node_page_state(nid, NR_KERNEL_STACK) *
 136                                THREAD_SIZE / 1024,
 137                       nid, K(node_page_state(nid, NR_PAGETABLE)),
 138                       nid, K(node_page_state(nid, NR_UNSTABLE_NFS)),
 139                       nid, K(node_page_state(nid, NR_BOUNCE)),
 140                       nid, K(node_page_state(nid, NR_WRITEBACK_TEMP)),
 141                       nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) +
 142                                node_page_state(nid, NR_SLAB_UNRECLAIMABLE)),
 143                       nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)),
 144#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 145                       nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))
 146                        , nid,
 147                        K(node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) *
 148                        HPAGE_PMD_NR));
 149#else
 150                       nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE)));
 151#endif
 152        n += hugetlb_report_node_meminfo(nid, buf + n);
 153        return n;
 154}
 155
 156#undef K
 157static DEVICE_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL);
 158
 159static ssize_t node_read_numastat(struct device *dev,
 160                                struct device_attribute *attr, char *buf)
 161{
 162        return sprintf(buf,
 163                       "numa_hit %lu\n"
 164                       "numa_miss %lu\n"
 165                       "numa_foreign %lu\n"
 166                       "interleave_hit %lu\n"
 167                       "local_node %lu\n"
 168                       "other_node %lu\n",
 169                       node_page_state(dev->id, NUMA_HIT),
 170                       node_page_state(dev->id, NUMA_MISS),
 171                       node_page_state(dev->id, NUMA_FOREIGN),
 172                       node_page_state(dev->id, NUMA_INTERLEAVE_HIT),
 173                       node_page_state(dev->id, NUMA_LOCAL),
 174                       node_page_state(dev->id, NUMA_OTHER));
 175}
 176static DEVICE_ATTR(numastat, S_IRUGO, node_read_numastat, NULL);
 177
 178static ssize_t node_read_vmstat(struct device *dev,
 179                                struct device_attribute *attr, char *buf)
 180{
 181        int nid = dev->id;
 182        int i;
 183        int n = 0;
 184
 185        for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
 186                n += sprintf(buf+n, "%s %lu\n", vmstat_text[i],
 187                             node_page_state(nid, i));
 188
 189        return n;
 190}
 191static DEVICE_ATTR(vmstat, S_IRUGO, node_read_vmstat, NULL);
 192
 193static ssize_t node_read_distance(struct device *dev,
 194                        struct device_attribute *attr, char * buf)
 195{
 196        int nid = dev->id;
 197        int len = 0;
 198        int i;
 199
 200        /*
 201         * buf is currently PAGE_SIZE in length and each node needs 4 chars
 202         * at the most (distance + space or newline).
 203         */
 204        BUILD_BUG_ON(MAX_NUMNODES * 4 > PAGE_SIZE);
 205
 206        for_each_online_node(i)
 207                len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i));
 208
 209        len += sprintf(buf + len, "\n");
 210        return len;
 211}
 212static DEVICE_ATTR(distance, S_IRUGO, node_read_distance, NULL);
 213
 214#ifdef CONFIG_HUGETLBFS
 215/*
 216 * hugetlbfs per node attributes registration interface:
 217 * When/if hugetlb[fs] subsystem initializes [sometime after this module],
 218 * it will register its per node attributes for all online nodes with
 219 * memory.  It will also call register_hugetlbfs_with_node(), below, to
 220 * register its attribute registration functions with this node driver.
 221 * Once these hooks have been initialized, the node driver will call into
 222 * the hugetlb module to [un]register attributes for hot-plugged nodes.
 223 */
 224static node_registration_func_t __hugetlb_register_node;
 225static node_registration_func_t __hugetlb_unregister_node;
 226
 227static inline bool hugetlb_register_node(struct node *node)
 228{
 229        if (__hugetlb_register_node &&
 230                        node_state(node->dev.id, N_HIGH_MEMORY)) {
 231                __hugetlb_register_node(node);
 232                return true;
 233        }
 234        return false;
 235}
 236
 237static inline void hugetlb_unregister_node(struct node *node)
 238{
 239        if (__hugetlb_unregister_node)
 240                __hugetlb_unregister_node(node);
 241}
 242
 243void register_hugetlbfs_with_node(node_registration_func_t doregister,
 244                                  node_registration_func_t unregister)
 245{
 246        __hugetlb_register_node   = doregister;
 247        __hugetlb_unregister_node = unregister;
 248}
 249#else
 250static inline void hugetlb_register_node(struct node *node) {}
 251
 252static inline void hugetlb_unregister_node(struct node *node) {}
 253#endif
 254
 255
 256/*
 257 * register_node - Setup a sysfs device for a node.
 258 * @num - Node number to use when creating the device.
 259 *
 260 * Initialize and register the node device.
 261 */
 262int register_node(struct node *node, int num, struct node *parent)
 263{
 264        int error;
 265
 266        node->dev.id = num;
 267        node->dev.bus = &node_subsys;
 268        error = device_register(&node->dev);
 269
 270        if (!error){
 271                device_create_file(&node->dev, &dev_attr_cpumap);
 272                device_create_file(&node->dev, &dev_attr_cpulist);
 273                device_create_file(&node->dev, &dev_attr_meminfo);
 274                device_create_file(&node->dev, &dev_attr_numastat);
 275                device_create_file(&node->dev, &dev_attr_distance);
 276                device_create_file(&node->dev, &dev_attr_vmstat);
 277
 278                scan_unevictable_register_node(node);
 279
 280                hugetlb_register_node(node);
 281
 282                compaction_register_node(node);
 283        }
 284        return error;
 285}
 286
 287/**
 288 * unregister_node - unregister a node device
 289 * @node: node going away
 290 *
 291 * Unregisters a node device @node.  All the devices on the node must be
 292 * unregistered before calling this function.
 293 */
 294void unregister_node(struct node *node)
 295{
 296        device_remove_file(&node->dev, &dev_attr_cpumap);
 297        device_remove_file(&node->dev, &dev_attr_cpulist);
 298        device_remove_file(&node->dev, &dev_attr_meminfo);
 299        device_remove_file(&node->dev, &dev_attr_numastat);
 300        device_remove_file(&node->dev, &dev_attr_distance);
 301        device_remove_file(&node->dev, &dev_attr_vmstat);
 302
 303        scan_unevictable_unregister_node(node);
 304        hugetlb_unregister_node(node);          /* no-op, if memoryless node */
 305
 306        device_unregister(&node->dev);
 307}
 308
 309struct node node_devices[MAX_NUMNODES];
 310
 311/*
 312 * register cpu under node
 313 */
 314int register_cpu_under_node(unsigned int cpu, unsigned int nid)
 315{
 316        int ret;
 317        struct device *obj;
 318
 319        if (!node_online(nid))
 320                return 0;
 321
 322        obj = get_cpu_device(cpu);
 323        if (!obj)
 324                return 0;
 325
 326        ret = sysfs_create_link(&node_devices[nid].dev.kobj,
 327                                &obj->kobj,
 328                                kobject_name(&obj->kobj));
 329        if (ret)
 330                return ret;
 331
 332        return sysfs_create_link(&obj->kobj,
 333                                 &node_devices[nid].dev.kobj,
 334                                 kobject_name(&node_devices[nid].dev.kobj));
 335}
 336
 337int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
 338{
 339        struct device *obj;
 340
 341        if (!node_online(nid))
 342                return 0;
 343
 344        obj = get_cpu_device(cpu);
 345        if (!obj)
 346                return 0;
 347
 348        sysfs_remove_link(&node_devices[nid].dev.kobj,
 349                          kobject_name(&obj->kobj));
 350        sysfs_remove_link(&obj->kobj,
 351                          kobject_name(&node_devices[nid].dev.kobj));
 352
 353        return 0;
 354}
 355
 356#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
 357#define page_initialized(page)  (page->lru.next)
 358
 359static int get_nid_for_pfn(unsigned long pfn)
 360{
 361        struct page *page;
 362
 363        if (!pfn_valid_within(pfn))
 364                return -1;
 365        page = pfn_to_page(pfn);
 366        if (!page_initialized(page))
 367                return -1;
 368        return pfn_to_nid(pfn);
 369}
 370
 371/* register memory section under specified node if it spans that node */
 372int register_mem_sect_under_node(struct memory_block *mem_blk, int nid)
 373{
 374        int ret;
 375        unsigned long pfn, sect_start_pfn, sect_end_pfn;
 376
 377        if (!mem_blk)
 378                return -EFAULT;
 379        if (!node_online(nid))
 380                return 0;
 381
 382        sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
 383        sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr);
 384        sect_end_pfn += PAGES_PER_SECTION - 1;
 385        for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {
 386                int page_nid;
 387
 388                page_nid = get_nid_for_pfn(pfn);
 389                if (page_nid < 0)
 390                        continue;
 391                if (page_nid != nid)
 392                        continue;
 393                ret = sysfs_create_link_nowarn(&node_devices[nid].dev.kobj,
 394                                        &mem_blk->dev.kobj,
 395                                        kobject_name(&mem_blk->dev.kobj));
 396                if (ret)
 397                        return ret;
 398
 399                return sysfs_create_link_nowarn(&mem_blk->dev.kobj,
 400                                &node_devices[nid].dev.kobj,
 401                                kobject_name(&node_devices[nid].dev.kobj));
 402        }
 403        /* mem section does not span the specified node */
 404        return 0;
 405}
 406
 407/* unregister memory section under all nodes that it spans */
 408int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
 409                                    unsigned long phys_index)
 410{
 411        NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL);
 412        unsigned long pfn, sect_start_pfn, sect_end_pfn;
 413
 414        if (!mem_blk) {
 415                NODEMASK_FREE(unlinked_nodes);
 416                return -EFAULT;
 417        }
 418        if (!unlinked_nodes)
 419                return -ENOMEM;
 420        nodes_clear(*unlinked_nodes);
 421
 422        sect_start_pfn = section_nr_to_pfn(phys_index);
 423        sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1;
 424        for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {
 425                int nid;
 426
 427                nid = get_nid_for_pfn(pfn);
 428                if (nid < 0)
 429                        continue;
 430                if (!node_online(nid))
 431                        continue;
 432                if (node_test_and_set(nid, *unlinked_nodes))
 433                        continue;
 434                sysfs_remove_link(&node_devices[nid].dev.kobj,
 435                         kobject_name(&mem_blk->dev.kobj));
 436                sysfs_remove_link(&mem_blk->dev.kobj,
 437                         kobject_name(&node_devices[nid].dev.kobj));
 438        }
 439        NODEMASK_FREE(unlinked_nodes);
 440        return 0;
 441}
 442
 443static int link_mem_sections(int nid)
 444{
 445        unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn;
 446        unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages;
 447        unsigned long pfn;
 448        struct memory_block *mem_blk = NULL;
 449        int err = 0;
 450
 451        for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
 452                unsigned long section_nr = pfn_to_section_nr(pfn);
 453                struct mem_section *mem_sect;
 454                int ret;
 455
 456                if (!present_section_nr(section_nr))
 457                        continue;
 458                mem_sect = __nr_to_section(section_nr);
 459
 460                /* same memblock ? */
 461                if (mem_blk)
 462                        if ((section_nr >= mem_blk->start_section_nr) &&
 463                            (section_nr <= mem_blk->end_section_nr))
 464                                continue;
 465
 466                mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
 467
 468                ret = register_mem_sect_under_node(mem_blk, nid);
 469                if (!err)
 470                        err = ret;
 471
 472                /* discard ref obtained in find_memory_block() */
 473        }
 474
 475        if (mem_blk)
 476                kobject_put(&mem_blk->dev.kobj);
 477        return err;
 478}
 479
 480#ifdef CONFIG_HUGETLBFS
 481/*
 482 * Handle per node hstate attribute [un]registration on transistions
 483 * to/from memoryless state.
 484 */
 485static void node_hugetlb_work(struct work_struct *work)
 486{
 487        struct node *node = container_of(work, struct node, node_work);
 488
 489        /*
 490         * We only get here when a node transitions to/from memoryless state.
 491         * We can detect which transition occurred by examining whether the
 492         * node has memory now.  hugetlb_register_node() already check this
 493         * so we try to register the attributes.  If that fails, then the
 494         * node has transitioned to memoryless, try to unregister the
 495         * attributes.
 496         */
 497        if (!hugetlb_register_node(node))
 498                hugetlb_unregister_node(node);
 499}
 500
 501static void init_node_hugetlb_work(int nid)
 502{
 503        INIT_WORK(&node_devices[nid].node_work, node_hugetlb_work);
 504}
 505
 506static int node_memory_callback(struct notifier_block *self,
 507                                unsigned long action, void *arg)
 508{
 509        struct memory_notify *mnb = arg;
 510        int nid = mnb->status_change_nid;
 511
 512        switch (action) {
 513        case MEM_ONLINE:
 514        case MEM_OFFLINE:
 515                /*
 516                 * offload per node hstate [un]registration to a work thread
 517                 * when transitioning to/from memoryless state.
 518                 */
 519                if (nid != NUMA_NO_NODE)
 520                        schedule_work(&node_devices[nid].node_work);
 521                break;
 522
 523        case MEM_GOING_ONLINE:
 524        case MEM_GOING_OFFLINE:
 525        case MEM_CANCEL_ONLINE:
 526        case MEM_CANCEL_OFFLINE:
 527        default:
 528                break;
 529        }
 530
 531        return NOTIFY_OK;
 532}
 533#endif  /* CONFIG_HUGETLBFS */
 534#else   /* !CONFIG_MEMORY_HOTPLUG_SPARSE */
 535
 536static int link_mem_sections(int nid) { return 0; }
 537#endif  /* CONFIG_MEMORY_HOTPLUG_SPARSE */
 538
 539#if !defined(CONFIG_MEMORY_HOTPLUG_SPARSE) || \
 540    !defined(CONFIG_HUGETLBFS)
 541static inline int node_memory_callback(struct notifier_block *self,
 542                                unsigned long action, void *arg)
 543{
 544        return NOTIFY_OK;
 545}
 546
 547static void init_node_hugetlb_work(int nid) { }
 548
 549#endif
 550
 551int register_one_node(int nid)
 552{
 553        int error = 0;
 554        int cpu;
 555
 556        if (node_online(nid)) {
 557                int p_node = parent_node(nid);
 558                struct node *parent = NULL;
 559
 560                if (p_node != nid)
 561                        parent = &node_devices[p_node];
 562
 563                error = register_node(&node_devices[nid], nid, parent);
 564
 565                /* link cpu under this node */
 566                for_each_present_cpu(cpu) {
 567                        if (cpu_to_node(cpu) == nid)
 568                                register_cpu_under_node(cpu, nid);
 569                }
 570
 571                /* link memory sections under this node */
 572                error = link_mem_sections(nid);
 573
 574                /* initialize work queue for memory hot plug */
 575                init_node_hugetlb_work(nid);
 576        }
 577
 578        return error;
 579
 580}
 581
 582void unregister_one_node(int nid)
 583{
 584        unregister_node(&node_devices[nid]);
 585}
 586
 587/*
 588 * node states attributes
 589 */
 590
 591static ssize_t print_nodes_state(enum node_states state, char *buf)
 592{
 593        int n;
 594
 595        n = nodelist_scnprintf(buf, PAGE_SIZE-2, node_states[state]);
 596        buf[n++] = '\n';
 597        buf[n] = '\0';
 598        return n;
 599}
 600
 601struct node_attr {
 602        struct device_attribute attr;
 603        enum node_states state;
 604};
 605
 606static ssize_t show_node_state(struct device *dev,
 607                               struct device_attribute *attr, char *buf)
 608{
 609        struct node_attr *na = container_of(attr, struct node_attr, attr);
 610        return print_nodes_state(na->state, buf);
 611}
 612
 613#define _NODE_ATTR(name, state) \
 614        { __ATTR(name, 0444, show_node_state, NULL), state }
 615
 616static struct node_attr node_state_attr[] = {
 617        _NODE_ATTR(possible, N_POSSIBLE),
 618        _NODE_ATTR(online, N_ONLINE),
 619        _NODE_ATTR(has_normal_memory, N_NORMAL_MEMORY),
 620        _NODE_ATTR(has_cpu, N_CPU),
 621#ifdef CONFIG_HIGHMEM
 622        _NODE_ATTR(has_high_memory, N_HIGH_MEMORY),
 623#endif
 624};
 625
 626static struct attribute *node_state_attrs[] = {
 627        &node_state_attr[0].attr.attr,
 628        &node_state_attr[1].attr.attr,
 629        &node_state_attr[2].attr.attr,
 630        &node_state_attr[3].attr.attr,
 631#ifdef CONFIG_HIGHMEM
 632        &node_state_attr[4].attr.attr,
 633#endif
 634        NULL
 635};
 636
 637static struct attribute_group memory_root_attr_group = {
 638        .attrs = node_state_attrs,
 639};
 640
 641static const struct attribute_group *cpu_root_attr_groups[] = {
 642        &memory_root_attr_group,
 643        NULL,
 644};
 645
 646#define NODE_CALLBACK_PRI       2       /* lower than SLAB */
 647static int __init register_node_type(void)
 648{
 649        int ret;
 650
 651        BUILD_BUG_ON(ARRAY_SIZE(node_state_attr) != NR_NODE_STATES);
 652        BUILD_BUG_ON(ARRAY_SIZE(node_state_attrs)-1 != NR_NODE_STATES);
 653
 654        ret = subsys_system_register(&node_subsys, cpu_root_attr_groups);
 655        if (!ret) {
 656                hotplug_memory_notifier(node_memory_callback,
 657                                        NODE_CALLBACK_PRI);
 658        }
 659
 660        /*
 661         * Note:  we're not going to unregister the node class if we fail
 662         * to register the node state class attribute files.
 663         */
 664        return ret;
 665}
 666postcore_initcall(register_node_type);
 667
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.