Adapt vm_page_aflag_set(PGA_WRITEABLE) to the locking of

pmap_enter(PMAP_ENTER_NOSLEEP).  The PGA_WRITEABLE flag can be set
when either the page is busied, or the owner object is locked.

Update comments, move all assertions about page state when
PGA_WRITEABLE flag is set, into new helper
vm_page_assert_pga_writeable().

Reviewed by:	alc
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
This commit is contained in:
kib 2014-08-09 05:00:34 +00:00
parent e23364d720
commit 41802e2c86
2 changed files with 27 additions and 11 deletions

View File

@ -3134,6 +3134,24 @@ vm_page_object_lock_assert(vm_page_t m)
if (m->object != NULL && !vm_page_xbusied(m))
VM_OBJECT_ASSERT_WLOCKED(m->object);
}
void
vm_page_assert_pga_writeable(vm_page_t m, uint8_t bits)
{
if ((bits & PGA_WRITEABLE) == 0)
return;
/*
* The PGA_WRITEABLE flag can only be set if the page is
* managed, is exclusively busied or the object is locked.
* Currently, this flag is only set by pmap_enter().
*/
KASSERT((m->oflags & VPO_UNMANAGED) == 0,
("PGA_WRITEABLE on unmanaged page"));
if (!vm_page_xbusied(m))
VM_OBJECT_ASSERT_LOCKED(m->object);
}
#endif
#include "opt_ddb.h"

View File

@ -305,10 +305,10 @@ extern struct mtx_padalign pa_lock[];
* both the MI and MD VM layers. However, kernel loadable modules should not
* directly set this flag. They should call vm_page_reference() instead.
*
* PGA_WRITEABLE is set exclusively on managed pages by pmap_enter(). When it
* does so, the page must be exclusive busied. The MI VM layer must never
* access this flag directly. Instead, it should call
* pmap_page_is_write_mapped().
* PGA_WRITEABLE is set exclusively on managed pages by pmap_enter().
* When it does so, the object must be locked, or the page must be
* exclusive busied. The MI VM layer must never access this flag
* directly. Instead, it should call pmap_page_is_write_mapped().
*
* PGA_EXECUTABLE may be set by pmap routines, and indicates that a page has
* at least one executable mapping. It is not consumed by the MI VM layer.
@ -533,8 +533,12 @@ void vm_page_lock_assert_KBI(vm_page_t m, int a, const char *file, int line);
#ifdef INVARIANTS
void vm_page_object_lock_assert(vm_page_t m);
#define VM_PAGE_OBJECT_LOCK_ASSERT(m) vm_page_object_lock_assert(m)
void vm_page_assert_pga_writeable(vm_page_t m, uint8_t bits);
#define VM_PAGE_ASSERT_PGA_WRITEABLE(m, bits) \
vm_page_assert_pga_writeable(m, bits)
#else
#define VM_PAGE_OBJECT_LOCK_ASSERT(m) (void)0
#define VM_PAGE_ASSERT_PGA_WRITEABLE(m, bits) (void)0
#endif
/*
@ -582,13 +586,7 @@ vm_page_aflag_set(vm_page_t m, uint8_t bits)
{
uint32_t *addr, val;
/*
* The PGA_WRITEABLE flag can only be set if the page is managed and
* exclusive busied. Currently, this flag is only set by pmap_enter().
*/
KASSERT((bits & PGA_WRITEABLE) == 0 ||
((m->oflags & VPO_UNMANAGED) == 0 && vm_page_xbusied(m)),
("vm_page_aflag_set: PGA_WRITEABLE and not exclusive busy"));
VM_PAGE_ASSERT_PGA_WRITEABLE(m, bits);
/*
* Access the whole 32-bit word containing the aflags field with an