Date: Fri, 3 Aug 2012 01:48:16 +0000 (UTC) From: Alan Cox <alc@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r238998 - head/sys/vm Message-ID: <201208030148.q731mGcZ050429@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: alc Date: Fri Aug 3 01:48:15 2012 New Revision: 238998 URL: http://svn.freebsd.org/changeset/base/238998 Log: 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. Modified: head/sys/vm/vm_page.c head/sys/vm/vm_page.h Modified: head/sys/vm/vm_page.c ============================================================================== --- head/sys/vm/vm_page.c Fri Aug 3 00:11:13 2012 (r238997) +++ head/sys/vm/vm_page.c Fri Aug 3 01:48:15 2012 (r238998) @@ -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) { Modified: head/sys/vm/vm_page.h ============================================================================== --- head/sys/vm/vm_page.h Fri Aug 3 00:11:13 2012 (r238997) +++ head/sys/vm/vm_page.h Fri Aug 3 01:48:15 2012 (r238998) @@ -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_loc #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); @@ -428,6 +431,75 @@ void vm_page_object_lock_assert(vm_page_ #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: * * Set all bits in the page's dirty field.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208030148.q731mGcZ050429>