diff options
author | alc <alc@FreeBSD.org> | 2010-12-25 21:26:56 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2010-12-25 21:26:56 +0000 |
commit | 971b02b7bcce9c49f919797dcad7b646c206b7b6 (patch) | |
tree | 069da87e128b6f0f35be7629bb29fa3f3c2db97e /sys/kern/vfs_bio.c | |
parent | 8e6dc31ba726f1333c1f0a995641a8d976ea3b4b (diff) | |
download | FreeBSD-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.c | 39 |
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; |