Subject: Page Loan API change proposal
To: None <tech-kern@netbsd.org>
From: Jaromír <jdolecek@netbsd.org>
List: tech-kern
Date: 09/20/2001 22:02:53
--ELM70990762-2312-0_
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=US-ASCII

Hi,
I'd like to adjust the API a bit, to allow to loan memory pages
to kernel as unwired, and to get rid of uvm_unloan*() variants.
I'd like to have the former flexibility since e.g. NEW_PIPE
is using TOPAGE loans and doesn't need the pages wired, and
using TOANON loans there would be unnecessary overhead (though
negliable, but still overhead).

I'd like to:
1. add UVM_LOAN_WIRED flag - if set, the UVM_LOAN_TOPAGE loan
   would wire the loaned pages (or unwire when unloaning)
1. add uvm_unloan(void **result, int npages, int flags), to be used
   instead uvm_unloanpage() & uvm_unloananon(), 'flags' have
   same meaning as for uvm_loan()
	 
Opinions? I'm appending patch.

Jaromir
-- 
Jaromir Dolecek <jdolecek@NetBSD.org>      http://www.ics.muni.cz/~dolecek/
NetBSD - just plain best OS! -=*=- Got spare MCA cards or docs? Hand me them!

--ELM70990762-2312-0_
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=ISO-8859-2
Content-Disposition: attachment; filename=uvmloan.diff

Index: uvm_loan.c
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_loan.c,v
retrieving revision 1.32
diff -u -p -r1.32 uvm_loan.c
--- uvm_loan.c	2001/09/15 20:36:46	1.32
+++ uvm_loan.c	2001/09/20 20:02:21
@@ -110,7 +110,10 @@ static int	uvm_loanentry __P((struct uvm
 static int	uvm_loanuobj __P((struct uvm_faultinfo *, void ***,
 				int, vaddr_t));
 static int	uvm_loanzero __P((struct uvm_faultinfo *, void ***, int));
+static void	uvm_unloananon __P((struct vm_anon **, int, int));
+static void	uvm_unloanpage __P((struct vm_page **, int, int));
 
+
 /*
  * inlines
  */
@@ -309,10 +312,10 @@ fail:
 	if (output - result) {
 		if (flags & UVM_LOAN_TOANON)
 			uvm_unloananon((struct vm_anon **)result,
-			    output - result);
+			    output - result, flags & UVM_LOAN_WIRED);
 		else
 			uvm_unloanpage((struct vm_page **)result,
-			    output - result);
+			    output - result, flags & UVM_LOAN_WIRED);
 	}
 	return (error);
 }
@@ -395,7 +398,9 @@ uvm_loananon(ufi, output, flags, anon)
 	if (pg->loan_count == 0)
 		pmap_page_protect(pg, VM_PROT_READ);
 	pg->loan_count++;
-	uvm_pagewire(pg);	/* always wire it */
+	/* If requested, wire */
+	if (flags & UVM_LOAN_WIRED)
+		uvm_pagewire(pg);
 	uvm_unlock_pageq();
 	**output = pg;
 	*output = (*output) + 1;
@@ -418,7 +423,7 @@ uvm_loananon(ufi, output, flags, anon)
  *	 1 = got it, everything still locked
  */
 
-int
+static int
 uvm_loanuobj(ufi, output, flags, va)
 	struct uvm_faultinfo *ufi;
 	void ***output;
@@ -537,7 +542,9 @@ uvm_loanuobj(ufi, output, flags, va)
 		if (pg->loan_count == 0)
 			pmap_page_protect(pg, VM_PROT_READ);
 		pg->loan_count++;
-		uvm_pagewire(pg);
+		/* If requested, wire */
+		if (flags & UVM_LOAN_WIRED)
+			uvm_pagewire(pg);
 		uvm_unlock_pageq();
 		**output = pg;
 		*output = (*output) + 1;
@@ -615,7 +622,7 @@ uvm_loanuobj(ufi, output, flags, va)
  *	 1 = got it, everything still locked
  */
 
-int
+static int
 uvm_loanzero(ufi, output, flags)
 	struct uvm_faultinfo *ufi;
 	void ***output;
@@ -647,8 +654,9 @@ uvm_loanzero(ufi, output, flags)
 		**output = pg;
 		*output = (*output) + 1;
 		uvm_lock_pageq();
-		/* wire it as we are loaning to kernel-page */
-		uvm_pagewire(pg);
+		/* If requested, wire */
+		if (flags & UVM_LOAN_WIRED)
+			uvm_pagewire(pg);
 		pg->loan_count = 1;
 		uvm_unlock_pageq();
 		return(1);
@@ -706,10 +714,10 @@ uvm_loanzero(ufi, output, flags)
  * => we expect all our resources to be unlocked
  */
 
-void
-uvm_unloananon(aloans, nanons)
+static void
+uvm_unloananon(aloans, nanons, wired)
 	struct vm_anon **aloans;
-	int nanons;
+	int nanons, wired;
 {
 	struct vm_anon *anon;
 
@@ -733,10 +741,10 @@ uvm_unloananon(aloans, nanons)
  * => we expect all our resources to be unlocked
  */
 
-void
-uvm_unloanpage(ploans, npages)
+static void
+uvm_unloanpage(ploans, npages, wired)
 	struct vm_page **ploans;
-	int npages;
+	int npages, wired;
 {
 	struct vm_page *pg;
 
@@ -749,7 +757,9 @@ uvm_unloanpage(ploans, npages)
 			panic("uvm_unloanpage: page %p isn't loaned", pg);
 
 		pg->loan_count--;		/* drop loan */
-		uvm_pageunwire(pg);		/* and unwire */
+		
+		if (wired)
+			uvm_pageunwire(pg);
 
 		/*
 		 * if page is unowned and we killed last loan, then we can
@@ -771,3 +781,16 @@ uvm_unloanpage(ploans, npages)
 	uvm_unlock_pageq();
 }
 
+/*
+ * Unloan the memory.
+ */
+void
+uvm_unloan(void **result, int npages, int flags)
+{
+	if (flags & UVM_LOAN_TOANON)
+		uvm_unloananon((struct vm_anon **)result, npages,
+		    flags & UVM_LOAN_WIRED);
+	else
+		uvm_unloanpage((struct vm_page **)result,
+		    npages, flags & UVM_LOAN_WIRED);
+}
Index: uvm_loan.h
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_loan.h,v
retrieving revision 1.7
diff -u -p -r1.7 uvm_loan.h
--- uvm_loan.h	1999/06/21 17:25:11	1.7
+++ uvm_loan.h	2001/09/20 20:02:21
@@ -45,14 +45,14 @@
 
 #define UVM_LOAN_TOANON		0x1		/* loan to anon */
 #define UVM_LOAN_TOPAGE		0x2		/* loan to page */
+#define UVM_LOAN_WIRED		0x4		/* wire the page loan */
 
 /*
  * loan prototypes
  */
 
 int uvm_loan __P((struct vm_map *, vaddr_t, vsize_t, void **, int));
-void uvm_unloananon __P((struct vm_anon **, int));
-void uvm_unloanpage __P((struct vm_page **, int));
+void uvm_unloan __P((void **, int, int));
 
 #endif /* _KERNEL */
 

--ELM70990762-2312-0_--