| .. | .. |
|---|
| 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 */ |
|---|