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>
index | next in thread | previous in thread | raw e-mail
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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200301112051.h0BKpiWr047795>
