Inline vm_page_aflags_clear() and vm_page_aflags_set().
Add comments stating that neither these functions nor the flags that they are used to manipulate are part of the KBI.
This commit is contained in:
parent
0f3fae6159
commit
369763e31a
@ -450,63 +450,6 @@ vm_page_startup(vm_offset_t vaddr)
|
||||
return (vaddr);
|
||||
}
|
||||
|
||||
|
||||
CTASSERT(offsetof(struct vm_page, aflags) % sizeof(uint32_t) == 0);
|
||||
|
||||
void
|
||||
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
|
||||
* VPO_BUSY. Currently, this flag is only set by pmap_enter().
|
||||
*/
|
||||
KASSERT((bits & PGA_WRITEABLE) == 0 ||
|
||||
(m->oflags & (VPO_UNMANAGED | VPO_BUSY)) == VPO_BUSY,
|
||||
("PGA_WRITEABLE and !VPO_BUSY"));
|
||||
|
||||
/*
|
||||
* We want to use atomic updates for m->aflags, which is a
|
||||
* byte wide. Not all architectures provide atomic operations
|
||||
* on the single-byte destination. Punt and access the whole
|
||||
* 4-byte word with an atomic update. Parallel non-atomic
|
||||
* updates to the fields included in the update by proximity
|
||||
* are handled properly by atomics.
|
||||
*/
|
||||
addr = (void *)&m->aflags;
|
||||
MPASS(((uintptr_t)addr & (sizeof(uint32_t) - 1)) == 0);
|
||||
val = bits;
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
val <<= 24;
|
||||
#endif
|
||||
atomic_set_32(addr, val);
|
||||
}
|
||||
|
||||
void
|
||||
vm_page_aflag_clear(vm_page_t m, uint8_t bits)
|
||||
{
|
||||
uint32_t *addr, val;
|
||||
|
||||
/*
|
||||
* The PGA_REFERENCED flag can only be cleared if the object
|
||||
* containing the page is locked.
|
||||
*/
|
||||
KASSERT((bits & PGA_REFERENCED) == 0 || VM_OBJECT_LOCKED(m->object),
|
||||
("PGA_REFERENCED and !VM_OBJECT_LOCKED"));
|
||||
|
||||
/*
|
||||
* See the comment in vm_page_aflag_set().
|
||||
*/
|
||||
addr = (void *)&m->aflags;
|
||||
MPASS(((uintptr_t)addr & (sizeof(uint32_t) - 1)) == 0);
|
||||
val = bits;
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
val <<= 24;
|
||||
#endif
|
||||
atomic_clear_32(addr, val);
|
||||
}
|
||||
|
||||
void
|
||||
vm_page_reference(vm_page_t m)
|
||||
{
|
||||
|
@ -239,13 +239,14 @@ extern struct vpglocks pa_lock[];
|
||||
#define vm_page_queue_free_mtx vm_page_queue_free_lock.data
|
||||
|
||||
/*
|
||||
* These are the flags defined for vm_page.
|
||||
*
|
||||
* aflags are updated by atomic accesses. Use the vm_page_aflag_set()
|
||||
* and vm_page_aflag_clear() functions to set and clear the flags.
|
||||
* The vm_page's aflags are updated using atomic operations. To set or clear
|
||||
* these flags, the functions vm_page_aflag_set() and vm_page_aflag_clear()
|
||||
* must be used. Neither these flags nor these functions are part of the KBI.
|
||||
*
|
||||
* PGA_REFERENCED may be cleared only if the object containing the page is
|
||||
* locked. It is set by both the MI and MD VM layers.
|
||||
* locked. It is set by 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 VPO_BUSY. The MI VM layer must never access this
|
||||
@ -281,8 +282,12 @@ extern struct vpglocks pa_lock[];
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <vm/vm_param.h>
|
||||
|
||||
#include <machine/atomic.h>
|
||||
|
||||
/*
|
||||
* Each pageable resident page falls into one of five lists:
|
||||
*
|
||||
@ -349,8 +354,6 @@ extern struct vpglocks vm_page_queue_lock;
|
||||
#define VM_ALLOC_COUNT_SHIFT 16
|
||||
#define VM_ALLOC_COUNT(count) ((count) << VM_ALLOC_COUNT_SHIFT)
|
||||
|
||||
void vm_page_aflag_set(vm_page_t m, uint8_t bits);
|
||||
void vm_page_aflag_clear(vm_page_t m, uint8_t bits);
|
||||
void vm_page_busy(vm_page_t m);
|
||||
void vm_page_flash(vm_page_t m);
|
||||
void vm_page_io_start(vm_page_t m);
|
||||
@ -427,6 +430,75 @@ void vm_page_object_lock_assert(vm_page_t m);
|
||||
#define VM_PAGE_OBJECT_LOCK_ASSERT(m) (void)0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We want to use atomic updates for the aflags field, which is 8 bits wide.
|
||||
* However, not all architectures support atomic operations on 8-bit
|
||||
* destinations. In order that we can easily use a 32-bit operation, we
|
||||
* require that the aflags field be 32-bit aligned.
|
||||
*/
|
||||
CTASSERT(offsetof(struct vm_page, aflags) % sizeof(uint32_t) == 0);
|
||||
|
||||
/*
|
||||
* Clear the given bits in the specified page.
|
||||
*/
|
||||
static inline void
|
||||
vm_page_aflag_clear(vm_page_t m, uint8_t bits)
|
||||
{
|
||||
uint32_t *addr, val;
|
||||
|
||||
/*
|
||||
* The PGA_REFERENCED flag can only be cleared if the object
|
||||
* containing the page is locked.
|
||||
*/
|
||||
if ((bits & PGA_REFERENCED) != 0)
|
||||
VM_PAGE_OBJECT_LOCK_ASSERT(m);
|
||||
|
||||
/*
|
||||
* Access the whole 32-bit word containing the aflags field with an
|
||||
* atomic update. Parallel non-atomic updates to the other fields
|
||||
* within this word are handled properly by the atomic update.
|
||||
*/
|
||||
addr = (void *)&m->aflags;
|
||||
KASSERT(((uintptr_t)addr & (sizeof(uint32_t) - 1)) == 0,
|
||||
("vm_page_aflag_clear: aflags is misaligned"));
|
||||
val = bits;
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
val <<= 24;
|
||||
#endif
|
||||
atomic_clear_32(addr, val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the given bits in the specified page.
|
||||
*/
|
||||
static inline void
|
||||
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
|
||||
* VPO_BUSY. Currently, this flag is only set by pmap_enter().
|
||||
*/
|
||||
KASSERT((bits & PGA_WRITEABLE) == 0 ||
|
||||
(m->oflags & (VPO_UNMANAGED | VPO_BUSY)) == VPO_BUSY,
|
||||
("vm_page_aflag_set: PGA_WRITEABLE and !VPO_BUSY"));
|
||||
|
||||
/*
|
||||
* Access the whole 32-bit word containing the aflags field with an
|
||||
* atomic update. Parallel non-atomic updates to the other fields
|
||||
* within this word are handled properly by the atomic update.
|
||||
*/
|
||||
addr = (void *)&m->aflags;
|
||||
KASSERT(((uintptr_t)addr & (sizeof(uint32_t) - 1)) == 0,
|
||||
("vm_page_aflag_set: aflags is misaligned"));
|
||||
val = bits;
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
val <<= 24;
|
||||
#endif
|
||||
atomic_set_32(addr, val);
|
||||
}
|
||||
|
||||
/*
|
||||
* vm_page_dirty:
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user