public inbox for linux-ia64@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] allocate multiple contiguous pages via uncached allocator
@ 2008-04-22  0:50 Dean Nelson
  2008-04-22  7:21 ` Jes Sorensen
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Dean Nelson @ 2008-04-22  0:50 UTC (permalink / raw)
  To: linux-ia64

Enable the uncached allocator to allocate multiple pages of contiguous
uncached memory.
 
Signed-off-by: Dean Nelson <dcn@sgi.com>
 
---
 
 arch/ia64/kernel/uncached.c |   21 ++++++++++++---------
 drivers/char/mspec.c        |   12 ++++++------
 include/asm-ia64/uncached.h |    4 ++--
 3 files changed, 20 insertions(+), 17 deletions(-)

Index: linux-2.6/arch/ia64/kernel/uncached.c
=================================--- linux-2.6.orig/arch/ia64/kernel/uncached.c	2007-10-04 06:52:20.000000000 -0500
+++ linux-2.6/arch/ia64/kernel/uncached.c	2007-11-08 12:14:31.408258515 -0600
@@ -177,12 +177,13 @@
  * uncached_alloc_page
  *
  * @starting_nid: node id of node to start with, or -1
+ * @n_pages: number of contiguous pages to allocate
  *
- * Allocate 1 uncached page. Allocates on the requested node. If no
- * uncached pages are available on the requested node, roundrobin starting
- * with the next higher node.
+ * Allocate the specified number of contiguous uncached pages on the
+ * the requested node. If not enough contiguous uncached pages are available
+ * on the requested node, roundrobin starting with the next higher node.
  */
-unsigned long uncached_alloc_page(int starting_nid)
+unsigned long uncached_alloc_page(int starting_nid, int n_pages)
 {
 	unsigned long uc_addr;
 	struct uncached_pool *uc_pool;
@@ -202,7 +203,8 @@
 		if (uc_pool->pool = NULL)
 			continue;
 		do {
-			uc_addr = gen_pool_alloc(uc_pool->pool, PAGE_SIZE);
+			uc_addr = gen_pool_alloc(uc_pool->pool,
+						 n_pages * PAGE_SIZE);
 			if (uc_addr != 0)
 				return uc_addr;
 		} while (uncached_add_chunk(uc_pool, nid) = 0);
@@ -217,11 +219,12 @@
 /*
  * uncached_free_page
  *
- * @uc_addr: uncached address of page to free
+ * @uc_addr: uncached address of first page to free
+ * @n_pages: number of contiguous pages to free
  *
- * Free a single uncached page.
+ * Free the specified number of uncached pages.
  */
-void uncached_free_page(unsigned long uc_addr)
+void uncached_free_page(unsigned long uc_addr, int n_pages)
 {
 	int nid = paddr_to_nid(uc_addr - __IA64_UNCACHED_OFFSET);
 	struct gen_pool *pool = uncached_pools[nid].pool;
@@ -232,7 +235,7 @@
 	if ((uc_addr & (0XFUL << 60)) != __IA64_UNCACHED_OFFSET)
 		panic("uncached_free_page invalid address %lx\n", uc_addr);
 
-	gen_pool_free(pool, uc_addr, PAGE_SIZE);
+	gen_pool_free(pool, uc_addr, n_pages * PAGE_SIZE);
 }
 EXPORT_SYMBOL(uncached_free_page);
 
Index: linux-2.6/drivers/char/mspec.c
=================================--- linux-2.6.orig/drivers/char/mspec.c	2007-10-04 06:52:21.000000000 -0500
+++ linux-2.6/drivers/char/mspec.c	2007-11-08 12:07:17.458415225 -0600
@@ -180,7 +180,7 @@
 		my_page = vdata->maddr[index];
 		vdata->maddr[index] = 0;
 		if (!mspec_zero_block(my_page, PAGE_SIZE))
-			uncached_free_page(my_page);
+			uncached_free_page(my_page, 1);
 		else
 			printk(KERN_WARNING "mspec_close(): "
 			       "failed to zero page %ld\n", my_page);
@@ -209,7 +209,7 @@
 	index = (address - vdata->vm_start) >> PAGE_SHIFT;
 	maddr = (volatile unsigned long) vdata->maddr[index];
 	if (maddr = 0) {
-		maddr = uncached_alloc_page(numa_node_id());
+		maddr = uncached_alloc_page(numa_node_id(), 1);
 		if (maddr = 0)
 			return NOPFN_OOM;
 
@@ -218,7 +218,7 @@
 			vdata->count++;
 			vdata->maddr[index] = maddr;
 		} else {
-			uncached_free_page(maddr);
+			uncached_free_page(maddr, 1);
 			maddr = vdata->maddr[index];
 		}
 		spin_unlock(&vdata->lock);
@@ -367,7 +367,7 @@
 				int nasid;
 				unsigned long phys;
 
-				scratch_page[nid] = uncached_alloc_page(nid);
+				scratch_page[nid] = uncached_alloc_page(nid, 1);
 				if (scratch_page[nid] = 0)
 					goto free_scratch_pages;
 				phys = __pa(scratch_page[nid]);
@@ -414,7 +414,7 @@
  free_scratch_pages:
 	for_each_node(nid) {
 		if (scratch_page[nid] != 0)
-			uncached_free_page(scratch_page[nid]);
+			uncached_free_page(scratch_page[nid], 1);
 	}
 	return ret;
 }
@@ -431,7 +431,7 @@
 
 		for_each_node(nid) {
 			if (scratch_page[nid] != 0)
-				uncached_free_page(scratch_page[nid]);
+				uncached_free_page(scratch_page[nid], 1);
 		}
 	}
 }
Index: linux-2.6/include/asm-ia64/uncached.h
=================================--- linux-2.6.orig/include/asm-ia64/uncached.h	2007-10-04 06:52:25.000000000 -0500
+++ linux-2.6/include/asm-ia64/uncached.h	2007-11-08 12:05:00.633469891 -0600
@@ -8,5 +8,5 @@
  * Prototypes for the uncached page allocator
  */
 
-extern unsigned long uncached_alloc_page(int nid);
-extern void uncached_free_page(unsigned long);
+extern unsigned long uncached_alloc_page(int, int);
+extern void uncached_free_page(unsigned long, int);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] allocate multiple contiguous pages via uncached allocator
  2008-04-22  0:50 [PATCH] allocate multiple contiguous pages via uncached allocator Dean Nelson
@ 2008-04-22  7:21 ` Jes Sorensen
  2008-04-25 18:46 ` [PATCH] allocate multiple contiguous pages via uncached allocator -v2 Dean Nelson
  2008-04-25 20:22 ` [PATCH] allocate multiple contiguous pages via uncached allocator -v3 Dean Nelson
  2 siblings, 0 replies; 5+ messages in thread
From: Jes Sorensen @ 2008-04-22  7:21 UTC (permalink / raw)
  To: linux-ia64

Dean Nelson wrote:
> Enable the uncached allocator to allocate multiple pages of contiguous
> uncached memory.
>  
> Signed-off-by: Dean Nelson <dcn@sgi.com>

Acked-by: Jes Sorensen <jes@sgi.com>


> ---
>  
>  arch/ia64/kernel/uncached.c |   21 ++++++++++++---------
>  drivers/char/mspec.c        |   12 ++++++------
>  include/asm-ia64/uncached.h |    4 ++--
>  3 files changed, 20 insertions(+), 17 deletions(-)
> 
> Index: linux-2.6/arch/ia64/kernel/uncached.c
> =================================> --- linux-2.6.orig/arch/ia64/kernel/uncached.c	2007-10-04 06:52:20.000000000 -0500
> +++ linux-2.6/arch/ia64/kernel/uncached.c	2007-11-08 12:14:31.408258515 -0600
> @@ -177,12 +177,13 @@
>   * uncached_alloc_page
>   *
>   * @starting_nid: node id of node to start with, or -1
> + * @n_pages: number of contiguous pages to allocate
>   *
> - * Allocate 1 uncached page. Allocates on the requested node. If no
> - * uncached pages are available on the requested node, roundrobin starting
> - * with the next higher node.
> + * Allocate the specified number of contiguous uncached pages on the
> + * the requested node. If not enough contiguous uncached pages are available
> + * on the requested node, roundrobin starting with the next higher node.
>   */
> -unsigned long uncached_alloc_page(int starting_nid)
> +unsigned long uncached_alloc_page(int starting_nid, int n_pages)
>  {
>  	unsigned long uc_addr;
>  	struct uncached_pool *uc_pool;
> @@ -202,7 +203,8 @@
>  		if (uc_pool->pool = NULL)
>  			continue;
>  		do {
> -			uc_addr = gen_pool_alloc(uc_pool->pool, PAGE_SIZE);
> +			uc_addr = gen_pool_alloc(uc_pool->pool,
> +						 n_pages * PAGE_SIZE);
>  			if (uc_addr != 0)
>  				return uc_addr;
>  		} while (uncached_add_chunk(uc_pool, nid) = 0);
> @@ -217,11 +219,12 @@
>  /*
>   * uncached_free_page
>   *
> - * @uc_addr: uncached address of page to free
> + * @uc_addr: uncached address of first page to free
> + * @n_pages: number of contiguous pages to free
>   *
> - * Free a single uncached page.
> + * Free the specified number of uncached pages.
>   */
> -void uncached_free_page(unsigned long uc_addr)
> +void uncached_free_page(unsigned long uc_addr, int n_pages)
>  {
>  	int nid = paddr_to_nid(uc_addr - __IA64_UNCACHED_OFFSET);
>  	struct gen_pool *pool = uncached_pools[nid].pool;
> @@ -232,7 +235,7 @@
>  	if ((uc_addr & (0XFUL << 60)) != __IA64_UNCACHED_OFFSET)
>  		panic("uncached_free_page invalid address %lx\n", uc_addr);
>  
> -	gen_pool_free(pool, uc_addr, PAGE_SIZE);
> +	gen_pool_free(pool, uc_addr, n_pages * PAGE_SIZE);
>  }
>  EXPORT_SYMBOL(uncached_free_page);
>  
> Index: linux-2.6/drivers/char/mspec.c
> =================================> --- linux-2.6.orig/drivers/char/mspec.c	2007-10-04 06:52:21.000000000 -0500
> +++ linux-2.6/drivers/char/mspec.c	2007-11-08 12:07:17.458415225 -0600
> @@ -180,7 +180,7 @@
>  		my_page = vdata->maddr[index];
>  		vdata->maddr[index] = 0;
>  		if (!mspec_zero_block(my_page, PAGE_SIZE))
> -			uncached_free_page(my_page);
> +			uncached_free_page(my_page, 1);
>  		else
>  			printk(KERN_WARNING "mspec_close(): "
>  			       "failed to zero page %ld\n", my_page);
> @@ -209,7 +209,7 @@
>  	index = (address - vdata->vm_start) >> PAGE_SHIFT;
>  	maddr = (volatile unsigned long) vdata->maddr[index];
>  	if (maddr = 0) {
> -		maddr = uncached_alloc_page(numa_node_id());
> +		maddr = uncached_alloc_page(numa_node_id(), 1);
>  		if (maddr = 0)
>  			return NOPFN_OOM;
>  
> @@ -218,7 +218,7 @@
>  			vdata->count++;
>  			vdata->maddr[index] = maddr;
>  		} else {
> -			uncached_free_page(maddr);
> +			uncached_free_page(maddr, 1);
>  			maddr = vdata->maddr[index];
>  		}
>  		spin_unlock(&vdata->lock);
> @@ -367,7 +367,7 @@
>  				int nasid;
>  				unsigned long phys;
>  
> -				scratch_page[nid] = uncached_alloc_page(nid);
> +				scratch_page[nid] = uncached_alloc_page(nid, 1);
>  				if (scratch_page[nid] = 0)
>  					goto free_scratch_pages;
>  				phys = __pa(scratch_page[nid]);
> @@ -414,7 +414,7 @@
>   free_scratch_pages:
>  	for_each_node(nid) {
>  		if (scratch_page[nid] != 0)
> -			uncached_free_page(scratch_page[nid]);
> +			uncached_free_page(scratch_page[nid], 1);
>  	}
>  	return ret;
>  }
> @@ -431,7 +431,7 @@
>  
>  		for_each_node(nid) {
>  			if (scratch_page[nid] != 0)
> -				uncached_free_page(scratch_page[nid]);
> +				uncached_free_page(scratch_page[nid], 1);
>  		}
>  	}
>  }
> Index: linux-2.6/include/asm-ia64/uncached.h
> =================================> --- linux-2.6.orig/include/asm-ia64/uncached.h	2007-10-04 06:52:25.000000000 -0500
> +++ linux-2.6/include/asm-ia64/uncached.h	2007-11-08 12:05:00.633469891 -0600
> @@ -8,5 +8,5 @@
>   * Prototypes for the uncached page allocator
>   */
>  
> -extern unsigned long uncached_alloc_page(int nid);
> -extern void uncached_free_page(unsigned long);
> +extern unsigned long uncached_alloc_page(int, int);
> +extern void uncached_free_page(unsigned long, int);


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] allocate multiple contiguous pages via uncached allocator -v2
  2008-04-22  0:50 [PATCH] allocate multiple contiguous pages via uncached allocator Dean Nelson
  2008-04-22  7:21 ` Jes Sorensen
@ 2008-04-25 18:46 ` Dean Nelson
  2008-04-25 18:50   ` Matthew Wilcox
  2008-04-25 20:22 ` [PATCH] allocate multiple contiguous pages via uncached allocator -v3 Dean Nelson
  2 siblings, 1 reply; 5+ messages in thread
From: Dean Nelson @ 2008-04-25 18:46 UTC (permalink / raw)
  To: jes, tony.luck; +Cc: linux-ia64, linux-kernel

Enable the uncached allocator to allocate multiple pages of contiguous
uncached memory.
 
Signed-off-by: Dean Nelson <dcn@sgi.com>
 
---

Version 1 of this patch was missing the necessary changes to xpc_partition.c
to support this change. A future patch will take advantage of this new
capability of the uncached allocator.
 
 arch/ia64/kernel/uncached.c         |   21 ++++++++++++---------
 drivers/char/mspec.c                |   12 ++++++------
 drivers/misc/sgi-xp/xpc_partition.c |    4 ++--
 include/asm-ia64/uncached.h         |    4 ++--
 4 files changed, 22 insertions(+), 19 deletions(-)

Index: linux-2.6/arch/ia64/kernel/uncached.c
=================================--- linux-2.6.orig/arch/ia64/kernel/uncached.c	2008-04-25 13:20:33.305200359 -0500
+++ linux-2.6/arch/ia64/kernel/uncached.c	2008-04-25 13:25:06.773566374 -0500
@@ -177,12 +177,13 @@ failed:
  * uncached_alloc_page
  *
  * @starting_nid: node id of node to start with, or -1
+ * @n_pages: number of contiguous pages to allocate
  *
- * Allocate 1 uncached page. Allocates on the requested node. If no
- * uncached pages are available on the requested node, roundrobin starting
- * with the next higher node.
+ * Allocate the specified number of contiguous uncached pages on the
+ * the requested node. If not enough contiguous uncached pages are available
+ * on the requested node, roundrobin starting with the next higher node.
  */
-unsigned long uncached_alloc_page(int starting_nid)
+unsigned long uncached_alloc_page(int starting_nid, int n_pages)
 {
 	unsigned long uc_addr;
 	struct uncached_pool *uc_pool;
@@ -202,7 +203,8 @@ unsigned long uncached_alloc_page(int st
 		if (uc_pool->pool = NULL)
 			continue;
 		do {
-			uc_addr = gen_pool_alloc(uc_pool->pool, PAGE_SIZE);
+			uc_addr = gen_pool_alloc(uc_pool->pool,
+						 n_pages * PAGE_SIZE);
 			if (uc_addr != 0)
 				return uc_addr;
 		} while (uncached_add_chunk(uc_pool, nid) = 0);
@@ -217,11 +219,12 @@ EXPORT_SYMBOL(uncached_alloc_page);
 /*
  * uncached_free_page
  *
- * @uc_addr: uncached address of page to free
+ * @uc_addr: uncached address of first page to free
+ * @n_pages: number of contiguous pages to free
  *
- * Free a single uncached page.
+ * Free the specified number of uncached pages.
  */
-void uncached_free_page(unsigned long uc_addr)
+void uncached_free_page(unsigned long uc_addr, int n_pages)
 {
 	int nid = paddr_to_nid(uc_addr - __IA64_UNCACHED_OFFSET);
 	struct gen_pool *pool = uncached_pools[nid].pool;
@@ -232,7 +235,7 @@ void uncached_free_page(unsigned long uc
 	if ((uc_addr & (0XFUL << 60)) != __IA64_UNCACHED_OFFSET)
 		panic("uncached_free_page invalid address %lx\n", uc_addr);
 
-	gen_pool_free(pool, uc_addr, PAGE_SIZE);
+	gen_pool_free(pool, uc_addr, n_pages * PAGE_SIZE);
 }
 EXPORT_SYMBOL(uncached_free_page);
 
Index: linux-2.6/drivers/char/mspec.c
=================================--- linux-2.6.orig/drivers/char/mspec.c	2008-04-25 13:20:33.305200359 -0500
+++ linux-2.6/drivers/char/mspec.c	2008-04-25 13:25:06.793568744 -0500
@@ -180,7 +180,7 @@ mspec_close(struct vm_area_struct *vma)
 		my_page = vdata->maddr[index];
 		vdata->maddr[index] = 0;
 		if (!mspec_zero_block(my_page, PAGE_SIZE))
-			uncached_free_page(my_page);
+			uncached_free_page(my_page, 1);
 		else
 			printk(KERN_WARNING "mspec_close(): "
 			       "failed to zero page %ld\n", my_page);
@@ -209,7 +209,7 @@ mspec_nopfn(struct vm_area_struct *vma, 
 	index = (address - vdata->vm_start) >> PAGE_SHIFT;
 	maddr = (volatile unsigned long) vdata->maddr[index];
 	if (maddr = 0) {
-		maddr = uncached_alloc_page(numa_node_id());
+		maddr = uncached_alloc_page(numa_node_id(), 1);
 		if (maddr = 0)
 			return NOPFN_OOM;
 
@@ -218,7 +218,7 @@ mspec_nopfn(struct vm_area_struct *vma, 
 			vdata->count++;
 			vdata->maddr[index] = maddr;
 		} else {
-			uncached_free_page(maddr);
+			uncached_free_page(maddr, 1);
 			maddr = vdata->maddr[index];
 		}
 		spin_unlock(&vdata->lock);
@@ -367,7 +367,7 @@ mspec_init(void)
 				int nasid;
 				unsigned long phys;
 
-				scratch_page[nid] = uncached_alloc_page(nid);
+				scratch_page[nid] = uncached_alloc_page(nid, 1);
 				if (scratch_page[nid] = 0)
 					goto free_scratch_pages;
 				phys = __pa(scratch_page[nid]);
@@ -414,7 +414,7 @@ mspec_init(void)
  free_scratch_pages:
 	for_each_node(nid) {
 		if (scratch_page[nid] != 0)
-			uncached_free_page(scratch_page[nid]);
+			uncached_free_page(scratch_page[nid], 1);
 	}
 	return ret;
 }
@@ -431,7 +431,7 @@ mspec_exit(void)
 
 		for_each_node(nid) {
 			if (scratch_page[nid] != 0)
-				uncached_free_page(scratch_page[nid]);
+				uncached_free_page(scratch_page[nid], 1);
 		}
 	}
 }
Index: linux-2.6/include/asm-ia64/uncached.h
=================================--- linux-2.6.orig/include/asm-ia64/uncached.h	2008-04-25 13:20:33.305200359 -0500
+++ linux-2.6/include/asm-ia64/uncached.h	2008-04-25 13:25:06.821572061 -0500
@@ -8,5 +8,5 @@
  * Prototypes for the uncached page allocator
  */
 
-extern unsigned long uncached_alloc_page(int nid);
-extern void uncached_free_page(unsigned long);
+extern unsigned long uncached_alloc_page(int, int);
+extern void uncached_free_page(unsigned long, int);
Index: linux-2.6/drivers/misc/sgi-xp/xpc_partition.c
=================================--- linux-2.6.orig/drivers/misc/sgi-xp/xpc_partition.c	2008-04-25 13:12:02.000000000 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xpc_partition.c	2008-04-25 13:28:24.340999346 -0500
@@ -211,7 +211,7 @@ xpc_rsvd_page_init(void)
 	 */
 	amos_page = xpc_vars->amos_page;
 	if (amos_page = NULL) {
-		amos_page = (AMO_t *)TO_AMO(uncached_alloc_page(0));
+		amos_page = (AMO_t *)TO_AMO(uncached_alloc_page(0, 1));
 		if (amos_page = NULL) {
 			dev_err(xpc_part, "can't allocate page of AMOs\n");
 			return NULL;
@@ -230,7 +230,7 @@ xpc_rsvd_page_init(void)
 				dev_err(xpc_part, "can't change memory "
 					"protections\n");
 				uncached_free_page(__IA64_UNCACHED_OFFSET |
-						   TO_PHYS((u64)amos_page));
+						   TO_PHYS((u64)amos_page), 1);
 				return NULL;
 			}
 		}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] allocate multiple contiguous pages via uncached allocator -v2
  2008-04-25 18:46 ` [PATCH] allocate multiple contiguous pages via uncached allocator -v2 Dean Nelson
@ 2008-04-25 18:50   ` Matthew Wilcox
  0 siblings, 0 replies; 5+ messages in thread
From: Matthew Wilcox @ 2008-04-25 18:50 UTC (permalink / raw)
  To: Dean Nelson; +Cc: jes, tony.luck, linux-ia64, linux-kernel

On Fri, Apr 25, 2008 at 01:46:06PM -0500, Dean Nelson wrote:
> +++ linux-2.6/include/asm-ia64/uncached.h	2008-04-25 13:25:06.821572061 -0500
> @@ -8,5 +8,5 @@
>   * Prototypes for the uncached page allocator
>   */
>  
> -extern unsigned long uncached_alloc_page(int nid);
> -extern void uncached_free_page(unsigned long);
> +extern unsigned long uncached_alloc_page(int, int);
> +extern void uncached_free_page(unsigned long, int);

It would be good to name the arguments, particularly since you can't
identify them by type.

-- 
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] allocate multiple contiguous pages via uncached allocator -v3
  2008-04-22  0:50 [PATCH] allocate multiple contiguous pages via uncached allocator Dean Nelson
  2008-04-22  7:21 ` Jes Sorensen
  2008-04-25 18:46 ` [PATCH] allocate multiple contiguous pages via uncached allocator -v2 Dean Nelson
@ 2008-04-25 20:22 ` Dean Nelson
  2 siblings, 0 replies; 5+ messages in thread
From: Dean Nelson @ 2008-04-25 20:22 UTC (permalink / raw)
  To: jes, tony.luck; +Cc: matthew, linux-ia64, linux-kernel

Enable the uncached allocator to allocate multiple pages of contiguous
uncached memory.
 
Signed-off-by: Dean Nelson <dcn@sgi.com>
 
---

This version of this patch adds the argument names to the prototype statements
in the header file.
 
 arch/ia64/kernel/uncached.c         |   23 +++++++++++++----------
 drivers/char/mspec.c                |   12 ++++++------
 drivers/misc/sgi-xp/xpc_partition.c |    4 ++--
 include/asm-ia64/uncached.h         |    6 +++---
 4 files changed, 24 insertions(+), 21 deletions(-)

Index: linux-2.6/arch/ia64/kernel/uncached.c
=================================--- linux-2.6.orig/arch/ia64/kernel/uncached.c	2008-04-25 13:20:33.305200359 -0500
+++ linux-2.6/arch/ia64/kernel/uncached.c	2008-04-25 15:12:00.470227278 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2001-2006 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 2001-2008 Silicon Graphics, Inc.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License
@@ -177,12 +177,13 @@ failed:
  * uncached_alloc_page
  *
  * @starting_nid: node id of node to start with, or -1
+ * @n_pages: number of contiguous pages to allocate
  *
- * Allocate 1 uncached page. Allocates on the requested node. If no
- * uncached pages are available on the requested node, roundrobin starting
- * with the next higher node.
+ * Allocate the specified number of contiguous uncached pages on the
+ * the requested node. If not enough contiguous uncached pages are available
+ * on the requested node, roundrobin starting with the next higher node.
  */
-unsigned long uncached_alloc_page(int starting_nid)
+unsigned long uncached_alloc_page(int starting_nid, int n_pages)
 {
 	unsigned long uc_addr;
 	struct uncached_pool *uc_pool;
@@ -202,7 +203,8 @@ unsigned long uncached_alloc_page(int st
 		if (uc_pool->pool = NULL)
 			continue;
 		do {
-			uc_addr = gen_pool_alloc(uc_pool->pool, PAGE_SIZE);
+			uc_addr = gen_pool_alloc(uc_pool->pool,
+						 n_pages * PAGE_SIZE);
 			if (uc_addr != 0)
 				return uc_addr;
 		} while (uncached_add_chunk(uc_pool, nid) = 0);
@@ -217,11 +219,12 @@ EXPORT_SYMBOL(uncached_alloc_page);
 /*
  * uncached_free_page
  *
- * @uc_addr: uncached address of page to free
+ * @uc_addr: uncached address of first page to free
+ * @n_pages: number of contiguous pages to free
  *
- * Free a single uncached page.
+ * Free the specified number of uncached pages.
  */
-void uncached_free_page(unsigned long uc_addr)
+void uncached_free_page(unsigned long uc_addr, int n_pages)
 {
 	int nid = paddr_to_nid(uc_addr - __IA64_UNCACHED_OFFSET);
 	struct gen_pool *pool = uncached_pools[nid].pool;
@@ -232,7 +235,7 @@ void uncached_free_page(unsigned long uc
 	if ((uc_addr & (0XFUL << 60)) != __IA64_UNCACHED_OFFSET)
 		panic("uncached_free_page invalid address %lx\n", uc_addr);
 
-	gen_pool_free(pool, uc_addr, PAGE_SIZE);
+	gen_pool_free(pool, uc_addr, n_pages * PAGE_SIZE);
 }
 EXPORT_SYMBOL(uncached_free_page);
 
Index: linux-2.6/drivers/char/mspec.c
=================================--- linux-2.6.orig/drivers/char/mspec.c	2008-04-25 13:20:33.305200359 -0500
+++ linux-2.6/drivers/char/mspec.c	2008-04-25 13:25:06.793568744 -0500
@@ -180,7 +180,7 @@ mspec_close(struct vm_area_struct *vma)
 		my_page = vdata->maddr[index];
 		vdata->maddr[index] = 0;
 		if (!mspec_zero_block(my_page, PAGE_SIZE))
-			uncached_free_page(my_page);
+			uncached_free_page(my_page, 1);
 		else
 			printk(KERN_WARNING "mspec_close(): "
 			       "failed to zero page %ld\n", my_page);
@@ -209,7 +209,7 @@ mspec_nopfn(struct vm_area_struct *vma, 
 	index = (address - vdata->vm_start) >> PAGE_SHIFT;
 	maddr = (volatile unsigned long) vdata->maddr[index];
 	if (maddr = 0) {
-		maddr = uncached_alloc_page(numa_node_id());
+		maddr = uncached_alloc_page(numa_node_id(), 1);
 		if (maddr = 0)
 			return NOPFN_OOM;
 
@@ -218,7 +218,7 @@ mspec_nopfn(struct vm_area_struct *vma, 
 			vdata->count++;
 			vdata->maddr[index] = maddr;
 		} else {
-			uncached_free_page(maddr);
+			uncached_free_page(maddr, 1);
 			maddr = vdata->maddr[index];
 		}
 		spin_unlock(&vdata->lock);
@@ -367,7 +367,7 @@ mspec_init(void)
 				int nasid;
 				unsigned long phys;
 
-				scratch_page[nid] = uncached_alloc_page(nid);
+				scratch_page[nid] = uncached_alloc_page(nid, 1);
 				if (scratch_page[nid] = 0)
 					goto free_scratch_pages;
 				phys = __pa(scratch_page[nid]);
@@ -414,7 +414,7 @@ mspec_init(void)
  free_scratch_pages:
 	for_each_node(nid) {
 		if (scratch_page[nid] != 0)
-			uncached_free_page(scratch_page[nid]);
+			uncached_free_page(scratch_page[nid], 1);
 	}
 	return ret;
 }
@@ -431,7 +431,7 @@ mspec_exit(void)
 
 		for_each_node(nid) {
 			if (scratch_page[nid] != 0)
-				uncached_free_page(scratch_page[nid]);
+				uncached_free_page(scratch_page[nid], 1);
 		}
 	}
 }
Index: linux-2.6/include/asm-ia64/uncached.h
=================================--- linux-2.6.orig/include/asm-ia64/uncached.h	2008-04-25 13:20:33.305200359 -0500
+++ linux-2.6/include/asm-ia64/uncached.h	2008-04-25 15:12:13.587833507 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2001-2005 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 2001-2008 Silicon Graphics, Inc.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License
@@ -8,5 +8,5 @@
  * Prototypes for the uncached page allocator
  */
 
-extern unsigned long uncached_alloc_page(int nid);
-extern void uncached_free_page(unsigned long);
+extern unsigned long uncached_alloc_page(int starting_nid, int n_pages);
+extern void uncached_free_page(unsigned long uc_addr, int n_pages);
Index: linux-2.6/drivers/misc/sgi-xp/xpc_partition.c
=================================--- linux-2.6.orig/drivers/misc/sgi-xp/xpc_partition.c	2008-04-25 13:12:02.000000000 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xpc_partition.c	2008-04-25 13:28:24.340999346 -0500
@@ -211,7 +211,7 @@ xpc_rsvd_page_init(void)
 	 */
 	amos_page = xpc_vars->amos_page;
 	if (amos_page = NULL) {
-		amos_page = (AMO_t *)TO_AMO(uncached_alloc_page(0));
+		amos_page = (AMO_t *)TO_AMO(uncached_alloc_page(0, 1));
 		if (amos_page = NULL) {
 			dev_err(xpc_part, "can't allocate page of AMOs\n");
 			return NULL;
@@ -230,7 +230,7 @@ xpc_rsvd_page_init(void)
 				dev_err(xpc_part, "can't change memory "
 					"protections\n");
 				uncached_free_page(__IA64_UNCACHED_OFFSET |
-						   TO_PHYS((u64)amos_page));
+						   TO_PHYS((u64)amos_page), 1);
 				return NULL;
 			}
 		}

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-04-25 20:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-22  0:50 [PATCH] allocate multiple contiguous pages via uncached allocator Dean Nelson
2008-04-22  7:21 ` Jes Sorensen
2008-04-25 18:46 ` [PATCH] allocate multiple contiguous pages via uncached allocator -v2 Dean Nelson
2008-04-25 18:50   ` Matthew Wilcox
2008-04-25 20:22 ` [PATCH] allocate multiple contiguous pages via uncached allocator -v3 Dean Nelson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox