.. | .. |
---|
47 | 47 | |
---|
48 | 48 | /* Types for control the zone type of onlined and offlined memory */ |
---|
49 | 49 | enum { |
---|
50 | | - MMOP_OFFLINE = -1, |
---|
51 | | - MMOP_ONLINE_KEEP, |
---|
| 50 | + /* Offline the memory. */ |
---|
| 51 | + MMOP_OFFLINE = 0, |
---|
| 52 | + /* Online the memory. Zone depends, see default_zone_for_pfn(). */ |
---|
| 53 | + MMOP_ONLINE, |
---|
| 54 | + /* Online the memory to ZONE_NORMAL. */ |
---|
52 | 55 | MMOP_ONLINE_KERNEL, |
---|
| 56 | + /* Online the memory to ZONE_MOVABLE. */ |
---|
53 | 57 | MMOP_ONLINE_MOVABLE, |
---|
| 58 | +}; |
---|
| 59 | + |
---|
| 60 | +/* Flags for add_memory() and friends to specify memory hotplug details. */ |
---|
| 61 | +typedef int __bitwise mhp_t; |
---|
| 62 | + |
---|
| 63 | +/* No special request */ |
---|
| 64 | +#define MHP_NONE ((__force mhp_t)0) |
---|
| 65 | +/* |
---|
| 66 | + * Allow merging of the added System RAM resource with adjacent, |
---|
| 67 | + * mergeable resources. After a successful call to add_memory_resource() |
---|
| 68 | + * with this flag set, the resource pointer must no longer be used as it |
---|
| 69 | + * might be stale, or the resource might have changed. |
---|
| 70 | + */ |
---|
| 71 | +#define MEMHP_MERGE_RESOURCE ((__force mhp_t)BIT(0)) |
---|
| 72 | + |
---|
| 73 | +/* |
---|
| 74 | + * Extended parameters for memory hotplug: |
---|
| 75 | + * altmap: alternative allocator for memmap array (optional) |
---|
| 76 | + * pgprot: page protection flags to apply to newly created page tables |
---|
| 77 | + * (required) |
---|
| 78 | + */ |
---|
| 79 | +struct mhp_params { |
---|
| 80 | + struct vmem_altmap *altmap; |
---|
| 81 | + pgprot_t pgprot; |
---|
54 | 82 | }; |
---|
55 | 83 | |
---|
56 | 84 | /* |
---|
.. | .. |
---|
84 | 112 | extern int zone_grow_waitqueues(struct zone *zone, unsigned long nr_pages); |
---|
85 | 113 | extern int add_one_highpage(struct page *page, int pfn, int bad_ppro); |
---|
86 | 114 | /* VM interface that may be used by firmware interface */ |
---|
87 | | -extern int online_pages(unsigned long, unsigned long, int); |
---|
88 | | -extern int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn, |
---|
89 | | - unsigned long *valid_start, unsigned long *valid_end); |
---|
90 | | -extern void __offline_isolated_pages(unsigned long, unsigned long); |
---|
| 115 | +extern int online_pages(unsigned long pfn, unsigned long nr_pages, |
---|
| 116 | + int online_type, int nid); |
---|
| 117 | +extern struct zone *test_pages_in_a_zone(unsigned long start_pfn, |
---|
| 118 | + unsigned long end_pfn); |
---|
| 119 | +extern void __offline_isolated_pages(unsigned long start_pfn, |
---|
| 120 | + unsigned long end_pfn); |
---|
91 | 121 | |
---|
92 | | -typedef void (*online_page_callback_t)(struct page *page); |
---|
| 122 | +typedef void (*online_page_callback_t)(struct page *page, unsigned int order); |
---|
93 | 123 | |
---|
| 124 | +extern void generic_online_page(struct page *page, unsigned int order); |
---|
94 | 125 | extern int set_online_page_callback(online_page_callback_t callback); |
---|
95 | 126 | extern int restore_online_page_callback(online_page_callback_t callback); |
---|
96 | 127 | |
---|
97 | | -extern void __online_page_set_limits(struct page *page); |
---|
98 | | -extern void __online_page_increment_counters(struct page *page); |
---|
99 | | -extern void __online_page_free(struct page *page); |
---|
100 | | - |
---|
101 | 128 | extern int try_online_node(int nid); |
---|
102 | 129 | |
---|
103 | | -extern bool memhp_auto_online; |
---|
| 130 | +extern int arch_add_memory(int nid, u64 start, u64 size, |
---|
| 131 | + struct mhp_params *params); |
---|
| 132 | +extern u64 max_mem_size; |
---|
| 133 | + |
---|
| 134 | +extern int memhp_online_type_from_str(const char *str); |
---|
| 135 | + |
---|
| 136 | +/* Default online_type (MMOP_*) when new memory blocks are added. */ |
---|
| 137 | +extern int memhp_default_online_type; |
---|
104 | 138 | /* If movable_node boot option specified */ |
---|
105 | 139 | extern bool movable_node_enabled; |
---|
106 | 140 | static inline bool movable_node_is_enabled(void) |
---|
.. | .. |
---|
115 | 149 | |
---|
116 | 150 | /* reasonably generic interface to expand the physical pages */ |
---|
117 | 151 | extern int __add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages, |
---|
118 | | - struct vmem_altmap *altmap, bool want_memblock); |
---|
| 152 | + struct mhp_params *params); |
---|
119 | 153 | |
---|
120 | 154 | #ifndef CONFIG_ARCH_HAS_ADD_PAGES |
---|
121 | 155 | static inline int add_pages(int nid, unsigned long start_pfn, |
---|
122 | | - unsigned long nr_pages, struct vmem_altmap *altmap, |
---|
123 | | - bool want_memblock) |
---|
| 156 | + unsigned long nr_pages, struct mhp_params *params) |
---|
124 | 157 | { |
---|
125 | | - return __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock); |
---|
| 158 | + return __add_pages(nid, start_pfn, nr_pages, params); |
---|
126 | 159 | } |
---|
127 | 160 | #else /* ARCH_HAS_ADD_PAGES */ |
---|
128 | 161 | int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages, |
---|
129 | | - struct vmem_altmap *altmap, bool want_memblock); |
---|
| 162 | + struct mhp_params *params); |
---|
130 | 163 | #endif /* ARCH_HAS_ADD_PAGES */ |
---|
131 | | - |
---|
132 | | -#ifdef CONFIG_NUMA |
---|
133 | | -extern int memory_add_physaddr_to_nid(u64 start); |
---|
134 | | -#else |
---|
135 | | -static inline int memory_add_physaddr_to_nid(u64 start) |
---|
136 | | -{ |
---|
137 | | - return 0; |
---|
138 | | -} |
---|
139 | | -#endif |
---|
140 | 164 | |
---|
141 | 165 | #ifdef CONFIG_HAVE_ARCH_NODEDATA_EXTENSION |
---|
142 | 166 | /* |
---|
.. | .. |
---|
215 | 239 | void mem_hotplug_begin(void); |
---|
216 | 240 | void mem_hotplug_done(void); |
---|
217 | 241 | |
---|
218 | | -extern void set_zone_contiguous(struct zone *zone); |
---|
219 | | -extern void clear_zone_contiguous(struct zone *zone); |
---|
220 | | - |
---|
221 | 242 | #else /* ! CONFIG_MEMORY_HOTPLUG */ |
---|
222 | 243 | #define pfn_to_online_page(pfn) \ |
---|
223 | 244 | ({ \ |
---|
.. | .. |
---|
238 | 259 | static inline void zone_span_writelock(struct zone *zone) {} |
---|
239 | 260 | static inline void zone_span_writeunlock(struct zone *zone) {} |
---|
240 | 261 | static inline void zone_seqlock_init(struct zone *zone) {} |
---|
241 | | - |
---|
242 | | -static inline int mhp_notimplemented(const char *func) |
---|
243 | | -{ |
---|
244 | | - printk(KERN_WARNING "%s() called, with CONFIG_MEMORY_HOTPLUG disabled\n", func); |
---|
245 | | - dump_stack(); |
---|
246 | | - return -ENOSYS; |
---|
247 | | -} |
---|
248 | 262 | |
---|
249 | 263 | static inline void register_page_bootmem_info_node(struct pglist_data *pgdat) |
---|
250 | 264 | { |
---|
.. | .. |
---|
297 | 311 | |
---|
298 | 312 | #ifdef CONFIG_MEMORY_HOTREMOVE |
---|
299 | 313 | |
---|
300 | | -extern bool is_mem_section_removable(unsigned long pfn, unsigned long nr_pages); |
---|
301 | 314 | extern void try_offline_node(int nid); |
---|
302 | 315 | extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); |
---|
303 | | -extern void remove_memory(int nid, u64 start, u64 size); |
---|
| 316 | +extern int remove_memory(int nid, u64 start, u64 size); |
---|
| 317 | +extern int remove_memory_subsection(int nid, u64 start, u64 size); |
---|
304 | 318 | extern void __remove_memory(int nid, u64 start, u64 size); |
---|
| 319 | +extern int offline_and_remove_memory(int nid, u64 start, u64 size); |
---|
305 | 320 | |
---|
306 | 321 | #else |
---|
307 | | -static inline bool is_mem_section_removable(unsigned long pfn, |
---|
308 | | - unsigned long nr_pages) |
---|
309 | | -{ |
---|
310 | | - return false; |
---|
311 | | -} |
---|
312 | | - |
---|
313 | 322 | static inline void try_offline_node(int nid) {} |
---|
314 | 323 | |
---|
315 | 324 | static inline int offline_pages(unsigned long start_pfn, unsigned long nr_pages) |
---|
.. | .. |
---|
317 | 326 | return -EINVAL; |
---|
318 | 327 | } |
---|
319 | 328 | |
---|
320 | | -static inline void remove_memory(int nid, u64 start, u64 size) {} |
---|
| 329 | +static inline int remove_memory(int nid, u64 start, u64 size) |
---|
| 330 | +{ |
---|
| 331 | + return -EBUSY; |
---|
| 332 | +} |
---|
| 333 | + |
---|
321 | 334 | static inline void __remove_memory(int nid, u64 start, u64 size) {} |
---|
322 | 335 | #endif /* CONFIG_MEMORY_HOTREMOVE */ |
---|
323 | 336 | |
---|
| 337 | +extern void set_zone_contiguous(struct zone *zone); |
---|
| 338 | +extern void clear_zone_contiguous(struct zone *zone); |
---|
| 339 | + |
---|
| 340 | +#ifdef CONFIG_MEMORY_HOTPLUG |
---|
324 | 341 | extern void __ref free_area_init_core_hotplug(int nid); |
---|
325 | | -extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn, |
---|
326 | | - void *arg, int (*func)(struct memory_block *, void *)); |
---|
327 | | -extern int __add_memory(int nid, u64 start, u64 size); |
---|
328 | | -extern int add_memory(int nid, u64 start, u64 size); |
---|
329 | | -extern int add_memory_resource(int nid, struct resource *resource, bool online); |
---|
330 | | -extern int arch_add_memory(int nid, u64 start, u64 size, |
---|
331 | | - struct vmem_altmap *altmap, bool want_memblock); |
---|
| 342 | +extern int __add_memory(int nid, u64 start, u64 size, mhp_t mhp_flags); |
---|
| 343 | +extern int add_memory(int nid, u64 start, u64 size, mhp_t mhp_flags); |
---|
| 344 | +extern int add_memory_subsection(int nid, u64 start, u64 size); |
---|
| 345 | +extern int add_memory_resource(int nid, struct resource *resource, |
---|
| 346 | + mhp_t mhp_flags); |
---|
| 347 | +extern int add_memory_driver_managed(int nid, u64 start, u64 size, |
---|
| 348 | + const char *resource_name, |
---|
| 349 | + mhp_t mhp_flags); |
---|
332 | 350 | extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn, |
---|
333 | | - unsigned long nr_pages, struct vmem_altmap *altmap); |
---|
| 351 | + unsigned long nr_pages, |
---|
| 352 | + struct vmem_altmap *altmap, int migratetype); |
---|
334 | 353 | extern void remove_pfn_range_from_zone(struct zone *zone, |
---|
335 | 354 | unsigned long start_pfn, |
---|
336 | 355 | unsigned long nr_pages); |
---|
337 | | -extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); |
---|
338 | 356 | extern bool is_memblock_offlined(struct memory_block *mem); |
---|
339 | | -extern int sparse_add_one_section(int nid, unsigned long start_pfn, |
---|
340 | | - struct vmem_altmap *altmap); |
---|
341 | | -extern void sparse_remove_one_section(struct mem_section *ms, |
---|
| 357 | +extern int sparse_add_section(int nid, unsigned long pfn, |
---|
| 358 | + unsigned long nr_pages, struct vmem_altmap *altmap); |
---|
| 359 | +extern void sparse_remove_section(struct mem_section *ms, |
---|
| 360 | + unsigned long pfn, unsigned long nr_pages, |
---|
342 | 361 | unsigned long map_offset, struct vmem_altmap *altmap); |
---|
343 | 362 | extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map, |
---|
344 | 363 | unsigned long pnum); |
---|
345 | | -extern bool allow_online_pfn_range(int nid, unsigned long pfn, unsigned long nr_pages, |
---|
346 | | - int online_type); |
---|
347 | 364 | extern struct zone *zone_for_pfn_range(int online_type, int nid, |
---|
348 | 365 | unsigned long start_pfn, unsigned long nr_pages); |
---|
| 366 | +#endif /* CONFIG_MEMORY_HOTPLUG */ |
---|
| 367 | + |
---|
349 | 368 | #endif /* __LINUX_MEMORY_HOTPLUG_H */ |
---|