Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Jan 2003 12:51:44 -0800 (PST)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        hackers@freebsd.org
Cc:        "Alan L. Cox" <alc@imimic.com>, Tor.Egge@cvsup.no.freebsd.org
Subject:   vmapbuf/vunmapbuf consolidation  -- need alpha/ia64 review.
Message-ID:  <200301112051.h0BKpiWr047795@apollo.backplane.com>
References:  <20021102171534X.tegge@cvsup.no.freebsd.org> <3DCD7F3A.DE013857@imimic.com> <200301092137.h09Lbo0E005483@apollo.backplane.com> <3E1DF369.81ADB566@imimic.com> <200301100058.h0A0wiqo000380@apollo.backplane.com> <3E1FF17B.455C2A71@imimic.com>

next in thread | previous in thread | raw e-mail | index | archive | help
    This patch consolidates all the vmapbuf()/vunmapbuf() implementations
    into kern/vfs_bio.c, removing them from */*/vm_machdep.c.

    All the implmentations appeared to be the same.  The alpha and Ia64
    implementations appeared to be older versions of the i386 implementation.

    I would like people associated with the alpha and ia64 work to review
    the change.  Basically the alpha and ia64 were using individual
    pmap_kenter() calls while all the other implementations use a
    single pmap_qenter() call (and appeared to be exactly identical to
    the i386 vmapbuf() and vunmapbuf()).

    This consolidation is a necessary precursor to a complete reorganization
    of how pages will be reserved for physical I/O.  Right now we use 
    useracc() and vm_map_check_protection() but at least in regards to 
    physical I/O these are wholely inadequate as they do not reserve the
    underlying pages or even determine if the address space is truely valid,
    only that the vm_map_entry is valid (e.g. mapping a 1MB file into a 4MB
    space with mmap() and issuing physical I/O above 1MB will panic both
    -current and -stable).

					Thanks,

					-Matt
					Matthew Dillon 
					<dillon@backplane.com>


:>         * Combine all the platform-specific vmapbuf() and friends into
:>           a single version in sys/vm, in -current.
:
:They actually look and smell a lot like other code in kern/vfs_bio.c. 
:In fact, their prototypes are in sys/buf.h alongside other functions
:from kern/vfs_bio.c.
:
:Alan


Index: alpha/alpha/vm_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/vm_machdep.c,v
retrieving revision 1.77
diff -u -r1.77 vm_machdep.c
--- alpha/alpha/vm_machdep.c	10 Dec 2002 02:33:43 -0000	1.77
+++ alpha/alpha/vm_machdep.c	11 Jan 2003 20:39:48 -0000
@@ -337,6 +337,8 @@
 {
 }
 
+#if 0
+
 /*
  * Map an IO request into kernel virtual address space.
  *
@@ -405,6 +407,8 @@
 
 	bp->b_data = bp->b_saveaddr;
 }
+
+#endif
 
 /*
  * Reset back to firmware.
Index: i386/i386/vm_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/vm_machdep.c,v
retrieving revision 1.196
diff -u -r1.196 vm_machdep.c
--- i386/i386/vm_machdep.c	10 Dec 2002 02:33:43 -0000	1.196
+++ i386/i386/vm_machdep.c	11 Jan 2003 20:40:23 -0000
@@ -435,6 +435,8 @@
 	return((int)va);
 }
 
+#if 0
+
 /*
  * Map an IO request into kernel virtual address space.
  *
@@ -508,6 +510,7 @@
 
 	bp->b_data = bp->b_saveaddr;
 }
+#endif
 
 /*
  * Force reset the processor by invalidating the entire address space!
Index: ia64/ia64/vm_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/ia64/ia64/vm_machdep.c,v
retrieving revision 1.51
diff -u -r1.51 vm_machdep.c
--- ia64/ia64/vm_machdep.c	10 Dec 2002 02:33:43 -0000	1.51
+++ ia64/ia64/vm_machdep.c	11 Jan 2003 20:41:06 -0000
@@ -350,6 +350,8 @@
 {
 }
 
+#if 0
+
 /*
  * Map an IO request into kernel virtual address space.
  *
@@ -418,6 +420,8 @@
 
 	bp->b_data = bp->b_saveaddr;
 }
+
+#endif
 
 /*
  * Force reset the processor by invalidating the entire address space!
Index: powerpc/powerpc/vm_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/powerpc/powerpc/vm_machdep.c,v
retrieving revision 1.80
diff -u -r1.80 vm_machdep.c
--- powerpc/powerpc/vm_machdep.c	8 Jan 2003 12:29:59 -0000	1.80
+++ powerpc/powerpc/vm_machdep.c	11 Jan 2003 20:41:20 -0000
@@ -230,6 +230,9 @@
 	panic("cpu_throw() didn't");
 }
 
+
+#if 0
+
 /*
  * Map an IO request into kernel virtual address space.
  *
@@ -303,6 +306,8 @@
 
 	bp->b_data = bp->b_saveaddr;
 }
+
+#endif
 
 /*
  * Reset back to firmware.
Index: sparc64/sparc64/vm_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/sparc64/sparc64/vm_machdep.c,v
retrieving revision 1.32
diff -u -r1.32 vm_machdep.c
--- sparc64/sparc64/vm_machdep.c	5 Jan 2003 05:30:40 -0000	1.32
+++ sparc64/sparc64/vm_machdep.c	11 Jan 2003 20:41:33 -0000
@@ -377,6 +377,8 @@
 	return(r);
 }
 
+#if 0
+
 /*
  * Map an IO request into kernel virtual address space.
  *
@@ -450,3 +452,5 @@
 
 	bp->b_data = bp->b_saveaddr;
 }
+
+#endif
Index: kern/vfs_bio.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_bio.c,v
retrieving revision 1.352
diff -u -r1.352 vfs_bio.c
--- kern/vfs_bio.c	7 Jan 2003 19:55:08 -0000	1.352
+++ kern/vfs_bio.c	11 Jan 2003 20:42:03 -0000
@@ -3540,6 +3540,77 @@
 	bp->b_npages = newnpages;
 }
 
+/*
+ * Map an IO request into kernel virtual address space.
+ *
+ * All requests are (re)mapped into kernel VA space.
+ * Notice that we use b_bufsize for the size of the buffer
+ * to be mapped.  b_bcount might be modified by the driver.
+ */
+void
+vmapbuf(struct buf *bp)
+{
+	caddr_t addr, kva;
+	vm_offset_t pa;
+	int pidx;
+	struct vm_page *m;
+
+	GIANT_REQUIRED;
+
+	if ((bp->b_flags & B_PHYS) == 0)
+		panic("vmapbuf");
+
+	for (addr = (caddr_t)trunc_page((vm_offset_t)bp->b_data), pidx = 0;
+	     addr < bp->b_data + bp->b_bufsize;
+	     addr += PAGE_SIZE, pidx++) {
+		/*
+		 * Do the vm_fault if needed; do the copy-on-write thing
+		 * when reading stuff off device into memory.
+		 */
+		vm_fault_quick((addr >= bp->b_data) ? addr : bp->b_data,
+			(bp->b_iocmd == BIO_READ)?(VM_PROT_READ|VM_PROT_WRITE):VM_PROT_READ);
+		pa = trunc_page(pmap_kextract((vm_offset_t) addr));
+		if (pa == 0)
+			panic("vmapbuf: page not present");
+		m = PHYS_TO_VM_PAGE(pa);
+		vm_page_hold(m);
+		bp->b_pages[pidx] = m;
+	}
+	if (pidx > btoc(MAXPHYS))
+		panic("vmapbuf: mapped more than MAXPHYS");
+	pmap_qenter((vm_offset_t)bp->b_saveaddr, bp->b_pages, pidx);
+	
+	kva = bp->b_saveaddr;
+	bp->b_npages = pidx;
+	bp->b_saveaddr = bp->b_data;
+	bp->b_data = kva + (((vm_offset_t) bp->b_data) & PAGE_MASK);
+}
+
+/*
+ * Free the io map PTEs associated with this IO operation.
+ * We also invalidate the TLB entries and restore the original b_addr.
+ */
+void
+vunmapbuf(struct buf *bp)
+{
+	int pidx;
+	int npages;
+
+	GIANT_REQUIRED;
+
+	if ((bp->b_flags & B_PHYS) == 0)
+		panic("vunmapbuf");
+
+	npages = bp->b_npages;
+	pmap_qremove(trunc_page((vm_offset_t)bp->b_data),
+		     npages);
+	vm_page_lock_queues();
+	for (pidx = 0; pidx < npages; pidx++)
+		vm_page_unhold(bp->b_pages[pidx]);
+	vm_page_unlock_queues();
+
+	bp->b_data = bp->b_saveaddr;
+}
 
 #include "opt_ddb.h"
 #ifdef DDB

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200301112051.h0BKpiWr047795>