linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Christoph Lameter <clameter@sgi.com>
To: akpm@linux-foundation.org
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: [02/18] vunmap: return page array passed on vmap()
Date: Wed, 03 Oct 2007 20:59:37 -0700	[thread overview]
Message-ID: <20071004040002.172507452@sgi.com> (raw)
In-Reply-To: 20071004035935.042951211@sgi.com

[-- Attachment #1: vcompound_vunmap_returns_pages --]
[-- Type: text/plain, Size: 4461 bytes --]

Make vunmap return the page array that was used at vmap. This is useful
if one has no structures to track the page array but simply stores the
virtual address somewhere. The disposition of the page array can be
decided upon after vunmap. vfree() may now also be used instead of
vunmap which will release the page array after vunmap'ping it.

As noted by Kamezawa: The same subsystem that provides the page array
to vmap must must use its own method to dispose of the page array.

If vfree() is called to free the page array then the page array must either
be

1. Allocated via the slab allocator

2. Allocated via vmalloc but then VM_VPAGES must have been passed at
   vunmap to specify that a vfree is needed.

Signed-off-by: Christoph Lameter <clameter@sgi.com>

---
 include/linux/vmalloc.h |    2 +-
 mm/vmalloc.c            |   32 ++++++++++++++++++++++----------
 2 files changed, 23 insertions(+), 11 deletions(-)

Index: linux-2.6/include/linux/vmalloc.h
===================================================================
--- linux-2.6.orig/include/linux/vmalloc.h	2007-10-03 16:19:29.000000000 -0700
+++ linux-2.6/include/linux/vmalloc.h	2007-10-03 16:19:41.000000000 -0700
@@ -49,7 +49,7 @@ extern void vfree(void *addr);
 
 extern void *vmap(struct page **pages, unsigned int count,
 			unsigned long flags, pgprot_t prot);
-extern void vunmap(void *addr);
+extern struct page **vunmap(void *addr);
 
 extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
 							unsigned long pgoff);
Index: linux-2.6/mm/vmalloc.c
===================================================================
--- linux-2.6.orig/mm/vmalloc.c	2007-10-03 16:19:35.000000000 -0700
+++ linux-2.6/mm/vmalloc.c	2007-10-03 16:20:15.000000000 -0700
@@ -152,6 +152,7 @@ int map_vm_area(struct vm_struct *area, 
 	unsigned long addr = (unsigned long) area->addr;
 	unsigned long end = addr + area->size - PAGE_SIZE;
 	int err;
+	area->pages = *pages;
 
 	BUG_ON(addr >= end);
 	pgd = pgd_offset_k(addr);
@@ -162,6 +163,8 @@ int map_vm_area(struct vm_struct *area, 
 			break;
 	} while (pgd++, addr = next, addr != end);
 	flush_cache_vmap((unsigned long) area->addr, end);
+
+	area->nr_pages = *pages - area->pages;
 	return err;
 }
 EXPORT_SYMBOL_GPL(map_vm_area);
@@ -318,17 +321,18 @@ struct vm_struct *remove_vm_area(void *a
 	return v;
 }
 
-static void __vunmap(void *addr, int deallocate_pages)
+static struct page **__vunmap(void *addr, int deallocate_pages)
 {
 	struct vm_struct *area;
+	struct page **pages;
 
 	if (!addr)
-		return;
+		return NULL;
 
 	if ((PAGE_SIZE-1) & (unsigned long)addr) {
 		printk(KERN_ERR "Trying to vfree() bad address (%p)\n", addr);
 		WARN_ON(1);
-		return;
+		return NULL;
 	}
 
 	area = remove_vm_area(addr);
@@ -336,29 +340,30 @@ static void __vunmap(void *addr, int dea
 		printk(KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n",
 				addr);
 		WARN_ON(1);
-		return;
+		return NULL;
 	}
 
+	pages = area->pages;
 	debug_check_no_locks_freed(addr, area->size);
 
 	if (deallocate_pages) {
 		int i;
 
 		for (i = 0; i < area->nr_pages; i++) {
-			struct page *page = area->pages[i];
+			struct page *page = pages[i];
 
 			BUG_ON(!page);
 			__free_page(page);
 		}
 
 		if (area->flags & VM_VPAGES)
-			vfree(area->pages);
+			vfree(pages);
 		else
-			kfree(area->pages);
+			kfree(pages);
 	}
 
 	kfree(area);
-	return;
+	return pages;
 }
 
 /**
@@ -387,10 +392,10 @@ EXPORT_SYMBOL(vfree);
  *
  *	Must not be called in interrupt context.
  */
-void vunmap(void *addr)
+struct page **vunmap(void *addr)
 {
 	BUG_ON(in_interrupt());
-	__vunmap(addr, 0);
+	return __vunmap(addr, 0);
 }
 EXPORT_SYMBOL(vunmap);
 
@@ -403,6 +408,13 @@ EXPORT_SYMBOL(vunmap);
  *
  *	Maps @count pages from @pages into contiguous kernel virtual
  *	space.
+ *
+ *	The page array may be freed via vfree() on the virtual address
+ *	returned. In that case the page array must be allocated via
+ *	the slab allocator. If the page array was allocated via
+ *	vmalloc then VM_VPAGES must be specified in the flags. There is
+ *	no support for vfree() to free a page array allocated via the
+ *	page allocator.
  */
 void *vmap(struct page **pages, unsigned int count,
 		unsigned long flags, pgprot_t prot)

-- 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  parent reply	other threads:[~2007-10-04  3:59 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-04  3:59 [00/18] Virtual Compound Page Support V2 Christoph Lameter
2007-10-04  3:59 ` [01/18] vmalloc: clean up page array indexing Christoph Lameter
2007-10-04  3:59 ` Christoph Lameter [this message]
2007-10-04  3:59 ` [03/18] vmalloc_address(): Determine vmalloc address from page struct Christoph Lameter
2007-10-04  3:59 ` [04/18] Vcompound: Smart up virt_to_head_page() Christoph Lameter
2007-10-04  3:59 ` [05/18] Page flags: Add PageVcompound() Christoph Lameter
2007-10-04  3:59 ` [06/18] Vcompound: Update page address determination Christoph Lameter
2007-10-04  3:59 ` [07/18] Vcompound: Add compound_nth_page() to determine nth base page Christoph Lameter
2007-10-04  3:59 ` [08/18] GFP_VFALLBACK: Allow fallback of compound pages to virtual mappings Christoph Lameter
2007-10-04  3:59 ` [09/18] Vcompound: GFP_VFALLBACK debugging aid Christoph Lameter
2007-10-04  3:59 ` [10/18] Sparsemem: Use fallback for the memmap Christoph Lameter
2007-10-04  3:59 ` [11/18] Page allocator: Use a higher order allocation for the zone wait table Christoph Lameter
2007-10-04  3:59 ` [12/18] Wait: Allow bit_waitqueue to wait on a bit in a virtual compound page Christoph Lameter
2007-10-04  3:59 ` [13/18] x86_64: Allow fallback for the stack Christoph Lameter
2007-10-04 11:56   ` Andi Kleen
2007-10-04 12:08     ` Peter Zijlstra
2007-10-04 12:25       ` Andi Kleen
2007-10-04 12:30         ` Peter Zijlstra
2007-10-04 17:40         ` Christoph Lameter
2007-10-04 19:20     ` Christoph Lameter
2007-10-04 19:39       ` Rik van Riel
2007-10-04 21:20         ` Christoph Lameter
2007-10-07  7:35           ` Nick Piggin
2007-10-08 17:36             ` Christoph Lameter
2007-10-08 12:55               ` Nick Piggin
2007-10-09 18:39                 ` Christoph Lameter
2007-10-09  8:46                   ` Nick Piggin
2007-10-10  1:26                     ` Christoph Lameter
2007-10-09  9:56                       ` Nick Piggin
2007-10-10  3:36                         ` where to get ZONE_MOVABLE pathces? Jacky(GuangXiang  Lee)
2007-10-10 10:32                           ` Mel Gorman
2007-10-06 18:53         ` [13/18] x86_64: Allow fallback for the stack Bill Davidsen
2007-10-04  3:59 ` [14/18] Configure stack size Christoph Lameter
2007-10-04  4:36   ` Arjan van de Ven
2007-10-04  4:43     ` David Miller, Arjan van de Ven
2007-10-04 19:34       ` Christoph Lameter
2007-10-04  9:11   ` Andi Kleen
2007-10-04 19:26     ` Christoph Lameter
2007-10-04  3:59 ` [15/18] Fallback for temporary order 2 allocation Christoph Lameter
2007-10-04  3:59 ` [16/18] Virtual Compound page allocation from interrupt context Christoph Lameter
2007-10-04  3:59 ` [17/18] Virtual compound page freeing in " Christoph Lameter
2007-10-04  3:59 ` [18/18] SLUB: Use fallback for table of callers/freers of a slab cache Christoph Lameter

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=20071004040002.172507452@sgi.com \
    --to=clameter@sgi.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    /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;
as well as URLs for NNTP newsgroup(s).