Blame view

mm/mm_init.c 4.84 KB
6b74ab97b   Mel Gorman   mm: add a basic d...
1
2
3
4
5
6
7
8
9
  /*
   * mm_init.c - Memory initialisation verification and debugging
   *
   * Copyright 2008 IBM Corporation, 2008
   * Author Mel Gorman <mel@csn.ul.ie>
   *
   */
  #include <linux/kernel.h>
  #include <linux/init.h>
ff7ea79cf   Nishanth Aravamudan   mm: create /sys/k...
10
  #include <linux/kobject.h>
b95f1b31b   Paul Gortmaker   mm: Map most file...
11
  #include <linux/export.h>
917d9290a   Tim Chen   mm: tune vm_commi...
12
13
  #include <linux/memory.h>
  #include <linux/notifier.h>
7e18adb4f   Mel Gorman   mm: meminit: init...
14
  #include <linux/sched.h>
708614e61   Mel Gorman   mm: verify the pa...
15
  #include "internal.h"
6b74ab97b   Mel Gorman   mm: add a basic d...
16

5e9426abe   Nishanth Aravamudan   mm: remove mm_ini...
17
  #ifdef CONFIG_DEBUG_MEMORY_INIT
194e81512   Rasmus Villemoes   mm/mm_init.c: mar...
18
  int __meminitdata mminit_loglevel;
6b74ab97b   Mel Gorman   mm: add a basic d...
19

5c9ffc9c3   Andrew Morton   mm_init.c: avoid ...
20
21
22
  #ifndef SECTIONS_SHIFT
  #define SECTIONS_SHIFT	0
  #endif
68ad8df42   Mel Gorman   mm: print out the...
23
  /* The zonelists are simply reported, validation is manual. */
0e2342c70   Rasmus Villemoes   mm/mm_init.c: par...
24
  void __init mminit_verify_zonelist(void)
68ad8df42   Mel Gorman   mm: print out the...
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  {
  	int nid;
  
  	if (mminit_loglevel < MMINIT_VERIFY)
  		return;
  
  	for_each_online_node(nid) {
  		pg_data_t *pgdat = NODE_DATA(nid);
  		struct zone *zone;
  		struct zoneref *z;
  		struct zonelist *zonelist;
  		int i, listid, zoneid;
  
  		BUG_ON(MAX_ZONELISTS > 2);
  		for (i = 0; i < MAX_ZONELISTS * MAX_NR_ZONES; i++) {
  
  			/* Identify the zone and nodelist */
  			zoneid = i % MAX_NR_ZONES;
  			listid = i / MAX_NR_ZONES;
  			zonelist = &pgdat->node_zonelists[listid];
  			zone = &pgdat->node_zones[zoneid];
  			if (!populated_zone(zone))
  				continue;
  
  			/* Print information about the zonelist */
  			printk(KERN_DEBUG "mminit::zonelist %s %d:%s = ",
  				listid > 0 ? "thisnode" : "general", nid,
  				zone->name);
  
  			/* Iterate the zonelist */
  			for_each_zone_zonelist(zone, z, zonelist, zoneid) {
  #ifdef CONFIG_NUMA
1170532bb   Joe Perches   mm: convert print...
57
  				pr_cont("%d:%s ", zone->node, zone->name);
68ad8df42   Mel Gorman   mm: print out the...
58
  #else
1170532bb   Joe Perches   mm: convert print...
59
  				pr_cont("0:%s ", zone->name);
68ad8df42   Mel Gorman   mm: print out the...
60
61
  #endif /* CONFIG_NUMA */
  			}
1170532bb   Joe Perches   mm: convert print...
62
63
  			pr_cont("
  ");
68ad8df42   Mel Gorman   mm: print out the...
64
65
66
  		}
  	}
  }
708614e61   Mel Gorman   mm: verify the pa...
67
68
69
70
71
72
  void __init mminit_verify_pageflags_layout(void)
  {
  	int shift, width;
  	unsigned long or_mask, add_mask;
  
  	shift = 8 * sizeof(unsigned long);
90572890d   Peter Zijlstra   mm: numa: Change ...
73
  	width = shift - SECTIONS_WIDTH - NODES_WIDTH - ZONES_WIDTH - LAST_CPUPID_SHIFT;
708614e61   Mel Gorman   mm: verify the pa...
74
  	mminit_dprintk(MMINIT_TRACE, "pageflags_layout_widths",
90572890d   Peter Zijlstra   mm: numa: Change ...
75
76
  		"Section %d Node %d Zone %d Lastcpupid %d Flags %d
  ",
708614e61   Mel Gorman   mm: verify the pa...
77
78
79
  		SECTIONS_WIDTH,
  		NODES_WIDTH,
  		ZONES_WIDTH,
90572890d   Peter Zijlstra   mm: numa: Change ...
80
  		LAST_CPUPID_WIDTH,
708614e61   Mel Gorman   mm: verify the pa...
81
82
  		NR_PAGEFLAGS);
  	mminit_dprintk(MMINIT_TRACE, "pageflags_layout_shifts",
90572890d   Peter Zijlstra   mm: numa: Change ...
83
84
  		"Section %d Node %d Zone %d Lastcpupid %d
  ",
708614e61   Mel Gorman   mm: verify the pa...
85
  		SECTIONS_SHIFT,
708614e61   Mel Gorman   mm: verify the pa...
86
  		NODES_SHIFT,
a4e1b4c6c   Mel Gorman   mm: init: report ...
87
  		ZONES_SHIFT,
90572890d   Peter Zijlstra   mm: numa: Change ...
88
  		LAST_CPUPID_SHIFT);
a4e1b4c6c   Mel Gorman   mm: init: report ...
89
  	mminit_dprintk(MMINIT_TRACE, "pageflags_layout_pgshifts",
90572890d   Peter Zijlstra   mm: numa: Change ...
90
91
  		"Section %lu Node %lu Zone %lu Lastcpupid %lu
  ",
708614e61   Mel Gorman   mm: verify the pa...
92
93
  		(unsigned long)SECTIONS_PGSHIFT,
  		(unsigned long)NODES_PGSHIFT,
a4e1b4c6c   Mel Gorman   mm: init: report ...
94
  		(unsigned long)ZONES_PGSHIFT,
90572890d   Peter Zijlstra   mm: numa: Change ...
95
  		(unsigned long)LAST_CPUPID_PGSHIFT);
a4e1b4c6c   Mel Gorman   mm: init: report ...
96
97
98
99
100
  	mminit_dprintk(MMINIT_TRACE, "pageflags_layout_nodezoneid",
  		"Node/Zone ID: %lu -> %lu
  ",
  		(unsigned long)(ZONEID_PGOFF + ZONEID_SHIFT),
  		(unsigned long)ZONEID_PGOFF);
708614e61   Mel Gorman   mm: verify the pa...
101
  	mminit_dprintk(MMINIT_TRACE, "pageflags_layout_usage",
a4e1b4c6c   Mel Gorman   mm: init: report ...
102
103
  		"location: %d -> %d layout %d -> %d unused %d -> %d page-flags
  ",
708614e61   Mel Gorman   mm: verify the pa...
104
105
106
107
108
  		shift, width, width, NR_PAGEFLAGS, NR_PAGEFLAGS, 0);
  #ifdef NODE_NOT_IN_PAGE_FLAGS
  	mminit_dprintk(MMINIT_TRACE, "pageflags_layout_nodeflags",
  		"Node not in page flags");
  #endif
90572890d   Peter Zijlstra   mm: numa: Change ...
109
  #ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
a4e1b4c6c   Mel Gorman   mm: init: report ...
110
  	mminit_dprintk(MMINIT_TRACE, "pageflags_layout_nodeflags",
90572890d   Peter Zijlstra   mm: numa: Change ...
111
  		"Last cpupid not in page flags");
a4e1b4c6c   Mel Gorman   mm: init: report ...
112
  #endif
708614e61   Mel Gorman   mm: verify the pa...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
  
  	if (SECTIONS_WIDTH) {
  		shift -= SECTIONS_WIDTH;
  		BUG_ON(shift != SECTIONS_PGSHIFT);
  	}
  	if (NODES_WIDTH) {
  		shift -= NODES_WIDTH;
  		BUG_ON(shift != NODES_PGSHIFT);
  	}
  	if (ZONES_WIDTH) {
  		shift -= ZONES_WIDTH;
  		BUG_ON(shift != ZONES_PGSHIFT);
  	}
  
  	/* Check for bitmask overlaps */
  	or_mask = (ZONES_MASK << ZONES_PGSHIFT) |
  			(NODES_MASK << NODES_PGSHIFT) |
  			(SECTIONS_MASK << SECTIONS_PGSHIFT);
  	add_mask = (ZONES_MASK << ZONES_PGSHIFT) +
  			(NODES_MASK << NODES_PGSHIFT) +
  			(SECTIONS_MASK << SECTIONS_PGSHIFT);
  	BUG_ON(or_mask != add_mask);
  }
6b74ab97b   Mel Gorman   mm: add a basic d...
136
137
138
139
140
141
  static __init int set_mminit_loglevel(char *str)
  {
  	get_option(&str, &mminit_loglevel);
  	return 0;
  }
  early_param("mminit_loglevel", set_mminit_loglevel);
5e9426abe   Nishanth Aravamudan   mm: remove mm_ini...
142
  #endif /* CONFIG_DEBUG_MEMORY_INIT */
ff7ea79cf   Nishanth Aravamudan   mm: create /sys/k...
143
144
145
  
  struct kobject *mm_kobj;
  EXPORT_SYMBOL_GPL(mm_kobj);
917d9290a   Tim Chen   mm: tune vm_commi...
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
  #ifdef CONFIG_SMP
  s32 vm_committed_as_batch = 32;
  
  static void __meminit mm_compute_batch(void)
  {
  	u64 memsized_batch;
  	s32 nr = num_present_cpus();
  	s32 batch = max_t(s32, nr*2, 32);
  
  	/* batch size set to 0.4% of (total memory/#cpus), or max int32 */
  	memsized_batch = min_t(u64, (totalram_pages/nr)/256, 0x7fffffff);
  
  	vm_committed_as_batch = max_t(s32, memsized_batch, batch);
  }
  
  static int __meminit mm_compute_batch_notifier(struct notifier_block *self,
  					unsigned long action, void *arg)
  {
  	switch (action) {
  	case MEM_ONLINE:
  	case MEM_OFFLINE:
  		mm_compute_batch();
  	default:
  		break;
  	}
  	return NOTIFY_OK;
  }
  
  static struct notifier_block compute_batch_nb __meminitdata = {
  	.notifier_call = mm_compute_batch_notifier,
  	.priority = IPC_CALLBACK_PRI, /* use lowest priority */
  };
  
  static int __init mm_compute_batch_init(void)
  {
  	mm_compute_batch();
  	register_hotmemory_notifier(&compute_batch_nb);
  
  	return 0;
  }
  
  __initcall(mm_compute_batch_init);
  
  #endif
ff7ea79cf   Nishanth Aravamudan   mm: create /sys/k...
190
191
192
193
194
195
196
197
  static int __init mm_sysfs_init(void)
  {
  	mm_kobj = kobject_create_and_add("mm", kernel_kobj);
  	if (!mm_kobj)
  		return -ENOMEM;
  
  	return 0;
  }
e82cb95d6   Hugh Dickins   mm: bring back /s...
198
  postcore_initcall(mm_sysfs_init);