svn commit: r238998 - head/sys/vm

Alan Cox alc at rice.edu
Fri Aug 3 02:04:16 UTC 2012


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.
>



More information about the svn-src-head mailing list