All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <50C135EA.2030308@gmail.com>

diff --git a/a/2.txt b/N1/2.txt
index 8b13789..b212b3c 100644
--- a/a/2.txt
+++ b/N1/2.txt
@@ -1 +1,172 @@
+>From 0ba5a0996d307d89f19ef79cf5fed1f8c4a7ed27 Mon Sep 17 00:00:00 2001
+From: Jiang Liu <jiang.liu@huawei.com>
+Date: Sun, 2 Dec 2012 20:54:32 +0800
+Subject: [PATCH 1/3] memblock: introduce interfaces to assoicate tag and data
+ with reserved regions
 
+Currently some subsystems use private static arrays to store information
+assoicated with memory blocks allocated/reserved from memblock subsystem.
+For example, dma-contiguous.c uses cma_reserved[] to store information
+assoicated with allocated memory blocks.
+
+So introduce interfaces to associate tag(type) and caller specific data
+with allocated/reserved memblock regions. Users of memblock subsystem
+may be simplified by using these new interfaces.
+
+Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
+---
+ include/linux/memblock.h |   33 ++++++++++++++++++++++++++
+ mm/Kconfig               |    3 +++
+ mm/memblock.c            |   58 +++++++++++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 93 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/memblock.h b/include/linux/memblock.h
+index d452ee1..40dea53 100644
+--- a/include/linux/memblock.h
++++ b/include/linux/memblock.h
+@@ -22,6 +22,10 @@
+ struct memblock_region {
+ 	phys_addr_t base;
+ 	phys_addr_t size;
++#ifdef CONFIG_HAVE_MEMBLOCK_TAG
++	void *data;
++	int tag;
++#endif
+ #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
+ 	int nid;
+ #endif
+@@ -118,6 +122,35 @@ void __next_free_mem_range_rev(u64 *idx, int nid, phys_addr_t *out_start,
+ 	     i != (u64)ULLONG_MAX;					\
+ 	     __next_free_mem_range_rev(&i, nid, p_start, p_end, p_nid))
+ 
++#ifdef CONFIG_HAVE_MEMBLOCK_TAG
++#define	MEMBLOCK_TAG_DEFAULT	0x0 /* default tag for bootmem allocatror */
++
++int memblock_mark_tag(phys_addr_t base, phys_addr_t size, int tag, void *data);
++void memblock_free_all_with_tag(int tag);
++
++/* Only merge regions with default tag */
++static inline bool memblock_tag_mergeable(struct memblock_region *prev,
++					  struct memblock_region *next)
++{
++	return prev->tag == MEMBLOCK_TAG_DEFAULT &&
++	       next->tag == MEMBLOCK_TAG_DEFAULT;
++}
++
++static inline void memblock_init_tag(struct memblock_region *reg)
++{
++	reg->tag = MEMBLOCK_TAG_DEFAULT;
++	reg->data = NULL;
++}
++#else /* CONFIG_HAVE_MEMBLOCK_TAG */
++static inline bool memblock_tag_mergeable(struct memblock_region *prev,
++					  struct memblock_region *next)
++{
++	return true;
++}
++
++static inline void memblock_init_tag(struct memblock_region *reg) {}
++#endif /* CONFIG_HAVE_MEMBLOCK_TAG */
++
+ #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
+ int memblock_set_node(phys_addr_t base, phys_addr_t size, int nid);
+ 
+diff --git a/mm/Kconfig b/mm/Kconfig
+index a3f8ddd..5080390 100644
+--- a/mm/Kconfig
++++ b/mm/Kconfig
+@@ -131,6 +131,9 @@ config SPARSEMEM_VMEMMAP
+ config HAVE_MEMBLOCK
+ 	boolean
+ 
++config HAVE_MEMBLOCK_TAG
++	boolean
++
+ config HAVE_MEMBLOCK_NODE_MAP
+ 	boolean
+ 
+diff --git a/mm/memblock.c b/mm/memblock.c
+index 6259055..c2c644e 100644
+--- a/mm/memblock.c
++++ b/mm/memblock.c
+@@ -307,7 +307,8 @@ static void __init_memblock memblock_merge_regions(struct memblock_type *type)
+ 
+ 		if (this->base + this->size != next->base ||
+ 		    memblock_get_region_node(this) !=
+-		    memblock_get_region_node(next)) {
++		    memblock_get_region_node(next) ||
++		    !memblock_tag_mergeable(this, next)) {
+ 			BUG_ON(this->base + this->size > next->base);
+ 			i++;
+ 			continue;
+@@ -339,6 +340,7 @@ static void __init_memblock memblock_insert_region(struct memblock_type *type,
+ 	memmove(rgn + 1, rgn, (type->cnt - idx) * sizeof(*rgn));
+ 	rgn->base = base;
+ 	rgn->size = size;
++	memblock_init_tag(rgn);
+ 	memblock_set_region_node(rgn, nid);
+ 	type->cnt++;
+ 	type->total_size += size;
+@@ -764,6 +766,60 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size,
+ }
+ #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */
+ 
++#ifdef CONFIG_HAVE_MEMBLOCK_TAG
++/**
++ * memblock_mark_tag - mark @tag and @data with reserved regions
++ * @base: base of area to mark @tag and @data with
++ * @size: size of area to mark @tag and @data with
++ * @tag: tag (type) to assoicated with reserved regions
++ * @data: caller specific data to associated with reserved regions
++ *
++ * Associate @tag(type) and caller specific @data with reserved memblock
++ * regions in [@base,@base+@size).
++ * Regions which cross the area boundaries are split as necessary.
++ *
++ * RETURNS:
++ * 0 on success, -errno on failure.
++ */
++int __init_memblock memblock_mark_tag(phys_addr_t base, phys_addr_t size,
++				      int tag, void *data)
++{
++	struct memblock_type *type = &memblock.reserved;
++	int start_rgn, end_rgn;
++	int i, ret;
++
++	ret = memblock_isolate_range(type, base, size, &start_rgn, &end_rgn);
++	if (ret)
++		return ret;
++
++	for (i = start_rgn; i < end_rgn; i++) {
++		type->regions[i].tag = tag;
++		type->regions[i].data = data;
++	}
++
++	memblock_merge_regions(type);
++
++	return 0;
++}
++
++/**
++ * memblock_free_all_with_tag - free all reserved regions with @tag
++ * @tag: tag to identify reserved memblock regions to be freed
++ *
++ * Free all reserved memblock regions with tag (type) of @tag
++ */
++void __init_memblock memblock_free_all_with_tag(int tag)
++{
++	int i;
++	struct memblock_type *type = &memblock.reserved;
++
++	/* scan backward because it may remove current region */
++	for (i = type->cnt - 1; i >= 0; i--)
++		if (type->regions[i].tag == tag)
++			memblock_remove_region(type, i);
++}
++#endif /* CONFIG_HAVE_MEMBLOCK_TAG */
++
+ static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size,
+ 					phys_addr_t align, phys_addr_t max_addr,
+ 					int nid)
+-- 
+1.7.9.5
diff --git a/N1/3.hdr b/N1/3.hdr
new file mode 100644
index 0000000..7623aaf
--- /dev/null
+++ b/N1/3.hdr
@@ -0,0 +1,6 @@
+Content-Type: text/x-patch;
+ name="0002-x86-memhotplug-reserve-memory-from-bootmem-allocator.patch"
+Content-Transfer-Encoding: 7bit
+Content-Disposition: attachment;
+ filename*0="0002-x86-memhotplug-reserve-memory-from-bootmem-allocator.pa";
+ filename*1="tch"
diff --git a/N1/3.txt b/N1/3.txt
new file mode 100644
index 0000000..61aa094
--- /dev/null
+++ b/N1/3.txt
@@ -0,0 +1,188 @@
+>From ba05910c7915e3f95a0cd0893b9abc6cd98ab22e Mon Sep 17 00:00:00 2001
+From: Jiang Liu <jiang.liu@huawei.com>
+Date: Sun, 2 Dec 2012 21:26:21 +0800
+Subject: [PATCH 2/3] x86, memhotplug: reserve memory from bootmem allocator
+ for memory hotplug
+
+There's no mechanism to migrate pages allocated from bootmem allocator,
+thus a memory device may become irremovable if bootmem  allocates any
+pages from it.
+
+This patch introduces a mechanism to
+1) reserve memory from bootmem allocator for hotplug early 'enough'
+   during boot.
+2) free reserve memory into buddy system at late when memory hogplug
+   infrastructure has been initialized.
+
+Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
+---
+ arch/x86/kernel/setup.c        |   11 ++++++++
+ arch/x86/mm/init.c             |   56 ++++++++++++++++++++++++++++++++++++++++
+ arch/x86/mm/init_32.c          |    2 ++
+ arch/x86/mm/init_64.c          |    2 ++
+ include/linux/memblock.h       |    1 +
+ include/linux/memory_hotplug.h |    5 ++++
+ mm/Kconfig                     |    1 +
+ 7 files changed, 78 insertions(+)
+
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index ca45696..93f6f10 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -940,6 +940,17 @@ void __init setup_arch(char **cmdline_p)
+ 		max_low_pfn = max_pfn;
+ 	}
+ #endif
++
++	/*
++	 * Try to reserve memory from bootmem allocator for memory hotplug
++	 * before updating memblock.current_limit to cover all low memory.
++	 * Until now memblock.current_limit is still set to the initial value
++	 * of max_pfn_mapped, which is 512M on x86_64 and xxx on i386. And
++	 * memblock allocates available memory in reverse order, so we almost
++	 * have no chance to reserve memory below 512M for memory hotplug.
++	 */
++	reserve_memory_for_hotplug();
++
+ 	memblock.current_limit = get_max_mapped();
+ 	dma_contiguous_reserve(0);
+ 
+diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
+index d7aea41..36bb5c2 100644
+--- a/arch/x86/mm/init.c
++++ b/arch/x86/mm/init.c
+@@ -424,3 +424,59 @@ void __init zone_sizes_init(void)
+ 	free_area_init_nodes(max_zone_pfns);
+ }
+ 
++#ifdef CONFIG_MEMORY_HOTREMOVE
++static int __init reserve_bootmem_for_hotplug(phys_addr_t base,
++					      phys_addr_t size)
++{
++	if (memblock_is_region_reserved(base, size) ||
++	    memblock_reserve(base, size) < 0)
++		return -EBUSY;
++
++	BUG_ON(memblock_mark_tag(base, size, MEMBLOCK_TAG_HOTPLUG, NULL));
++
++	return 0;
++}
++
++/*
++ * Try to reserve low memory for hotplug according to user configured
++ * movablecore_map. Movable zone hasn't been determined yet, so can't rely
++ * on zone_movable_is_highmem() but to reserve all low memory configured by
++ * movablecore_map parameter.
++ * Assume entries in movablecore_map.map are sorted in increasing order.
++ */
++static int __init reserve_hotplug_memory_from_movable_map(void)
++{
++	int i;
++	phys_addr_t start, end;
++	struct movablecore_entry *ep;
++
++	if (movablecore_map.nr_map == 0)
++		return 0;
++
++	for (i = 0; i < movablecore_map.nr_map; i++) {
++		ep = &movablecore_map.map[i];
++		start = ep->start << PAGE_SHIFT;
++		end = (min(ep->end, max_low_pfn) + 1) << PAGE_SHIFT;
++		if (end <= start)
++			break;
++
++		if (reserve_bootmem_for_hotplug(start, end - start))
++			pr_warn("mm: failed to reserve lowmem [%#016llx-%#016llx] for hotplug.",
++				(unsigned long long)start,
++				(unsigned long long)end - 1);
++	}
++
++	return 1;
++}
++
++void __init reserve_memory_for_hotplug(void)
++{
++	if (reserve_hotplug_memory_from_movable_map())
++		return;
++}
++
++void __init free_memory_reserved_for_hotplug(void)
++{
++	memblock_free_all_with_tag(MEMBLOCK_TAG_HOTPLUG);
++}
++#endif
+diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
+index 11a5800..815700a 100644
+--- a/arch/x86/mm/init_32.c
++++ b/arch/x86/mm/init_32.c
+@@ -745,6 +745,8 @@ void __init mem_init(void)
+ 	 */
+ 	set_highmem_pages_init();
+ 
++	free_memory_reserved_for_hotplug();
++
+ 	/* this will put all low memory onto the freelists */
+ 	totalram_pages += free_all_bootmem();
+ 
+diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
+index 3baff25..1a92fd6 100644
+--- a/arch/x86/mm/init_64.c
++++ b/arch/x86/mm/init_64.c
+@@ -695,6 +695,8 @@ void __init mem_init(void)
+ 
+ 	reservedpages = 0;
+ 
++	free_memory_reserved_for_hotplug();
++
+ 	/* this will put all low memory onto the freelists */
+ #ifdef CONFIG_NUMA
+ 	totalram_pages = numa_free_all_bootmem();
+diff --git a/include/linux/memblock.h b/include/linux/memblock.h
+index 40dea53..5420ed9 100644
+--- a/include/linux/memblock.h
++++ b/include/linux/memblock.h
+@@ -124,6 +124,7 @@ void __next_free_mem_range_rev(u64 *idx, int nid, phys_addr_t *out_start,
+ 
+ #ifdef CONFIG_HAVE_MEMBLOCK_TAG
+ #define	MEMBLOCK_TAG_DEFAULT	0x0 /* default tag for bootmem allocatror */
++#define	MEMBLOCK_TAG_HOTPLUG	0x1 /* reserved for memory hotplug */
+ 
+ int memblock_mark_tag(phys_addr_t base, phys_addr_t size, int tag, void *data);
+ void memblock_free_all_with_tag(int tag);
+diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
+index 95573ec..edf183d 100644
+--- a/include/linux/memory_hotplug.h
++++ b/include/linux/memory_hotplug.h
+@@ -222,6 +222,8 @@ static inline void unlock_memory_hotplug(void) {}
+ #ifdef CONFIG_MEMORY_HOTREMOVE
+ 
+ extern int is_mem_section_removable(unsigned long pfn, unsigned long nr_pages);
++extern void reserve_memory_for_hotplug(void);
++extern void free_memory_reserved_for_hotplug(void);
+ 
+ #else
+ static inline int is_mem_section_removable(unsigned long pfn,
+@@ -229,6 +231,9 @@ static inline int is_mem_section_removable(unsigned long pfn,
+ {
+ 	return 0;
+ }
++
++static inline void reserve_memory_for_hotplug(void) {}
++static inline void free_memory_reserved_for_hotplug(void) {}
+ #endif /* CONFIG_MEMORY_HOTREMOVE */
+ 
+ extern int mem_online_node(int nid);
+diff --git a/mm/Kconfig b/mm/Kconfig
+index 5080390..9d69e5d 100644
+--- a/mm/Kconfig
++++ b/mm/Kconfig
+@@ -160,6 +160,7 @@ config MEMORY_HOTPLUG_SPARSE
+ 
+ config MEMORY_HOTREMOVE
+ 	bool "Allow for memory hot remove"
++	select HAVE_MEMBLOCK_TAG
+ 	depends on MEMORY_HOTPLUG && ARCH_ENABLE_MEMORY_HOTREMOVE
+ 	depends on MIGRATION
+ 
+-- 
+1.7.9.5
diff --git a/N1/4.hdr b/N1/4.hdr
new file mode 100644
index 0000000..453cade
--- /dev/null
+++ b/N1/4.hdr
@@ -0,0 +1,6 @@
+Content-Type: text/x-patch;
+ name="0003-CMA-use-new-memblock-interfaces-to-simplify-implemen.patch"
+Content-Transfer-Encoding: 7bit
+Content-Disposition: attachment;
+ filename*0="0003-CMA-use-new-memblock-interfaces-to-simplify-implemen.pa";
+ filename*1="tch"
diff --git a/N1/4.txt b/N1/4.txt
new file mode 100644
index 0000000..d4cb98a
--- /dev/null
+++ b/N1/4.txt
@@ -0,0 +1,116 @@
+>From d1ddc6e2196758923c71d649d52b9a14d678419b Mon Sep 17 00:00:00 2001
+From: Jiang Liu <jiang.liu@huawei.com>
+Date: Sun, 2 Dec 2012 21:00:52 +0800
+Subject: [PATCH 3/3] CMA: use new memblock interfaces to simplify
+ implementation
+
+This patch simplifies dma-continuous.c by using new memblock interfaces.
+
+Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
+---
+ drivers/base/Kconfig          |    1 +
+ drivers/base/dma-contiguous.c |   36 +++++++++++++-----------------------
+ include/linux/memblock.h      |    1 +
+ 3 files changed, 15 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
+index b34b5cd..b0ac008 100644
+--- a/drivers/base/Kconfig
++++ b/drivers/base/Kconfig
+@@ -197,6 +197,7 @@ config CMA
+ 	depends on HAVE_DMA_CONTIGUOUS && HAVE_MEMBLOCK && EXPERIMENTAL
+ 	select MIGRATION
+ 	select MEMORY_ISOLATION
++	select HAVE_MEMBLOCK_TAG
+ 	help
+ 	  This enables the Contiguous Memory Allocator which allows drivers
+ 	  to allocate big physically-contiguous blocks of memory for use with
+diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
+index 612afcc..c092b76 100644
+--- a/drivers/base/dma-contiguous.c
++++ b/drivers/base/dma-contiguous.c
+@@ -190,27 +190,24 @@ no_mem:
+ 	return ERR_PTR(ret);
+ }
+ 
+-static struct cma_reserved {
+-	phys_addr_t start;
+-	unsigned long size;
+-	struct device *dev;
+-} cma_reserved[MAX_CMA_AREAS] __initdata;
+ static unsigned cma_reserved_count __initdata;
+ 
+ static int __init cma_init_reserved_areas(void)
+ {
+-	struct cma_reserved *r = cma_reserved;
+-	unsigned i = cma_reserved_count;
++	struct memblock_region *reg;
++	struct cma *cma;
+ 
+ 	pr_debug("%s()\n", __func__);
+ 
+-	for (; i; --i, ++r) {
+-		struct cma *cma;
+-		cma = cma_create_area(PFN_DOWN(r->start),
+-				      r->size >> PAGE_SHIFT);
+-		if (!IS_ERR(cma))
+-			dev_set_cma_area(r->dev, cma);
+-	}
++	for_each_memblock(memory, reg)
++		if (reg->tag == MEMBLOCK_TAG_CMA) {
++			cma = cma_create_area(PFN_DOWN(reg->base),
++					      reg->size >> PAGE_SHIFT);
++			if (!IS_ERR(cma))
++				dev_set_cma_area(reg->data, cma);
++		}
++	memblock_free_all_with_tag(MEMBLOCK_TAG_CMA);
++
+ 	return 0;
+ }
+ core_initcall(cma_init_reserved_areas);
+@@ -230,7 +227,6 @@ core_initcall(cma_init_reserved_areas);
+ int __init dma_declare_contiguous(struct device *dev, unsigned long size,
+ 				  phys_addr_t base, phys_addr_t limit)
+ {
+-	struct cma_reserved *r = &cma_reserved[cma_reserved_count];
+ 	unsigned long alignment;
+ 
+ 	pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__,
+@@ -238,7 +234,7 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size,
+ 		 (unsigned long)limit);
+ 
+ 	/* Sanity checks */
+-	if (cma_reserved_count == ARRAY_SIZE(cma_reserved)) {
++	if (cma_reserved_count == MAX_CMA_AREAS) {
+ 		pr_err("Not enough slots for CMA reserved regions!\n");
+ 		return -ENOSPC;
+ 	}
+@@ -277,13 +273,7 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size,
+ 		}
+ 	}
+ 
+-	/*
+-	 * Each reserved area must be initialised later, when more kernel
+-	 * subsystems (like slab allocator) are available.
+-	 */
+-	r->start = base;
+-	r->size = size;
+-	r->dev = dev;
++	BUG_ON(memblock_mark_tag(base, size, MEMBLOCK_TAG_CMA, dev));
+ 	cma_reserved_count++;
+ 	pr_info("CMA: reserved %ld MiB at %08lx\n", size / SZ_1M,
+ 		(unsigned long)base);
+diff --git a/include/linux/memblock.h b/include/linux/memblock.h
+index 5420ed9..a662c07 100644
+--- a/include/linux/memblock.h
++++ b/include/linux/memblock.h
+@@ -125,6 +125,7 @@ void __next_free_mem_range_rev(u64 *idx, int nid, phys_addr_t *out_start,
+ #ifdef CONFIG_HAVE_MEMBLOCK_TAG
+ #define	MEMBLOCK_TAG_DEFAULT	0x0 /* default tag for bootmem allocatror */
+ #define	MEMBLOCK_TAG_HOTPLUG	0x1 /* reserved for memory hotplug */
++#define	MEMBLOCK_TAG_CMA	0x2 /* reserved for CMA */
+ 
+ int memblock_mark_tag(phys_addr_t base, phys_addr_t size, int tag, void *data);
+ void memblock_free_all_with_tag(int tag);
+-- 
+1.7.9.5
diff --git a/a/content_digest b/N1/content_digest
index 186a4ec..2bbe4a3 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -47,5 +47,487 @@
  "\01:2\0"
  "fn\00001-memblock-introduce-interfaces-to-assoicate-tag-and-d.patch\0"
  "b\0"
+ ">From 0ba5a0996d307d89f19ef79cf5fed1f8c4a7ed27 Mon Sep 17 00:00:00 2001\n"
+ "From: Jiang Liu <jiang.liu@huawei.com>\n"
+ "Date: Sun, 2 Dec 2012 20:54:32 +0800\n"
+ "Subject: [PATCH 1/3] memblock: introduce interfaces to assoicate tag and data\n"
+ " with reserved regions\n"
+ "\n"
+ "Currently some subsystems use private static arrays to store information\n"
+ "assoicated with memory blocks allocated/reserved from memblock subsystem.\n"
+ "For example, dma-contiguous.c uses cma_reserved[] to store information\n"
+ "assoicated with allocated memory blocks.\n"
+ "\n"
+ "So introduce interfaces to associate tag(type) and caller specific data\n"
+ "with allocated/reserved memblock regions. Users of memblock subsystem\n"
+ "may be simplified by using these new interfaces.\n"
+ "\n"
+ "Signed-off-by: Jiang Liu <jiang.liu@huawei.com>\n"
+ "---\n"
+ " include/linux/memblock.h |   33 ++++++++++++++++++++++++++\n"
+ " mm/Kconfig               |    3 +++\n"
+ " mm/memblock.c            |   58 +++++++++++++++++++++++++++++++++++++++++++++-\n"
+ " 3 files changed, 93 insertions(+), 1 deletion(-)\n"
+ "\n"
+ "diff --git a/include/linux/memblock.h b/include/linux/memblock.h\n"
+ "index d452ee1..40dea53 100644\n"
+ "--- a/include/linux/memblock.h\n"
+ "+++ b/include/linux/memblock.h\n"
+ "@@ -22,6 +22,10 @@\n"
+ " struct memblock_region {\n"
+ " \tphys_addr_t base;\n"
+ " \tphys_addr_t size;\n"
+ "+#ifdef CONFIG_HAVE_MEMBLOCK_TAG\n"
+ "+\tvoid *data;\n"
+ "+\tint tag;\n"
+ "+#endif\n"
+ " #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP\n"
+ " \tint nid;\n"
+ " #endif\n"
+ "@@ -118,6 +122,35 @@ void __next_free_mem_range_rev(u64 *idx, int nid, phys_addr_t *out_start,\n"
+ " \t     i != (u64)ULLONG_MAX;\t\t\t\t\t\\\n"
+ " \t     __next_free_mem_range_rev(&i, nid, p_start, p_end, p_nid))\n"
+ " \n"
+ "+#ifdef CONFIG_HAVE_MEMBLOCK_TAG\n"
+ "+#define\tMEMBLOCK_TAG_DEFAULT\t0x0 /* default tag for bootmem allocatror */\n"
+ "+\n"
+ "+int memblock_mark_tag(phys_addr_t base, phys_addr_t size, int tag, void *data);\n"
+ "+void memblock_free_all_with_tag(int tag);\n"
+ "+\n"
+ "+/* Only merge regions with default tag */\n"
+ "+static inline bool memblock_tag_mergeable(struct memblock_region *prev,\n"
+ "+\t\t\t\t\t  struct memblock_region *next)\n"
+ "+{\n"
+ "+\treturn prev->tag == MEMBLOCK_TAG_DEFAULT &&\n"
+ "+\t       next->tag == MEMBLOCK_TAG_DEFAULT;\n"
+ "+}\n"
+ "+\n"
+ "+static inline void memblock_init_tag(struct memblock_region *reg)\n"
+ "+{\n"
+ "+\treg->tag = MEMBLOCK_TAG_DEFAULT;\n"
+ "+\treg->data = NULL;\n"
+ "+}\n"
+ "+#else /* CONFIG_HAVE_MEMBLOCK_TAG */\n"
+ "+static inline bool memblock_tag_mergeable(struct memblock_region *prev,\n"
+ "+\t\t\t\t\t  struct memblock_region *next)\n"
+ "+{\n"
+ "+\treturn true;\n"
+ "+}\n"
+ "+\n"
+ "+static inline void memblock_init_tag(struct memblock_region *reg) {}\n"
+ "+#endif /* CONFIG_HAVE_MEMBLOCK_TAG */\n"
+ "+\n"
+ " #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP\n"
+ " int memblock_set_node(phys_addr_t base, phys_addr_t size, int nid);\n"
+ " \n"
+ "diff --git a/mm/Kconfig b/mm/Kconfig\n"
+ "index a3f8ddd..5080390 100644\n"
+ "--- a/mm/Kconfig\n"
+ "+++ b/mm/Kconfig\n"
+ "@@ -131,6 +131,9 @@ config SPARSEMEM_VMEMMAP\n"
+ " config HAVE_MEMBLOCK\n"
+ " \tboolean\n"
+ " \n"
+ "+config HAVE_MEMBLOCK_TAG\n"
+ "+\tboolean\n"
+ "+\n"
+ " config HAVE_MEMBLOCK_NODE_MAP\n"
+ " \tboolean\n"
+ " \n"
+ "diff --git a/mm/memblock.c b/mm/memblock.c\n"
+ "index 6259055..c2c644e 100644\n"
+ "--- a/mm/memblock.c\n"
+ "+++ b/mm/memblock.c\n"
+ "@@ -307,7 +307,8 @@ static void __init_memblock memblock_merge_regions(struct memblock_type *type)\n"
+ " \n"
+ " \t\tif (this->base + this->size != next->base ||\n"
+ " \t\t    memblock_get_region_node(this) !=\n"
+ "-\t\t    memblock_get_region_node(next)) {\n"
+ "+\t\t    memblock_get_region_node(next) ||\n"
+ "+\t\t    !memblock_tag_mergeable(this, next)) {\n"
+ " \t\t\tBUG_ON(this->base + this->size > next->base);\n"
+ " \t\t\ti++;\n"
+ " \t\t\tcontinue;\n"
+ "@@ -339,6 +340,7 @@ static void __init_memblock memblock_insert_region(struct memblock_type *type,\n"
+ " \tmemmove(rgn + 1, rgn, (type->cnt - idx) * sizeof(*rgn));\n"
+ " \trgn->base = base;\n"
+ " \trgn->size = size;\n"
+ "+\tmemblock_init_tag(rgn);\n"
+ " \tmemblock_set_region_node(rgn, nid);\n"
+ " \ttype->cnt++;\n"
+ " \ttype->total_size += size;\n"
+ "@@ -764,6 +766,60 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size,\n"
+ " }\n"
+ " #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */\n"
+ " \n"
+ "+#ifdef CONFIG_HAVE_MEMBLOCK_TAG\n"
+ "+/**\n"
+ "+ * memblock_mark_tag - mark @tag and @data with reserved regions\n"
+ "+ * @base: base of area to mark @tag and @data with\n"
+ "+ * @size: size of area to mark @tag and @data with\n"
+ "+ * @tag: tag (type) to assoicated with reserved regions\n"
+ "+ * @data: caller specific data to associated with reserved regions\n"
+ "+ *\n"
+ "+ * Associate @tag(type) and caller specific @data with reserved memblock\n"
+ "+ * regions in [@base,@base+@size).\n"
+ "+ * Regions which cross the area boundaries are split as necessary.\n"
+ "+ *\n"
+ "+ * RETURNS:\n"
+ "+ * 0 on success, -errno on failure.\n"
+ "+ */\n"
+ "+int __init_memblock memblock_mark_tag(phys_addr_t base, phys_addr_t size,\n"
+ "+\t\t\t\t      int tag, void *data)\n"
+ "+{\n"
+ "+\tstruct memblock_type *type = &memblock.reserved;\n"
+ "+\tint start_rgn, end_rgn;\n"
+ "+\tint i, ret;\n"
+ "+\n"
+ "+\tret = memblock_isolate_range(type, base, size, &start_rgn, &end_rgn);\n"
+ "+\tif (ret)\n"
+ "+\t\treturn ret;\n"
+ "+\n"
+ "+\tfor (i = start_rgn; i < end_rgn; i++) {\n"
+ "+\t\ttype->regions[i].tag = tag;\n"
+ "+\t\ttype->regions[i].data = data;\n"
+ "+\t}\n"
+ "+\n"
+ "+\tmemblock_merge_regions(type);\n"
+ "+\n"
+ "+\treturn 0;\n"
+ "+}\n"
+ "+\n"
+ "+/**\n"
+ "+ * memblock_free_all_with_tag - free all reserved regions with @tag\n"
+ "+ * @tag: tag to identify reserved memblock regions to be freed\n"
+ "+ *\n"
+ "+ * Free all reserved memblock regions with tag (type) of @tag\n"
+ "+ */\n"
+ "+void __init_memblock memblock_free_all_with_tag(int tag)\n"
+ "+{\n"
+ "+\tint i;\n"
+ "+\tstruct memblock_type *type = &memblock.reserved;\n"
+ "+\n"
+ "+\t/* scan backward because it may remove current region */\n"
+ "+\tfor (i = type->cnt - 1; i >= 0; i--)\n"
+ "+\t\tif (type->regions[i].tag == tag)\n"
+ "+\t\t\tmemblock_remove_region(type, i);\n"
+ "+}\n"
+ "+#endif /* CONFIG_HAVE_MEMBLOCK_TAG */\n"
+ "+\n"
+ " static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size,\n"
+ " \t\t\t\t\tphys_addr_t align, phys_addr_t max_addr,\n"
+ " \t\t\t\t\tint nid)\n"
+ "-- \n"
+ 1.7.9.5
+ "\01:3\0"
+ "fn\00002-x86-memhotplug-reserve-memory-from-bootmem-allocator.patch\0"
+ "b\0"
+ ">From ba05910c7915e3f95a0cd0893b9abc6cd98ab22e Mon Sep 17 00:00:00 2001\n"
+ "From: Jiang Liu <jiang.liu@huawei.com>\n"
+ "Date: Sun, 2 Dec 2012 21:26:21 +0800\n"
+ "Subject: [PATCH 2/3] x86, memhotplug: reserve memory from bootmem allocator\n"
+ " for memory hotplug\n"
+ "\n"
+ "There's no mechanism to migrate pages allocated from bootmem allocator,\n"
+ "thus a memory device may become irremovable if bootmem  allocates any\n"
+ "pages from it.\n"
+ "\n"
+ "This patch introduces a mechanism to\n"
+ "1) reserve memory from bootmem allocator for hotplug early 'enough'\n"
+ "   during boot.\n"
+ "2) free reserve memory into buddy system at late when memory hogplug\n"
+ "   infrastructure has been initialized.\n"
+ "\n"
+ "Signed-off-by: Jiang Liu <jiang.liu@huawei.com>\n"
+ "---\n"
+ " arch/x86/kernel/setup.c        |   11 ++++++++\n"
+ " arch/x86/mm/init.c             |   56 ++++++++++++++++++++++++++++++++++++++++\n"
+ " arch/x86/mm/init_32.c          |    2 ++\n"
+ " arch/x86/mm/init_64.c          |    2 ++\n"
+ " include/linux/memblock.h       |    1 +\n"
+ " include/linux/memory_hotplug.h |    5 ++++\n"
+ " mm/Kconfig                     |    1 +\n"
+ " 7 files changed, 78 insertions(+)\n"
+ "\n"
+ "diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c\n"
+ "index ca45696..93f6f10 100644\n"
+ "--- a/arch/x86/kernel/setup.c\n"
+ "+++ b/arch/x86/kernel/setup.c\n"
+ "@@ -940,6 +940,17 @@ void __init setup_arch(char **cmdline_p)\n"
+ " \t\tmax_low_pfn = max_pfn;\n"
+ " \t}\n"
+ " #endif\n"
+ "+\n"
+ "+\t/*\n"
+ "+\t * Try to reserve memory from bootmem allocator for memory hotplug\n"
+ "+\t * before updating memblock.current_limit to cover all low memory.\n"
+ "+\t * Until now memblock.current_limit is still set to the initial value\n"
+ "+\t * of max_pfn_mapped, which is 512M on x86_64 and xxx on i386. And\n"
+ "+\t * memblock allocates available memory in reverse order, so we almost\n"
+ "+\t * have no chance to reserve memory below 512M for memory hotplug.\n"
+ "+\t */\n"
+ "+\treserve_memory_for_hotplug();\n"
+ "+\n"
+ " \tmemblock.current_limit = get_max_mapped();\n"
+ " \tdma_contiguous_reserve(0);\n"
+ " \n"
+ "diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c\n"
+ "index d7aea41..36bb5c2 100644\n"
+ "--- a/arch/x86/mm/init.c\n"
+ "+++ b/arch/x86/mm/init.c\n"
+ "@@ -424,3 +424,59 @@ void __init zone_sizes_init(void)\n"
+ " \tfree_area_init_nodes(max_zone_pfns);\n"
+ " }\n"
+ " \n"
+ "+#ifdef CONFIG_MEMORY_HOTREMOVE\n"
+ "+static int __init reserve_bootmem_for_hotplug(phys_addr_t base,\n"
+ "+\t\t\t\t\t      phys_addr_t size)\n"
+ "+{\n"
+ "+\tif (memblock_is_region_reserved(base, size) ||\n"
+ "+\t    memblock_reserve(base, size) < 0)\n"
+ "+\t\treturn -EBUSY;\n"
+ "+\n"
+ "+\tBUG_ON(memblock_mark_tag(base, size, MEMBLOCK_TAG_HOTPLUG, NULL));\n"
+ "+\n"
+ "+\treturn 0;\n"
+ "+}\n"
+ "+\n"
+ "+/*\n"
+ "+ * Try to reserve low memory for hotplug according to user configured\n"
+ "+ * movablecore_map. Movable zone hasn't been determined yet, so can't rely\n"
+ "+ * on zone_movable_is_highmem() but to reserve all low memory configured by\n"
+ "+ * movablecore_map parameter.\n"
+ "+ * Assume entries in movablecore_map.map are sorted in increasing order.\n"
+ "+ */\n"
+ "+static int __init reserve_hotplug_memory_from_movable_map(void)\n"
+ "+{\n"
+ "+\tint i;\n"
+ "+\tphys_addr_t start, end;\n"
+ "+\tstruct movablecore_entry *ep;\n"
+ "+\n"
+ "+\tif (movablecore_map.nr_map == 0)\n"
+ "+\t\treturn 0;\n"
+ "+\n"
+ "+\tfor (i = 0; i < movablecore_map.nr_map; i++) {\n"
+ "+\t\tep = &movablecore_map.map[i];\n"
+ "+\t\tstart = ep->start << PAGE_SHIFT;\n"
+ "+\t\tend = (min(ep->end, max_low_pfn) + 1) << PAGE_SHIFT;\n"
+ "+\t\tif (end <= start)\n"
+ "+\t\t\tbreak;\n"
+ "+\n"
+ "+\t\tif (reserve_bootmem_for_hotplug(start, end - start))\n"
+ "+\t\t\tpr_warn(\"mm: failed to reserve lowmem [%#016llx-%#016llx] for hotplug.\",\n"
+ "+\t\t\t\t(unsigned long long)start,\n"
+ "+\t\t\t\t(unsigned long long)end - 1);\n"
+ "+\t}\n"
+ "+\n"
+ "+\treturn 1;\n"
+ "+}\n"
+ "+\n"
+ "+void __init reserve_memory_for_hotplug(void)\n"
+ "+{\n"
+ "+\tif (reserve_hotplug_memory_from_movable_map())\n"
+ "+\t\treturn;\n"
+ "+}\n"
+ "+\n"
+ "+void __init free_memory_reserved_for_hotplug(void)\n"
+ "+{\n"
+ "+\tmemblock_free_all_with_tag(MEMBLOCK_TAG_HOTPLUG);\n"
+ "+}\n"
+ "+#endif\n"
+ "diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c\n"
+ "index 11a5800..815700a 100644\n"
+ "--- a/arch/x86/mm/init_32.c\n"
+ "+++ b/arch/x86/mm/init_32.c\n"
+ "@@ -745,6 +745,8 @@ void __init mem_init(void)\n"
+ " \t */\n"
+ " \tset_highmem_pages_init();\n"
+ " \n"
+ "+\tfree_memory_reserved_for_hotplug();\n"
+ "+\n"
+ " \t/* this will put all low memory onto the freelists */\n"
+ " \ttotalram_pages += free_all_bootmem();\n"
+ " \n"
+ "diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c\n"
+ "index 3baff25..1a92fd6 100644\n"
+ "--- a/arch/x86/mm/init_64.c\n"
+ "+++ b/arch/x86/mm/init_64.c\n"
+ "@@ -695,6 +695,8 @@ void __init mem_init(void)\n"
+ " \n"
+ " \treservedpages = 0;\n"
+ " \n"
+ "+\tfree_memory_reserved_for_hotplug();\n"
+ "+\n"
+ " \t/* this will put all low memory onto the freelists */\n"
+ " #ifdef CONFIG_NUMA\n"
+ " \ttotalram_pages = numa_free_all_bootmem();\n"
+ "diff --git a/include/linux/memblock.h b/include/linux/memblock.h\n"
+ "index 40dea53..5420ed9 100644\n"
+ "--- a/include/linux/memblock.h\n"
+ "+++ b/include/linux/memblock.h\n"
+ "@@ -124,6 +124,7 @@ void __next_free_mem_range_rev(u64 *idx, int nid, phys_addr_t *out_start,\n"
+ " \n"
+ " #ifdef CONFIG_HAVE_MEMBLOCK_TAG\n"
+ " #define\tMEMBLOCK_TAG_DEFAULT\t0x0 /* default tag for bootmem allocatror */\n"
+ "+#define\tMEMBLOCK_TAG_HOTPLUG\t0x1 /* reserved for memory hotplug */\n"
+ " \n"
+ " int memblock_mark_tag(phys_addr_t base, phys_addr_t size, int tag, void *data);\n"
+ " void memblock_free_all_with_tag(int tag);\n"
+ "diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h\n"
+ "index 95573ec..edf183d 100644\n"
+ "--- a/include/linux/memory_hotplug.h\n"
+ "+++ b/include/linux/memory_hotplug.h\n"
+ "@@ -222,6 +222,8 @@ static inline void unlock_memory_hotplug(void) {}\n"
+ " #ifdef CONFIG_MEMORY_HOTREMOVE\n"
+ " \n"
+ " extern int is_mem_section_removable(unsigned long pfn, unsigned long nr_pages);\n"
+ "+extern void reserve_memory_for_hotplug(void);\n"
+ "+extern void free_memory_reserved_for_hotplug(void);\n"
+ " \n"
+ " #else\n"
+ " static inline int is_mem_section_removable(unsigned long pfn,\n"
+ "@@ -229,6 +231,9 @@ static inline int is_mem_section_removable(unsigned long pfn,\n"
+ " {\n"
+ " \treturn 0;\n"
+ " }\n"
+ "+\n"
+ "+static inline void reserve_memory_for_hotplug(void) {}\n"
+ "+static inline void free_memory_reserved_for_hotplug(void) {}\n"
+ " #endif /* CONFIG_MEMORY_HOTREMOVE */\n"
+ " \n"
+ " extern int mem_online_node(int nid);\n"
+ "diff --git a/mm/Kconfig b/mm/Kconfig\n"
+ "index 5080390..9d69e5d 100644\n"
+ "--- a/mm/Kconfig\n"
+ "+++ b/mm/Kconfig\n"
+ "@@ -160,6 +160,7 @@ config MEMORY_HOTPLUG_SPARSE\n"
+ " \n"
+ " config MEMORY_HOTREMOVE\n"
+ " \tbool \"Allow for memory hot remove\"\n"
+ "+\tselect HAVE_MEMBLOCK_TAG\n"
+ " \tdepends on MEMORY_HOTPLUG && ARCH_ENABLE_MEMORY_HOTREMOVE\n"
+ " \tdepends on MIGRATION\n"
+ " \n"
+ "-- \n"
+ 1.7.9.5
+ "\01:4\0"
+ "fn\00003-CMA-use-new-memblock-interfaces-to-simplify-implemen.patch\0"
+ "b\0"
+ ">From d1ddc6e2196758923c71d649d52b9a14d678419b Mon Sep 17 00:00:00 2001\n"
+ "From: Jiang Liu <jiang.liu@huawei.com>\n"
+ "Date: Sun, 2 Dec 2012 21:00:52 +0800\n"
+ "Subject: [PATCH 3/3] CMA: use new memblock interfaces to simplify\n"
+ " implementation\n"
+ "\n"
+ "This patch simplifies dma-continuous.c by using new memblock interfaces.\n"
+ "\n"
+ "Signed-off-by: Jiang Liu <jiang.liu@huawei.com>\n"
+ "---\n"
+ " drivers/base/Kconfig          |    1 +\n"
+ " drivers/base/dma-contiguous.c |   36 +++++++++++++-----------------------\n"
+ " include/linux/memblock.h      |    1 +\n"
+ " 3 files changed, 15 insertions(+), 23 deletions(-)\n"
+ "\n"
+ "diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig\n"
+ "index b34b5cd..b0ac008 100644\n"
+ "--- a/drivers/base/Kconfig\n"
+ "+++ b/drivers/base/Kconfig\n"
+ "@@ -197,6 +197,7 @@ config CMA\n"
+ " \tdepends on HAVE_DMA_CONTIGUOUS && HAVE_MEMBLOCK && EXPERIMENTAL\n"
+ " \tselect MIGRATION\n"
+ " \tselect MEMORY_ISOLATION\n"
+ "+\tselect HAVE_MEMBLOCK_TAG\n"
+ " \thelp\n"
+ " \t  This enables the Contiguous Memory Allocator which allows drivers\n"
+ " \t  to allocate big physically-contiguous blocks of memory for use with\n"
+ "diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c\n"
+ "index 612afcc..c092b76 100644\n"
+ "--- a/drivers/base/dma-contiguous.c\n"
+ "+++ b/drivers/base/dma-contiguous.c\n"
+ "@@ -190,27 +190,24 @@ no_mem:\n"
+ " \treturn ERR_PTR(ret);\n"
+ " }\n"
+ " \n"
+ "-static struct cma_reserved {\n"
+ "-\tphys_addr_t start;\n"
+ "-\tunsigned long size;\n"
+ "-\tstruct device *dev;\n"
+ "-} cma_reserved[MAX_CMA_AREAS] __initdata;\n"
+ " static unsigned cma_reserved_count __initdata;\n"
+ " \n"
+ " static int __init cma_init_reserved_areas(void)\n"
+ " {\n"
+ "-\tstruct cma_reserved *r = cma_reserved;\n"
+ "-\tunsigned i = cma_reserved_count;\n"
+ "+\tstruct memblock_region *reg;\n"
+ "+\tstruct cma *cma;\n"
+ " \n"
+ " \tpr_debug(\"%s()\\n\", __func__);\n"
+ " \n"
+ "-\tfor (; i; --i, ++r) {\n"
+ "-\t\tstruct cma *cma;\n"
+ "-\t\tcma = cma_create_area(PFN_DOWN(r->start),\n"
+ "-\t\t\t\t      r->size >> PAGE_SHIFT);\n"
+ "-\t\tif (!IS_ERR(cma))\n"
+ "-\t\t\tdev_set_cma_area(r->dev, cma);\n"
+ "-\t}\n"
+ "+\tfor_each_memblock(memory, reg)\n"
+ "+\t\tif (reg->tag == MEMBLOCK_TAG_CMA) {\n"
+ "+\t\t\tcma = cma_create_area(PFN_DOWN(reg->base),\n"
+ "+\t\t\t\t\t      reg->size >> PAGE_SHIFT);\n"
+ "+\t\t\tif (!IS_ERR(cma))\n"
+ "+\t\t\t\tdev_set_cma_area(reg->data, cma);\n"
+ "+\t\t}\n"
+ "+\tmemblock_free_all_with_tag(MEMBLOCK_TAG_CMA);\n"
+ "+\n"
+ " \treturn 0;\n"
+ " }\n"
+ " core_initcall(cma_init_reserved_areas);\n"
+ "@@ -230,7 +227,6 @@ core_initcall(cma_init_reserved_areas);\n"
+ " int __init dma_declare_contiguous(struct device *dev, unsigned long size,\n"
+ " \t\t\t\t  phys_addr_t base, phys_addr_t limit)\n"
+ " {\n"
+ "-\tstruct cma_reserved *r = &cma_reserved[cma_reserved_count];\n"
+ " \tunsigned long alignment;\n"
+ " \n"
+ " \tpr_debug(\"%s(size %lx, base %08lx, limit %08lx)\\n\", __func__,\n"
+ "@@ -238,7 +234,7 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size,\n"
+ " \t\t (unsigned long)limit);\n"
+ " \n"
+ " \t/* Sanity checks */\n"
+ "-\tif (cma_reserved_count == ARRAY_SIZE(cma_reserved)) {\n"
+ "+\tif (cma_reserved_count == MAX_CMA_AREAS) {\n"
+ " \t\tpr_err(\"Not enough slots for CMA reserved regions!\\n\");\n"
+ " \t\treturn -ENOSPC;\n"
+ " \t}\n"
+ "@@ -277,13 +273,7 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size,\n"
+ " \t\t}\n"
+ " \t}\n"
+ " \n"
+ "-\t/*\n"
+ "-\t * Each reserved area must be initialised later, when more kernel\n"
+ "-\t * subsystems (like slab allocator) are available.\n"
+ "-\t */\n"
+ "-\tr->start = base;\n"
+ "-\tr->size = size;\n"
+ "-\tr->dev = dev;\n"
+ "+\tBUG_ON(memblock_mark_tag(base, size, MEMBLOCK_TAG_CMA, dev));\n"
+ " \tcma_reserved_count++;\n"
+ " \tpr_info(\"CMA: reserved %ld MiB at %08lx\\n\", size / SZ_1M,\n"
+ " \t\t(unsigned long)base);\n"
+ "diff --git a/include/linux/memblock.h b/include/linux/memblock.h\n"
+ "index 5420ed9..a662c07 100644\n"
+ "--- a/include/linux/memblock.h\n"
+ "+++ b/include/linux/memblock.h\n"
+ "@@ -125,6 +125,7 @@ void __next_free_mem_range_rev(u64 *idx, int nid, phys_addr_t *out_start,\n"
+ " #ifdef CONFIG_HAVE_MEMBLOCK_TAG\n"
+ " #define\tMEMBLOCK_TAG_DEFAULT\t0x0 /* default tag for bootmem allocatror */\n"
+ " #define\tMEMBLOCK_TAG_HOTPLUG\t0x1 /* reserved for memory hotplug */\n"
+ "+#define\tMEMBLOCK_TAG_CMA\t0x2 /* reserved for CMA */\n"
+ " \n"
+ " int memblock_mark_tag(phys_addr_t base, phys_addr_t size, int tag, void *data);\n"
+ " void memblock_free_all_with_tag(int tag);\n"
+ "-- \n"
+ 1.7.9.5
 
-97963415fdbe490fcf9ed20892fd85133e2548043ff48af929475c300832df65
+099d809225fa7c39802a2a24d30e21e9687980ac0aa8efbd41350af47d9fb3b8

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.