]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - mm/mm_init.c
vmallocinfo: add NUMA information
[thirdparty/kernel/stable.git] / mm / mm_init.c
CommitLineData
6b74ab97
MG
1/*
2 * mm_init.c - Memory initialisation verification and debugging
3 *
4 * Copyright 2008 IBM Corporation, 2008
5 * Author Mel Gorman <mel@csn.ul.ie>
6 *
7 */
8#include <linux/kernel.h>
9#include <linux/init.h>
708614e6 10#include "internal.h"
6b74ab97
MG
11
12int __meminitdata mminit_loglevel;
13
68ad8df4
MG
14/* The zonelists are simply reported, validation is manual. */
15void mminit_verify_zonelist(void)
16{
17 int nid;
18
19 if (mminit_loglevel < MMINIT_VERIFY)
20 return;
21
22 for_each_online_node(nid) {
23 pg_data_t *pgdat = NODE_DATA(nid);
24 struct zone *zone;
25 struct zoneref *z;
26 struct zonelist *zonelist;
27 int i, listid, zoneid;
28
29 BUG_ON(MAX_ZONELISTS > 2);
30 for (i = 0; i < MAX_ZONELISTS * MAX_NR_ZONES; i++) {
31
32 /* Identify the zone and nodelist */
33 zoneid = i % MAX_NR_ZONES;
34 listid = i / MAX_NR_ZONES;
35 zonelist = &pgdat->node_zonelists[listid];
36 zone = &pgdat->node_zones[zoneid];
37 if (!populated_zone(zone))
38 continue;
39
40 /* Print information about the zonelist */
41 printk(KERN_DEBUG "mminit::zonelist %s %d:%s = ",
42 listid > 0 ? "thisnode" : "general", nid,
43 zone->name);
44
45 /* Iterate the zonelist */
46 for_each_zone_zonelist(zone, z, zonelist, zoneid) {
47#ifdef CONFIG_NUMA
48 printk(KERN_CONT "%d:%s ",
49 zone->node, zone->name);
50#else
51 printk(KERN_CONT "0:%s ", zone->name);
52#endif /* CONFIG_NUMA */
53 }
54 printk(KERN_CONT "\n");
55 }
56 }
57}
58
708614e6
MG
59void __init mminit_verify_pageflags_layout(void)
60{
61 int shift, width;
62 unsigned long or_mask, add_mask;
63
64 shift = 8 * sizeof(unsigned long);
65 width = shift - SECTIONS_WIDTH - NODES_WIDTH - ZONES_WIDTH;
66 mminit_dprintk(MMINIT_TRACE, "pageflags_layout_widths",
67 "Section %d Node %d Zone %d Flags %d\n",
68 SECTIONS_WIDTH,
69 NODES_WIDTH,
70 ZONES_WIDTH,
71 NR_PAGEFLAGS);
72 mminit_dprintk(MMINIT_TRACE, "pageflags_layout_shifts",
73 "Section %d Node %d Zone %d\n",
74#ifdef SECTIONS_SHIFT
75 SECTIONS_SHIFT,
76#else
77 0,
78#endif
79 NODES_SHIFT,
80 ZONES_SHIFT);
81 mminit_dprintk(MMINIT_TRACE, "pageflags_layout_offsets",
82 "Section %lu Node %lu Zone %lu\n",
83 (unsigned long)SECTIONS_PGSHIFT,
84 (unsigned long)NODES_PGSHIFT,
85 (unsigned long)ZONES_PGSHIFT);
86 mminit_dprintk(MMINIT_TRACE, "pageflags_layout_zoneid",
87 "Zone ID: %lu -> %lu\n",
88 (unsigned long)ZONEID_PGOFF,
89 (unsigned long)(ZONEID_PGOFF + ZONEID_SHIFT));
90 mminit_dprintk(MMINIT_TRACE, "pageflags_layout_usage",
91 "location: %d -> %d unused %d -> %d flags %d -> %d\n",
92 shift, width, width, NR_PAGEFLAGS, NR_PAGEFLAGS, 0);
93#ifdef NODE_NOT_IN_PAGE_FLAGS
94 mminit_dprintk(MMINIT_TRACE, "pageflags_layout_nodeflags",
95 "Node not in page flags");
96#endif
97
98 if (SECTIONS_WIDTH) {
99 shift -= SECTIONS_WIDTH;
100 BUG_ON(shift != SECTIONS_PGSHIFT);
101 }
102 if (NODES_WIDTH) {
103 shift -= NODES_WIDTH;
104 BUG_ON(shift != NODES_PGSHIFT);
105 }
106 if (ZONES_WIDTH) {
107 shift -= ZONES_WIDTH;
108 BUG_ON(shift != ZONES_PGSHIFT);
109 }
110
111 /* Check for bitmask overlaps */
112 or_mask = (ZONES_MASK << ZONES_PGSHIFT) |
113 (NODES_MASK << NODES_PGSHIFT) |
114 (SECTIONS_MASK << SECTIONS_PGSHIFT);
115 add_mask = (ZONES_MASK << ZONES_PGSHIFT) +
116 (NODES_MASK << NODES_PGSHIFT) +
117 (SECTIONS_MASK << SECTIONS_PGSHIFT);
118 BUG_ON(or_mask != add_mask);
119}
120
121void __meminit mminit_verify_page_links(struct page *page, enum zone_type zone,
122 unsigned long nid, unsigned long pfn)
123{
124 BUG_ON(page_to_nid(page) != nid);
125 BUG_ON(page_zonenum(page) != zone);
126 BUG_ON(page_to_pfn(page) != pfn);
127}
128
6b74ab97
MG
129static __init int set_mminit_loglevel(char *str)
130{
131 get_option(&str, &mminit_loglevel);
132 return 0;
133}
134early_param("mminit_loglevel", set_mminit_loglevel);