1
2#ifndef __LINUX_MEMORY_HOTPLUG_H
3#define __LINUX_MEMORY_HOTPLUG_H
4
5#include <linux/mmzone.h>
6#include <linux/spinlock.h>
7#include <linux/notifier.h>
8#include <linux/bug.h>
9
10struct page;
11struct zone;
12struct pglist_data;
13struct mem_section;
14struct memory_block;
15struct resource;
16struct vmem_altmap;
17
18#ifdef CONFIG_MEMORY_HOTPLUG
19
20
21
22
23
24#define pfn_to_online_page(pfn) \
25({ \
26 struct page *___page = NULL; \
27 unsigned long ___pfn = pfn; \
28 unsigned long ___nr = pfn_to_section_nr(___pfn); \
29 \
30 if (___nr < NR_MEM_SECTIONS && online_section_nr(___nr) && \
31 pfn_valid_within(___pfn)) \
32 ___page = pfn_to_page(___pfn); \
33 ___page; \
34})
35
36
37
38
39
40enum {
41 MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE = 12,
42 SECTION_INFO = MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE,
43 MIX_SECTION_INFO,
44 NODE_INFO,
45 MEMORY_HOTPLUG_MAX_BOOTMEM_TYPE = NODE_INFO,
46};
47
48
49enum {
50 MMOP_OFFLINE = -1,
51 MMOP_ONLINE_KEEP,
52 MMOP_ONLINE_KERNEL,
53 MMOP_ONLINE_MOVABLE,
54};
55
56
57
58
59
60
61struct mhp_restrictions {
62 unsigned long flags;
63 struct vmem_altmap *altmap;
64};
65
66
67
68
69
70
71
72
73static inline unsigned zone_span_seqbegin(struct zone *zone)
74{
75 return read_seqbegin(&zone->span_seqlock);
76}
77static inline int zone_span_seqretry(struct zone *zone, unsigned iv)
78{
79 return read_seqretry(&zone->span_seqlock, iv);
80}
81static inline void zone_span_writelock(struct zone *zone)
82{
83 write_seqlock(&zone->span_seqlock);
84}
85static inline void zone_span_writeunlock(struct zone *zone)
86{
87 write_sequnlock(&zone->span_seqlock);
88}
89static inline void zone_seqlock_init(struct zone *zone)
90{
91 seqlock_init(&zone->span_seqlock);
92}
93extern int zone_grow_free_lists(struct zone *zone, unsigned long new_nr_pages);
94extern int zone_grow_waitqueues(struct zone *zone, unsigned long nr_pages);
95extern int add_one_highpage(struct page *page, int pfn, int bad_ppro);
96
97extern int online_pages(unsigned long, unsigned long, int);
98extern int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn,
99 unsigned long *valid_start, unsigned long *valid_end);
100extern unsigned long __offline_isolated_pages(unsigned long start_pfn,
101 unsigned long end_pfn);
102
103typedef void (*online_page_callback_t)(struct page *page, unsigned int order);
104
105extern int set_online_page_callback(online_page_callback_t callback);
106extern int restore_online_page_callback(online_page_callback_t callback);
107
108extern void __online_page_set_limits(struct page *page);
109extern void __online_page_increment_counters(struct page *page);
110extern void __online_page_free(struct page *page);
111
112extern int try_online_node(int nid);
113
114extern int arch_add_memory(int nid, u64 start, u64 size,
115 struct mhp_restrictions *restrictions);
116extern u64 max_mem_size;
117
118extern bool memhp_auto_online;
119
120extern bool movable_node_enabled;
121static inline bool movable_node_is_enabled(void)
122{
123 return movable_node_enabled;
124}
125
126extern void arch_remove_memory(int nid, u64 start, u64 size,
127 struct vmem_altmap *altmap);
128extern void __remove_pages(struct zone *zone, unsigned long start_pfn,
129 unsigned long nr_pages, struct vmem_altmap *altmap);
130
131
132extern int __add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
133 struct mhp_restrictions *restrictions);
134
135#ifndef CONFIG_ARCH_HAS_ADD_PAGES
136static inline int add_pages(int nid, unsigned long start_pfn,
137 unsigned long nr_pages, struct mhp_restrictions *restrictions)
138{
139 return __add_pages(nid, start_pfn, nr_pages, restrictions);
140}
141#else
142int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
143 struct mhp_restrictions *restrictions);
144#endif
145
146#ifdef CONFIG_NUMA
147extern int memory_add_physaddr_to_nid(u64 start);
148#else
149static inline int memory_add_physaddr_to_nid(u64 start)
150{
151 return 0;
152}
153#endif
154
155#ifdef CONFIG_HAVE_ARCH_NODEDATA_EXTENSION
156
157
158
159
160
161
162
163
164
165
166extern pg_data_t *arch_alloc_nodedata(int nid);
167extern void arch_free_nodedata(pg_data_t *pgdat);
168extern void arch_refresh_nodedata(int nid, pg_data_t *pgdat);
169
170#else
171
172#define arch_alloc_nodedata(nid) generic_alloc_nodedata(nid)
173#define arch_free_nodedata(pgdat) generic_free_nodedata(pgdat)
174
175#ifdef CONFIG_NUMA
176
177
178
179
180
181
182#define generic_alloc_nodedata(nid) \
183({ \
184 kzalloc(sizeof(pg_data_t), GFP_KERNEL); \
185})
186
187
188
189
190#define generic_free_nodedata(pgdat) kfree(pgdat)
191
192extern pg_data_t *node_data[];
193static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)
194{
195 node_data[nid] = pgdat;
196}
197
198#else
199
200
201static inline pg_data_t *generic_alloc_nodedata(int nid)
202{
203 BUG();
204 return NULL;
205}
206static inline void generic_free_nodedata(pg_data_t *pgdat)
207{
208}
209static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)
210{
211}
212#endif
213#endif
214
215#ifdef CONFIG_HAVE_BOOTMEM_INFO_NODE
216extern void __init register_page_bootmem_info_node(struct pglist_data *pgdat);
217#else
218static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
219{
220}
221#endif
222extern void put_page_bootmem(struct page *page);
223extern void get_page_bootmem(unsigned long ingo, struct page *page,
224 unsigned long type);
225
226void get_online_mems(void);
227void put_online_mems(void);
228
229void mem_hotplug_begin(void);
230void mem_hotplug_done(void);
231
232extern void set_zone_contiguous(struct zone *zone);
233extern void clear_zone_contiguous(struct zone *zone);
234
235#else
236#define pfn_to_online_page(pfn) \
237({ \
238 struct page *___page = NULL; \
239 if (pfn_valid(pfn)) \
240 ___page = pfn_to_page(pfn); \
241 ___page; \
242 })
243
244static inline unsigned zone_span_seqbegin(struct zone *zone)
245{
246 return 0;
247}
248static inline int zone_span_seqretry(struct zone *zone, unsigned iv)
249{
250 return 0;
251}
252static inline void zone_span_writelock(struct zone *zone) {}
253static inline void zone_span_writeunlock(struct zone *zone) {}
254static inline void zone_seqlock_init(struct zone *zone) {}
255
256static inline int mhp_notimplemented(const char *func)
257{
258 printk(KERN_WARNING "%s() called, with CONFIG_MEMORY_HOTPLUG disabled\n", func);
259 dump_stack();
260 return -ENOSYS;
261}
262
263static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
264{
265}
266
267static inline int try_online_node(int nid)
268{
269 return 0;
270}
271
272static inline void get_online_mems(void) {}
273static inline void put_online_mems(void) {}
274
275static inline void mem_hotplug_begin(void) {}
276static inline void mem_hotplug_done(void) {}
277
278static inline bool movable_node_is_enabled(void)
279{
280 return false;
281}
282#endif
283
284#if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_DEFERRED_STRUCT_PAGE_INIT)
285
286
287
288static inline
289void pgdat_resize_lock(struct pglist_data *pgdat, unsigned long *flags)
290{
291 spin_lock_irqsave(&pgdat->node_size_lock, *flags);
292}
293static inline
294void pgdat_resize_unlock(struct pglist_data *pgdat, unsigned long *flags)
295{
296 spin_unlock_irqrestore(&pgdat->node_size_lock, *flags);
297}
298static inline
299void pgdat_resize_init(struct pglist_data *pgdat)
300{
301 spin_lock_init(&pgdat->node_size_lock);
302}
303#else
304
305
306
307static inline void pgdat_resize_lock(struct pglist_data *p, unsigned long *f) {}
308static inline void pgdat_resize_unlock(struct pglist_data *p, unsigned long *f) {}
309static inline void pgdat_resize_init(struct pglist_data *pgdat) {}
310#endif
311
312#ifdef CONFIG_MEMORY_HOTREMOVE
313
314extern bool is_mem_section_removable(unsigned long pfn, unsigned long nr_pages);
315extern void try_offline_node(int nid);
316extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
317extern int remove_memory(int nid, u64 start, u64 size);
318extern void __remove_memory(int nid, u64 start, u64 size);
319
320#else
321static inline bool is_mem_section_removable(unsigned long pfn,
322 unsigned long nr_pages)
323{
324 return false;
325}
326
327static inline void try_offline_node(int nid) {}
328
329static inline int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
330{
331 return -EINVAL;
332}
333
334static inline int remove_memory(int nid, u64 start, u64 size)
335{
336 return -EBUSY;
337}
338
339static inline void __remove_memory(int nid, u64 start, u64 size) {}
340#endif
341
342extern void __ref free_area_init_core_hotplug(int nid);
343extern int __add_memory(int nid, u64 start, u64 size);
344extern int add_memory(int nid, u64 start, u64 size);
345extern int add_memory_resource(int nid, struct resource *resource);
346extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn,
347 unsigned long nr_pages, struct vmem_altmap *altmap);
348extern bool is_memblock_offlined(struct memory_block *mem);
349extern int sparse_add_section(int nid, unsigned long pfn,
350 unsigned long nr_pages, struct vmem_altmap *altmap);
351extern void sparse_remove_section(struct mem_section *ms,
352 unsigned long pfn, unsigned long nr_pages,
353 unsigned long map_offset, struct vmem_altmap *altmap);
354extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map,
355 unsigned long pnum);
356extern bool allow_online_pfn_range(int nid, unsigned long pfn, unsigned long nr_pages,
357 int online_type);
358extern struct zone *zone_for_pfn_range(int online_type, int nid, unsigned start_pfn,
359 unsigned long nr_pages);
360#endif
361