aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/memblock.h24
-rw-r--r--mm/memblock.c12
-rw-r--r--mm/memory_hotplug.c1
3 files changed, 37 insertions, 0 deletions
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 97480d392e40..2f52c8c492bd 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -47,6 +47,10 @@ struct memblock {
47 47
48extern struct memblock memblock; 48extern struct memblock memblock;
49extern int memblock_debug; 49extern int memblock_debug;
50#ifdef CONFIG_MOVABLE_NODE
51/* If movable_node boot option specified */
52extern bool movable_node_enabled;
53#endif /* CONFIG_MOVABLE_NODE */
50 54
51#define memblock_dbg(fmt, ...) \ 55#define memblock_dbg(fmt, ...) \
52 if (memblock_debug) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) 56 if (memblock_debug) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
@@ -65,6 +69,26 @@ int memblock_reserve(phys_addr_t base, phys_addr_t size);
65void memblock_trim_memory(phys_addr_t align); 69void memblock_trim_memory(phys_addr_t align);
66int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size); 70int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size);
67int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size); 71int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);
72#ifdef CONFIG_MOVABLE_NODE
73static inline bool memblock_is_hotpluggable(struct memblock_region *m)
74{
75 return m->flags & MEMBLOCK_HOTPLUG;
76}
77
78static inline bool movable_node_is_enabled(void)
79{
80 return movable_node_enabled;
81}
82#else
83static inline bool memblock_is_hotpluggable(struct memblock_region *m)
84{
85 return false;
86}
87static inline bool movable_node_is_enabled(void)
88{
89 return false;
90}
91#endif
68 92
69#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP 93#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
70int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn, 94int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn,
diff --git a/mm/memblock.c b/mm/memblock.c
index d5681008dce1..6a2a48a122a9 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -39,6 +39,9 @@ struct memblock memblock __initdata_memblock = {
39}; 39};
40 40
41int memblock_debug __initdata_memblock; 41int memblock_debug __initdata_memblock;
42#ifdef CONFIG_MOVABLE_NODE
43bool movable_node_enabled __initdata_memblock = false;
44#endif
42static int memblock_can_resize __initdata_memblock; 45static int memblock_can_resize __initdata_memblock;
43static int memblock_memory_in_slab __initdata_memblock = 0; 46static int memblock_memory_in_slab __initdata_memblock = 0;
44static int memblock_reserved_in_slab __initdata_memblock = 0; 47static int memblock_reserved_in_slab __initdata_memblock = 0;
@@ -820,6 +823,11 @@ void __init_memblock __next_free_mem_range(u64 *idx, int nid,
820 * @out_nid: ptr to int for nid of the range, can be %NULL 823 * @out_nid: ptr to int for nid of the range, can be %NULL
821 * 824 *
822 * Reverse of __next_free_mem_range(). 825 * Reverse of __next_free_mem_range().
826 *
827 * Linux kernel cannot migrate pages used by itself. Memory hotplug users won't
828 * be able to hot-remove hotpluggable memory used by the kernel. So this
829 * function skip hotpluggable regions if needed when allocating memory for the
830 * kernel.
823 */ 831 */
824void __init_memblock __next_free_mem_range_rev(u64 *idx, int nid, 832void __init_memblock __next_free_mem_range_rev(u64 *idx, int nid,
825 phys_addr_t *out_start, 833 phys_addr_t *out_start,
@@ -844,6 +852,10 @@ void __init_memblock __next_free_mem_range_rev(u64 *idx, int nid,
844 if (nid != MAX_NUMNODES && nid != memblock_get_region_node(m)) 852 if (nid != MAX_NUMNODES && nid != memblock_get_region_node(m))
845 continue; 853 continue;
846 854
855 /* skip hotpluggable memory regions if needed */
856 if (movable_node_is_enabled() && memblock_is_hotpluggable(m))
857 continue;
858
847 /* scan areas before each reservation for intersection */ 859 /* scan areas before each reservation for intersection */
848 for ( ; ri >= 0; ri--) { 860 for ( ; ri >= 0; ri--) {
849 struct memblock_region *r = &rsv->regions[ri]; 861 struct memblock_region *r = &rsv->regions[ri];
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 489f235502db..01e39afde1cb 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1446,6 +1446,7 @@ static int __init cmdline_parse_movable_node(char *p)
1446 * the kernel away from hotpluggable memory. 1446 * the kernel away from hotpluggable memory.
1447 */ 1447 */
1448 memblock_set_bottom_up(true); 1448 memblock_set_bottom_up(true);
1449 movable_node_enabled = true;
1449#else 1450#else
1450 pr_warn("movable_node option not supported\n"); 1451 pr_warn("movable_node option not supported\n");
1451#endif 1452#endif