linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Yasunori Goto <y-goto@jp.fujitsu.com>
To: Badari Pulavarty <pbadari@us.ibm.com>,
	Andrew Morton <akpm@linux-foundation.org>
Cc: Linux Kernel ML <linux-kernel@vger.kernel.org>,
	linux-mm <linux-mm@kvack.org>, Yinghai Lu <yhlu.kernel@gmail.com>
Subject: [Patch 005/005](memory hotplug) free memmaps allocated by bootmem
Date: Mon, 07 Apr 2008 21:50:18 +0900	[thread overview]
Message-ID: <20080407214844.887A.E1E9C6FF@jp.fujitsu.com> (raw)
In-Reply-To: <20080407213519.886E.E1E9C6FF@jp.fujitsu.com>


This patch is to free memmaps which is allocated by bootmem.

Freeing usemap is not necessary. The pages of usemap may be necessary
for other sections.

If removing section is last section on the node,
its section is the final user of usemap page.
(usemaps are allocated on its section by previous patch.)
But it shouldn't be freed too, because the section must be
logical offline state which all pages are isolated against page allocater.
If it is freed, page alloctor may use it which will be removed
physically soon. It will be disaster.
So, this patch keeps it as it is.


Signed-off-by: Yasunori Goto <y-goto@jp.fujitsu.com>

---
 mm/internal.h       |    3 +--
 mm/memory_hotplug.c |   11 +++++++++++
 mm/page_alloc.c     |    2 +-
 mm/sparse.c         |   51 +++++++++++++++++++++++++++++++++++++++++++++++----
 4 files changed, 60 insertions(+), 7 deletions(-)

Index: current/mm/sparse.c
===================================================================
--- current.orig/mm/sparse.c	2008-04-07 20:13:25.000000000 +0900
+++ current/mm/sparse.c	2008-04-07 20:27:20.000000000 +0900
@@ -8,6 +8,7 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
+#include "internal.h"
 #include <asm/dma.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
@@ -360,6 +361,9 @@
 {
 	return; /* XXX: Not implemented yet */
 }
+static void free_map_bootmem(struct page *page, unsigned long nr_pages)
+{
+}
 #else
 static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
 {
@@ -397,17 +401,47 @@
 		free_pages((unsigned long)memmap,
 			   get_order(sizeof(struct page) * nr_pages));
 }
+
+static void free_map_bootmem(struct page *page, unsigned long nr_pages)
+{
+	unsigned long maps_section_nr, removing_section_nr, i;
+	int magic;
+
+	for (i = 0; i < nr_pages; i++, page++) {
+		magic = atomic_read(&page->_mapcount);
+
+		BUG_ON(magic == NODE_INFO);
+
+		maps_section_nr = pfn_to_section_nr(page_to_pfn(page));
+		removing_section_nr = page->private;
+
+		/*
+		 * When this function is called, the removing section is
+		 * logical offlined state. This means all pages are isolated
+		 * from page allocator. If removing section's memmap is placed
+		 * on the same section, it must not be freed.
+		 * If it is freed, page allocator may allocate it which will
+		 * be removed physically soon.
+		 */
+		if (maps_section_nr != removing_section_nr)
+			put_page_bootmem(page);
+	}
+}
 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
 
 static void free_section_usemap(struct page *memmap, unsigned long *usemap)
 {
+	struct page *usemap_page;
+	unsigned long nr_pages;
+
 	if (!usemap)
 		return;
 
+	usemap_page = virt_to_page(usemap);
 	/*
 	 * Check to see if allocation came from hot-plug-add
 	 */
-	if (PageSlab(virt_to_page(usemap))) {
+	if (PageSlab(usemap_page)) {
 		kfree(usemap);
 		if (memmap)
 			__kfree_section_memmap(memmap, PAGES_PER_SECTION);
@@ -415,10 +449,19 @@
 	}
 
 	/*
-	 * TODO: Allocations came from bootmem - how do I free up ?
+	 * The usemap came from bootmem. This is packed with other usemaps
+	 * on the section which has pgdat at boot time. Just keep it as is now.
 	 */
-	printk(KERN_WARNING "Not freeing up allocations from bootmem "
-			"- leaking memory\n");
+
+	if (memmap) {
+		struct page *memmap_page;
+		memmap_page = virt_to_page(memmap);
+
+		nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page))
+			>> PAGE_SHIFT;
+
+		free_map_bootmem(memmap_page, nr_pages);
+	}
 }
 
 /*
Index: current/mm/page_alloc.c
===================================================================
--- current.orig/mm/page_alloc.c	2008-04-07 20:12:55.000000000 +0900
+++ current/mm/page_alloc.c	2008-04-07 20:13:29.000000000 +0900
@@ -568,7 +568,7 @@
 /*
  * permit the bootmem allocator to evade page validation on high-order frees
  */
-void __init __free_pages_bootmem(struct page *page, unsigned int order)
+void __free_pages_bootmem(struct page *page, unsigned int order)
 {
 	if (order == 0) {
 		__ClearPageReserved(page);
Index: current/mm/internal.h
===================================================================
--- current.orig/mm/internal.h	2008-04-07 20:12:55.000000000 +0900
+++ current/mm/internal.h	2008-04-07 20:13:29.000000000 +0900
@@ -34,8 +34,7 @@
 	atomic_dec(&page->_count);
 }
 
-extern void __init __free_pages_bootmem(struct page *page,
-						unsigned int order);
+extern void __free_pages_bootmem(struct page *page, unsigned int order);
 
 /*
  * function for dealing with page's order in buddy system.
Index: current/mm/memory_hotplug.c
===================================================================
--- current.orig/mm/memory_hotplug.c	2008-04-07 20:12:55.000000000 +0900
+++ current/mm/memory_hotplug.c	2008-04-07 20:13:29.000000000 +0900
@@ -199,6 +199,16 @@
 	return register_new_memory(__pfn_to_section(phys_start_pfn));
 }
 
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+static int __remove_section(struct zone *zone, struct mem_section *ms)
+{
+	/*
+	 * XXX: Freeing memmap with vmemmap is not implement yet.
+	 *      This should be removed later.
+	 */
+	return -EBUSY;
+}
+#else
 static int __remove_section(struct zone *zone, struct mem_section *ms)
 {
 	unsigned long flags;
@@ -217,6 +227,7 @@
 	pgdat_resize_unlock(pgdat, &flags);
 	return 0;
 }
+#endif
 
 /*
  * Reasonably generic function for adding memory.  It is

-- 
Yasunori Goto 

  parent reply	other threads:[~2008-04-07 12:50 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-07 12:43 [Patch 000/005](memory hotplug) freeing pages allocated by bootmem for hotremove v3 Yasunori Goto
2008-04-07 12:45 ` [Patch 001/005](memory hotplug) register section/node id to free Yasunori Goto
2008-06-16 10:21   ` Andy Whitcroft
2008-06-16 13:58     ` Yasunori Goto
2008-06-17 11:39       ` [Patch](memory hotplug) Tiny fixes of bootmem free patch for memory hotremove Yasunori Goto
2008-04-07 12:46 ` [Patch 002/005](memory hotplug) align memmap to page size Yasunori Goto
2008-06-16 10:26   ` Andy Whitcroft
2008-06-16 13:26     ` Yasunori Goto
2008-04-07 12:47 ` [Patch 003/005](memory hotplug) make alloc_bootmem_section() Yasunori Goto
2008-06-16 10:32   ` Andy Whitcroft
2008-06-16 13:18     ` Yasunori Goto
2008-04-07 12:48 ` [Patch 004/005](memory hotplug)allocate usemap on the section with pgdat Yasunori Goto
2008-04-07 12:50 ` Yasunori Goto [this message]
2008-06-16 10:44   ` [Patch 005/005](memory hotplug) free memmaps allocated by bootmem Andy Whitcroft
2008-06-16 14:09     ` Yasunori Goto
  -- strict thread matches above, loose matches on Subject: below --
2008-04-03  5:37 [Patch 000/005](memory hotplug) freeing pages allocated by bootmem for hotremove v2 Yasunori Goto
2008-04-03  5:45 ` [Patch 005/005](memory hotplug) free memmaps allocated by bootmem Yasunori Goto

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080407214844.887A.E1E9C6FF@jp.fujitsu.com \
    --to=y-goto@jp.fujitsu.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=pbadari@us.ibm.com \
    --cc=yhlu.kernel@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox