aboutsummaryrefslogtreecommitdiff
path: root/sys/vm
diff options
context:
space:
mode:
authorAlan Cox <alc@FreeBSD.org>2010-05-16 23:45:10 +0000
committerAlan Cox <alc@FreeBSD.org>2010-05-16 23:45:10 +0000
commit9ab6032f7308c0fde81396b7f0dfd7dc88f3d741 (patch)
tree5d19152403395b71d9fe26760d1b05201ce13b02 /sys/vm
parent0532c3a5a51cd3e417cc92a5220b35b74c467b38 (diff)
downloadsrc-9ab6032f7308c0fde81396b7f0dfd7dc88f3d741.tar.gz
src-9ab6032f7308c0fde81396b7f0dfd7dc88f3d741.zip
On entry to pmap_enter(), assert that the page is busy. While I'm
here, make the style of assertion used by pmap_enter() consistent across all architectures. On entry to pmap_remove_write(), assert that the page is neither unmanaged nor fictitious, since we cannot remove write access to either kind of page. With the push down of the page queues lock, pmap_remove_write() cannot condition its behavior on the state of the PG_WRITEABLE flag if the page is busy. Assert that the object containing the page is locked. This allows us to know that the page will neither become busy nor will PG_WRITEABLE be set on it while pmap_remove_write() is running. Correct a long-standing bug in vm_page_cowsetup(). We cannot possibly do copy-on-write-based zero-copy transmit on unmanaged or fictitious pages, so don't even try. Previously, the call to pmap_remove_write() would have failed silently.
Notes
Notes: svn path=/head/; revision=208175
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_page.c4
-rw-r--r--sys/vm/vm_page.h4
2 files changed, 5 insertions, 3 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index e70ca3f5c514..1c877d932c28 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -2336,10 +2336,12 @@ vm_page_cowsetup(vm_page_t m)
{
vm_page_lock_assert(m, MA_OWNED);
- if (m->cow == USHRT_MAX - 1)
+ if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0 ||
+ m->cow == USHRT_MAX - 1 || !VM_OBJECT_TRYLOCK(m->object))
return (EBUSY);
m->cow++;
pmap_remove_write(m);
+ VM_OBJECT_UNLOCK(m->object);
return (0);
}
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index e9d95449f324..aebf79e1edcd 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -217,8 +217,8 @@ extern struct vpglocks pa_lock[];
* pte mappings, nor can they be removed from their objects via
* the object, and such pages are also not on any PQ queue.
*
- * PG_WRITEABLE is set exclusively by pmap_enter(). When it does so, either
- * the page must be VPO_BUSY or the containing object must be locked.
+ * PG_WRITEABLE is set exclusively by pmap_enter(). When it does so, the page
+ * must be VPO_BUSY.
*/
#define PG_CACHED 0x0001 /* page is cached */
#define PG_FREE 0x0002 /* page is free */