diff options
author | alc <alc@FreeBSD.org> | 2005-10-23 07:41:56 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2005-10-23 07:41:56 +0000 |
commit | 7e0abcbfdfd2aaab84f2ccdf2e2e9c34caf49a01 (patch) | |
tree | e5efa8663ca2c1c69874aa2369c6967dc945ea76 /sys/kern | |
parent | ef2eb0904eb393677771468885d9dc84acd4aebf (diff) | |
download | FreeBSD-src-7e0abcbfdfd2aaab84f2ccdf2e2e9c34caf49a01.zip FreeBSD-src-7e0abcbfdfd2aaab84f2ccdf2e2e9c34caf49a01.tar.gz |
Previously, nothing prevented the page that was returned by pmap_extract()
from being reclaimed before it was wired. Use pmap_extract_and_hold()
instead of pmap_extract() and retain the hold on the page until it has been
wired.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/uipc_cow.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/sys/kern/uipc_cow.c b/sys/kern/uipc_cow.c index c3a437c..b4773d1 100644 --- a/sys/kern/uipc_cow.c +++ b/sys/kern/uipc_cow.c @@ -99,7 +99,6 @@ socow_setup(struct mbuf *m0, struct uio *uio) { struct sf_buf *sf; vm_page_t pp; - vm_paddr_t pa; struct iovec *iov; struct vmspace *vmspace; struct vm_map *map; @@ -120,12 +119,11 @@ socow_setup(struct mbuf *m0, struct uio *uio) /* * verify page is mapped & not already wired for i/o */ - pa=pmap_extract(map->pmap, uva); - if(!pa) { + pp = pmap_extract_and_hold(map->pmap, uva, VM_PROT_READ); + if (pp == NULL) { socow_stats.fail_not_mapped++; return(0); } - pp = PHYS_TO_VM_PAGE(pa); /* * set up COW @@ -137,6 +135,7 @@ socow_setup(struct mbuf *m0, struct uio *uio) * wire the page for I/O */ vm_page_wire(pp); + vm_page_unhold(pp); vm_page_unlock_queues(); /* |