Date: Thu, 02 Aug 2012 21:04:14 -0500 From: Alan Cox <alc@rice.edu> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Cc: Alan Cox <alc@FreeBSD.org> Subject: Re: svn commit: r238998 - head/sys/vm Message-ID: <501B319E.3080305@rice.edu> In-Reply-To: <201208030148.q731mGcZ050429@svn.freebsd.org> References: <201208030148.q731mGcZ050429@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On 08/02/2012 20:48, Alan Cox wrote: > 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. This should have also included: Reviewed by: kib > 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?501B319E.3080305>