summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_bio.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2010-12-25 21:26:56 +0000
committeralc <alc@FreeBSD.org>2010-12-25 21:26:56 +0000
commit971b02b7bcce9c49f919797dcad7b646c206b7b6 (patch)
tree069da87e128b6f0f35be7629bb29fa3f3c2db97e /sys/kern/vfs_bio.c
parent8e6dc31ba726f1333c1f0a995641a8d976ea3b4b (diff)
downloadFreeBSD-src-971b02b7bcce9c49f919797dcad7b646c206b7b6.zip
FreeBSD-src-971b02b7bcce9c49f919797dcad7b646c206b7b6.tar.gz
Introduce and use a new VM interface for temporarily pinning pages. This
new interface replaces the combined use of vm_fault_quick() and pmap_extract_and_hold() throughout the kernel. In collaboration with: kib@
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r--sys/kern/vfs_bio.c39
1 files changed, 6 insertions, 33 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 7d04e33..0147bff 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -3855,46 +3855,19 @@ vm_hold_free_pages(struct buf *bp, int newbsize)
int
vmapbuf(struct buf *bp)
{
- caddr_t addr, kva;
+ caddr_t kva;
vm_prot_t prot;
- int pidx, i;
- struct vm_page *m;
- struct pmap *pmap = &curproc->p_vmspace->vm_pmap;
+ int pidx;
if (bp->b_bufsize < 0)
return (-1);
prot = VM_PROT_READ;
if (bp->b_iocmd == BIO_READ)
prot |= VM_PROT_WRITE; /* Less backwards than it looks */
- 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.
- *
- * NOTE! Must use pmap_extract() because addr may be in
- * the userland address space, and kextract is only guarenteed
- * to work for the kernland address space (see: sparc64 port).
- */
-retry:
- if (vm_fault_quick(addr >= bp->b_data ? addr : bp->b_data,
- prot) < 0) {
- for (i = 0; i < pidx; ++i) {
- vm_page_lock(bp->b_pages[i]);
- vm_page_unhold(bp->b_pages[i]);
- vm_page_unlock(bp->b_pages[i]);
- bp->b_pages[i] = NULL;
- }
- return(-1);
- }
- m = pmap_extract_and_hold(pmap, (vm_offset_t)addr, prot);
- if (m == NULL)
- goto retry;
- bp->b_pages[pidx] = m;
- }
- if (pidx > btoc(MAXPHYS))
- panic("vmapbuf: mapped more than MAXPHYS");
+ if ((pidx = vm_fault_quick_hold_pages(&curproc->p_vmspace->vm_map,
+ (vm_offset_t)bp->b_data, bp->b_bufsize, prot, bp->b_pages,
+ btoc(MAXPHYS))) < 0)
+ return (-1);
pmap_qenter((vm_offset_t)bp->b_saveaddr, bp->b_pages, pidx);
kva = bp->b_saveaddr;
OpenPOWER on IntegriCloud