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.c59
1 files changed, 49 insertions, 10 deletions
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 2872e86837b2..793f796c4da3 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -7,6 +7,7 @@
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/mm.h> 8#include <linux/mm.h>
9#include <linux/memory.h> 9#include <linux/memory.h>
10#include <linux/vmstat.h>
10#include <linux/node.h> 11#include <linux/node.h>
11#include <linux/hugetlb.h> 12#include <linux/hugetlb.h>
12#include <linux/compaction.h> 13#include <linux/compaction.h>
@@ -117,12 +118,21 @@ static ssize_t node_read_meminfo(struct sys_device * dev,
117 "Node %d WritebackTmp: %8lu kB\n" 118 "Node %d WritebackTmp: %8lu kB\n"
118 "Node %d Slab: %8lu kB\n" 119 "Node %d Slab: %8lu kB\n"
119 "Node %d SReclaimable: %8lu kB\n" 120 "Node %d SReclaimable: %8lu kB\n"
120 "Node %d SUnreclaim: %8lu kB\n", 121 "Node %d SUnreclaim: %8lu kB\n"
122#ifdef CONFIG_TRANSPARENT_HUGEPAGE
123 "Node %d AnonHugePages: %8lu kB\n"
124#endif
125 ,
121 nid, K(node_page_state(nid, NR_FILE_DIRTY)), 126 nid, K(node_page_state(nid, NR_FILE_DIRTY)),
122 nid, K(node_page_state(nid, NR_WRITEBACK)), 127 nid, K(node_page_state(nid, NR_WRITEBACK)),
123 nid, K(node_page_state(nid, NR_FILE_PAGES)), 128 nid, K(node_page_state(nid, NR_FILE_PAGES)),
124 nid, K(node_page_state(nid, NR_FILE_MAPPED)), 129 nid, K(node_page_state(nid, NR_FILE_MAPPED)),
125 nid, K(node_page_state(nid, NR_ANON_PAGES)), 130 nid, K(node_page_state(nid, NR_ANON_PAGES)
131#ifdef CONFIG_TRANSPARENT_HUGEPAGE
132 + node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) *
133 HPAGE_PMD_NR
134#endif
135 ),
126 nid, K(node_page_state(nid, NR_SHMEM)), 136 nid, K(node_page_state(nid, NR_SHMEM)),
127 nid, node_page_state(nid, NR_KERNEL_STACK) * 137 nid, node_page_state(nid, NR_KERNEL_STACK) *
128 THREAD_SIZE / 1024, 138 THREAD_SIZE / 1024,
@@ -133,7 +143,13 @@ static ssize_t node_read_meminfo(struct sys_device * dev,
133 nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) + 143 nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) +
134 node_page_state(nid, NR_SLAB_UNRECLAIMABLE)), 144 node_page_state(nid, NR_SLAB_UNRECLAIMABLE)),
135 nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)), 145 nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)),
136 nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))); 146 nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))
147#ifdef CONFIG_TRANSPARENT_HUGEPAGE
148 , nid,
149 K(node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) *
150 HPAGE_PMD_NR)
151#endif
152 );
137 n += hugetlb_report_node_meminfo(nid, buf + n); 153 n += hugetlb_report_node_meminfo(nid, buf + n);
138 return n; 154 return n;
139} 155}
@@ -160,6 +176,21 @@ static ssize_t node_read_numastat(struct sys_device * dev,
160} 176}
161static SYSDEV_ATTR(numastat, S_IRUGO, node_read_numastat, NULL); 177static SYSDEV_ATTR(numastat, S_IRUGO, node_read_numastat, NULL);
162 178
179static ssize_t node_read_vmstat(struct sys_device *dev,
180 struct sysdev_attribute *attr, char *buf)
181{
182 int nid = dev->id;
183 int i;
184 int n = 0;
185
186 for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
187 n += sprintf(buf+n, "%s %lu\n", vmstat_text[i],
188 node_page_state(nid, i));
189
190 return n;
191}
192static SYSDEV_ATTR(vmstat, S_IRUGO, node_read_vmstat, NULL);
193
163static ssize_t node_read_distance(struct sys_device * dev, 194static ssize_t node_read_distance(struct sys_device * dev,
164 struct sysdev_attribute *attr, char * buf) 195 struct sysdev_attribute *attr, char * buf)
165{ 196{
@@ -243,6 +274,7 @@ int register_node(struct node *node, int num, struct node *parent)
243 sysdev_create_file(&node->sysdev, &attr_meminfo); 274 sysdev_create_file(&node->sysdev, &attr_meminfo);
244 sysdev_create_file(&node->sysdev, &attr_numastat); 275 sysdev_create_file(&node->sysdev, &attr_numastat);
245 sysdev_create_file(&node->sysdev, &attr_distance); 276 sysdev_create_file(&node->sysdev, &attr_distance);
277 sysdev_create_file(&node->sysdev, &attr_vmstat);
246 278
247 scan_unevictable_register_node(node); 279 scan_unevictable_register_node(node);
248 280
@@ -267,6 +299,7 @@ void unregister_node(struct node *node)
267 sysdev_remove_file(&node->sysdev, &attr_meminfo); 299 sysdev_remove_file(&node->sysdev, &attr_meminfo);
268 sysdev_remove_file(&node->sysdev, &attr_numastat); 300 sysdev_remove_file(&node->sysdev, &attr_numastat);
269 sysdev_remove_file(&node->sysdev, &attr_distance); 301 sysdev_remove_file(&node->sysdev, &attr_distance);
302 sysdev_remove_file(&node->sysdev, &attr_vmstat);
270 303
271 scan_unevictable_unregister_node(node); 304 scan_unevictable_unregister_node(node);
272 hugetlb_unregister_node(node); /* no-op, if memoryless node */ 305 hugetlb_unregister_node(node); /* no-op, if memoryless node */
@@ -346,8 +379,10 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, int nid)
346 return -EFAULT; 379 return -EFAULT;
347 if (!node_online(nid)) 380 if (!node_online(nid))
348 return 0; 381 return 0;
349 sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); 382
350 sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; 383 sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
384 sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr);
385 sect_end_pfn += PAGES_PER_SECTION - 1;
351 for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { 386 for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {
352 int page_nid; 387 int page_nid;
353 388
@@ -371,7 +406,8 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, int nid)
371} 406}
372 407
373/* unregister memory section under all nodes that it spans */ 408/* unregister memory section under all nodes that it spans */
374int unregister_mem_sect_under_nodes(struct memory_block *mem_blk) 409int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
410 unsigned long phys_index)
375{ 411{
376 NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL); 412 NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL);
377 unsigned long pfn, sect_start_pfn, sect_end_pfn; 413 unsigned long pfn, sect_start_pfn, sect_end_pfn;
@@ -383,7 +419,8 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk)
383 if (!unlinked_nodes) 419 if (!unlinked_nodes)
384 return -ENOMEM; 420 return -ENOMEM;
385 nodes_clear(*unlinked_nodes); 421 nodes_clear(*unlinked_nodes);
386 sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); 422
423 sect_start_pfn = section_nr_to_pfn(phys_index);
387 sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; 424 sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1;
388 for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { 425 for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {
389 int nid; 426 int nid;
@@ -409,25 +446,27 @@ static int link_mem_sections(int nid)
409 unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn; 446 unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn;
410 unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages; 447 unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages;
411 unsigned long pfn; 448 unsigned long pfn;
449 struct memory_block *mem_blk = NULL;
412 int err = 0; 450 int err = 0;
413 451
414 for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { 452 for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
415 unsigned long section_nr = pfn_to_section_nr(pfn); 453 unsigned long section_nr = pfn_to_section_nr(pfn);
416 struct mem_section *mem_sect; 454 struct mem_section *mem_sect;
417 struct memory_block *mem_blk;
418 int ret; 455 int ret;
419 456
420 if (!present_section_nr(section_nr)) 457 if (!present_section_nr(section_nr))
421 continue; 458 continue;
422 mem_sect = __nr_to_section(section_nr); 459 mem_sect = __nr_to_section(section_nr);
423 mem_blk = find_memory_block(mem_sect); 460 mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
424 ret = register_mem_sect_under_node(mem_blk, nid); 461 ret = register_mem_sect_under_node(mem_blk, nid);
425 if (!err) 462 if (!err)
426 err = ret; 463 err = ret;
427 464
428 /* discard ref obtained in find_memory_block() */ 465 /* discard ref obtained in find_memory_block() */
429 kobject_put(&mem_blk->sysdev.kobj);
430 } 466 }
467
468 if (mem_blk)
469 kobject_put(&mem_blk->sysdev.kobj);
431 return err; 470 return err;
432} 471}
433 472