summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2005-10-23 07:41:56 +0000
committeralc <alc@FreeBSD.org>2005-10-23 07:41:56 +0000
commit7e0abcbfdfd2aaab84f2ccdf2e2e9c34caf49a01 (patch)
treee5efa8663ca2c1c69874aa2369c6967dc945ea76 /sys/kern
parentef2eb0904eb393677771468885d9dc84acd4aebf (diff)
downloadFreeBSD-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.c7
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();
/*
OpenPOWER on IntegriCloud