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