Blame view

mm/mm_init.c 5.31 KB
457c89965   Thomas Gleixner   treewide: Add SPD...
1
  // SPDX-License-Identifier: GPL-2.0-only
6b74ab97b   Mel Gorman   mm: add a basic d...
2
3
4
5
6
7
8
9
10
  /*
   * 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...
11
  #include <linux/kobject.h>
b95f1b31b   Paul Gortmaker   mm: Map most file...
12
  #include <linux/export.h>
917d9290a   Tim Chen   mm: tune vm_commi...
13
14
  #include <linux/memory.h>
  #include <linux/notifier.h>
7e18adb4f   Mel Gorman   mm: meminit: init...
15
  #include <linux/sched.h>
56f3547bf   Feng Tang   mm: adjust vm_com...
16
  #include <linux/mman.h>
708614e61   Mel Gorman   mm: verify the pa...
17
  #include "internal.h"
6b74ab97b   Mel Gorman   mm: add a basic d...
18

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

5c9ffc9c3   Andrew Morton   mm_init.c: avoid ...
22
23
24
  #ifndef SECTIONS_SHIFT
  #define SECTIONS_SHIFT	0
  #endif
68ad8df42   Mel Gorman   mm: print out the...
25
  /* The zonelists are simply reported, validation is manual. */
0e2342c70   Rasmus Villemoes   mm/mm_init.c: par...
26
  void __init mminit_verify_zonelist(void)
68ad8df42   Mel Gorman   mm: print out the...
27
28
29
30
31
32
33
34
35
36
37
38
  {
  	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;
e46b893dd   Mateusz Nosek   mm/mm_init.c: cle...
39
  		BUILD_BUG_ON(MAX_ZONELISTS > 2);
68ad8df42   Mel Gorman   mm: print out the...
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  		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 */
c1093b746   Pavel Tatashin   mm: access zone->...
56
57
  			for_each_zone_zonelist(zone, z, zonelist, zoneid)
  				pr_cont("%d:%s ", zone_to_nid(zone), zone->name);
1170532bb   Joe Perches   mm: convert print...
58
59
  			pr_cont("
  ");
68ad8df42   Mel Gorman   mm: print out the...
60
61
62
  		}
  	}
  }
708614e61   Mel Gorman   mm: verify the pa...
63
64
65
66
67
68
  void __init mminit_verify_pageflags_layout(void)
  {
  	int shift, width;
  	unsigned long or_mask, add_mask;
  
  	shift = 8 * sizeof(unsigned long);
86fea8b49   Jing Xia   mm/mm_init.c: rep...
69
70
  	width = shift - SECTIONS_WIDTH - NODES_WIDTH - ZONES_WIDTH
  		- LAST_CPUPID_SHIFT - KASAN_TAG_WIDTH;
708614e61   Mel Gorman   mm: verify the pa...
71
  	mminit_dprintk(MMINIT_TRACE, "pageflags_layout_widths",
86fea8b49   Jing Xia   mm/mm_init.c: rep...
72
73
  		"Section %d Node %d Zone %d Lastcpupid %d Kasantag %d Flags %d
  ",
708614e61   Mel Gorman   mm: verify the pa...
74
75
76
  		SECTIONS_WIDTH,
  		NODES_WIDTH,
  		ZONES_WIDTH,
90572890d   Peter Zijlstra   mm: numa: Change ...
77
  		LAST_CPUPID_WIDTH,
86fea8b49   Jing Xia   mm/mm_init.c: rep...
78
  		KASAN_TAG_WIDTH,
708614e61   Mel Gorman   mm: verify the pa...
79
80
  		NR_PAGEFLAGS);
  	mminit_dprintk(MMINIT_TRACE, "pageflags_layout_shifts",
86fea8b49   Jing Xia   mm/mm_init.c: rep...
81
82
  		"Section %d Node %d Zone %d Lastcpupid %d Kasantag %d
  ",
708614e61   Mel Gorman   mm: verify the pa...
83
  		SECTIONS_SHIFT,
708614e61   Mel Gorman   mm: verify the pa...
84
  		NODES_SHIFT,
a4e1b4c6c   Mel Gorman   mm: init: report ...
85
  		ZONES_SHIFT,
86fea8b49   Jing Xia   mm/mm_init.c: rep...
86
87
  		LAST_CPUPID_SHIFT,
  		KASAN_TAG_WIDTH);
a4e1b4c6c   Mel Gorman   mm: init: report ...
88
  	mminit_dprintk(MMINIT_TRACE, "pageflags_layout_pgshifts",
86fea8b49   Jing Xia   mm/mm_init.c: rep...
89
90
  		"Section %lu Node %lu Zone %lu Lastcpupid %lu Kasantag %lu
  ",
708614e61   Mel Gorman   mm: verify the pa...
91
92
  		(unsigned long)SECTIONS_PGSHIFT,
  		(unsigned long)NODES_PGSHIFT,
a4e1b4c6c   Mel Gorman   mm: init: report ...
93
  		(unsigned long)ZONES_PGSHIFT,
86fea8b49   Jing Xia   mm/mm_init.c: rep...
94
95
  		(unsigned long)LAST_CPUPID_PGSHIFT,
  		(unsigned long)KASAN_TAG_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
  #ifdef CONFIG_SMP
  s32 vm_committed_as_batch = 32;
56f3547bf   Feng Tang   mm: adjust vm_com...
148
  void mm_compute_batch(int overcommit_policy)
917d9290a   Tim Chen   mm: tune vm_commi...
149
150
151
152
  {
  	u64 memsized_batch;
  	s32 nr = num_present_cpus();
  	s32 batch = max_t(s32, nr*2, 32);
56f3547bf   Feng Tang   mm: adjust vm_com...
153
154
155
156
157
158
159
160
161
162
163
164
  	unsigned long ram_pages = totalram_pages();
  
  	/*
  	 * For policy OVERCOMMIT_NEVER, set batch size to 0.4% of
  	 * (total memory/#cpus), and lift it to 25% for other policies
  	 * to easy the possible lock contention for percpu_counter
  	 * vm_committed_as, while the max limit is INT_MAX
  	 */
  	if (overcommit_policy == OVERCOMMIT_NEVER)
  		memsized_batch = min_t(u64, ram_pages/nr/256, INT_MAX);
  	else
  		memsized_batch = min_t(u64, ram_pages/nr/4, INT_MAX);
917d9290a   Tim Chen   mm: tune vm_commi...
165
166
167
168
169
170
171
172
173
174
  
  	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:
56f3547bf   Feng Tang   mm: adjust vm_com...
175
  		mm_compute_batch(sysctl_overcommit_memory);
917d9290a   Tim Chen   mm: tune vm_commi...
176
177
178
179
180
181
182
183
184
185
186
187
188
  	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)
  {
56f3547bf   Feng Tang   mm: adjust vm_com...
189
  	mm_compute_batch(sysctl_overcommit_memory);
917d9290a   Tim Chen   mm: tune vm_commi...
190
191
192
193
194
195
196
197
  	register_hotmemory_notifier(&compute_batch_nb);
  
  	return 0;
  }
  
  __initcall(mm_compute_batch_init);
  
  #endif
ff7ea79cf   Nishanth Aravamudan   mm: create /sys/k...
198
199
200
201
202
203
204
205
  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...
206
  postcore_initcall(mm_sysfs_init);