From owner-svn-src-all@FreeBSD.ORG Tue Jun 21 20:30:46 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id F388B10656ED; Tue, 21 Jun 2011 20:30:45 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from mx1.sbone.de (mx1.sbone.de [IPv6:2a01:4f8:130:3ffc::401:25]) by mx1.freebsd.org (Postfix) with ESMTP id 4D9408FC16; Tue, 21 Jun 2011 20:30:45 +0000 (UTC) Received: from mail.sbone.de (mail.sbone.de [IPv6:fde9:577b:c1a9:31::2013:587]) (using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by mx1.sbone.de (Postfix) with ESMTPS id E64A625D386D; Tue, 21 Jun 2011 20:30:43 +0000 (UTC) Received: from content-filter.sbone.de (content-filter.sbone.de [IPv6:fde9:577b:c1a9:31::2013:2742]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.sbone.de (Postfix) with ESMTPS id 3280515A2310; Tue, 21 Jun 2011 20:30:43 +0000 (UTC) X-Virus-Scanned: amavisd-new at sbone.de Received: from mail.sbone.de ([IPv6:fde9:577b:c1a9:31::2013:587]) by content-filter.sbone.de (content-filter.sbone.de [fde9:577b:c1a9:31::2013:2742]) (amavisd-new, port 10024) with ESMTP id e5Yt7OjTz20U; Tue, 21 Jun 2011 20:30:40 +0000 (UTC) Received: from orange-en1.sbone.de (orange-en1.sbone.de [IPv6:fde9:577b:c1a9:31:cabc:c8ff:fecf:e8e3]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by mail.sbone.de (Postfix) with ESMTPSA id 435A715A230E; Tue, 21 Jun 2011 20:30:40 +0000 (UTC) Mime-Version: 1.0 (Apple Message framework v1084) Content-Type: text/plain; charset=us-ascii From: "Bjoern A. Zeeb" In-Reply-To: <201106191913.p5JJDOqJ006272@svn.freebsd.org> Date: Tue, 21 Jun 2011 20:30:38 +0000 Content-Transfer-Encoding: quoted-printable Message-Id: References: <201106191913.p5JJDOqJ006272@svn.freebsd.org> To: Alan Cox X-Mailer: Apple Mail (2.1084) Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r223307 - head/sys/vm X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Jun 2011 20:30:46 -0000 On Jun 19, 2011, at 7:13 PM, Alan Cox wrote: Hi Alan, > Author: alc > Date: Sun Jun 19 19:13:24 2011 > New Revision: 223307 > URL: http://svn.freebsd.org/changeset/base/223307 >=20 > Log: > Precisely document the synchronization rules for the page's dirty = field. > (Saying that the lock on the object that the page belongs to must be = held > only represents one aspect of the rules.) >=20 > Eliminate the use of the page queues lock for atomically performing = read- > modify-write operations on the dirty field when the underlying = architecture > supports atomic operations on char and short types. >=20 > Document the fact that 32KB pages aren't really supported. >=20 contrary to the tinderbox I'd like to point out that all mips kernels = built by universe are broken with a SVN HEAD from earlier today. Could = you please check and see if you can fix it? The errors I get are: vm_page.o: In function `vm_page_clear_dirty': /sys/vm/vm_page.c:(.text+0x18d0): undefined reference to = `atomic_clear_8' /sys/vm/vm_page.c:(.text+0x18d0): relocation truncated to fit: R_MIPS_26 = against `atomic_clear_8' vm_page.o: In function `vm_page_set_validclean': /sys/vm/vm_page.c:(.text+0x38f0): undefined reference to = `atomic_clear_8' /sys/vm/vm_page.c:(.text+0x38f0): relocation truncated to fit: R_MIPS_26 = against `atomic_clear_8' Thanks a lot! /bz > Reviewed by: attilio, kib >=20 > Modified: > head/sys/vm/vm_fault.c > head/sys/vm/vm_page.c > head/sys/vm/vm_page.h >=20 > Modified: head/sys/vm/vm_fault.c > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > --- head/sys/vm/vm_fault.c Sun Jun 19 18:34:49 2011 = (r223306) > +++ head/sys/vm/vm_fault.c Sun Jun 19 19:13:24 2011 = (r223307) > @@ -1089,10 +1089,20 @@ vm_fault_quick_hold_pages(vm_map_t map,=20 > * caller's changes may go unnoticed because = they are > * performed through an unmanaged mapping or by = a DMA > * operation. > + * > + * The object lock is not held here. Therefore, = like > + * a pmap operation, the page queues lock may be > + * required in order to call vm_page_dirty(). = See > + * vm_page_clear_dirty_mask(). > */ > +#if defined(__amd64__) || defined(__i386__) || defined(__ia64__) || \ > + defined(__mips__) > + vm_page_dirty(*mp); > +#else > vm_page_lock_queues(); > vm_page_dirty(*mp); > vm_page_unlock_queues(); > +#endif > } > } > if (pmap_failed) { >=20 > Modified: head/sys/vm/vm_page.c > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > --- head/sys/vm/vm_page.c Sun Jun 19 18:34:49 2011 = (r223306) > +++ head/sys/vm/vm_page.c Sun Jun 19 19:13:24 2011 = (r223307) > @@ -729,7 +729,12 @@ vm_page_sleep(vm_page_t m, const char *m > /* > * vm_page_dirty: > * > - * make page all dirty > + * Set all bits in the page's dirty field. > + * > + * The object containing the specified page must be locked if the = call is > + * made from the machine-independent layer. If, however, the call = is > + * made from the pmap layer, then the page queues lock may be = required. > + * See vm_page_clear_dirty_mask(). > */ > void > vm_page_dirty(vm_page_t m) > @@ -2325,15 +2330,41 @@ vm_page_clear_dirty_mask(vm_page_t m, in > /* > * If the object is locked and the page is neither VPO_BUSY nor > * PG_WRITEABLE, then the page's dirty field cannot possibly be > - * modified by a concurrent pmap operation.=20 > + * set by a concurrent pmap operation.=20 > */ > VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); > if ((m->oflags & VPO_BUSY) =3D=3D 0 && (m->flags & PG_WRITEABLE) = =3D=3D 0) > m->dirty &=3D ~pagebits; > else { > +#if defined(__amd64__) || defined(__i386__) || defined(__ia64__) || \ > + defined(__mips__) > + /* > + * On the aforementioned architectures, the page queues = lock > + * is not required by the following read-modify-write > + * operation. The combination of the object's lock and = an > + * atomic operation suffice. Moreover, the pmap layer = on > + * these architectures can call vm_page_dirty() without > + * holding the page queues lock. > + */ > +#if PAGE_SIZE =3D=3D 4096 > + atomic_clear_char(&m->dirty, pagebits); > +#elif PAGE_SIZE =3D=3D 8192 > + atomic_clear_short(&m->dirty, pagebits); > +#elif PAGE_SIZE =3D=3D 16384 > + atomic_clear_int(&m->dirty, pagebits); > +#else > +#error "PAGE_SIZE is not supported." > +#endif > +#else > + /* > + * Otherwise, the page queues lock is required to ensure = that > + * a concurrent pmap operation does not set the page's = dirty > + * field during the following read-modify-write = operation. > + */ > vm_page_lock_queues(); > m->dirty &=3D ~pagebits; > vm_page_unlock_queues(); > +#endif > } > } >=20 >=20 > Modified: head/sys/vm/vm_page.h > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > --- head/sys/vm/vm_page.h Sun Jun 19 18:34:49 2011 = (r223306) > +++ head/sys/vm/vm_page.h Sun Jun 19 19:13:24 2011 = (r223307) > @@ -89,10 +89,26 @@ > * and offset to which this page belongs (for pageout), > * and sundry status bits. > * > - * Fields in this structure are locked either by the lock on the > - * object that the page belongs to (O), its corresponding page lock = (P), > - * or by the lock on the page queues (Q). > - *=09 > + * In general, operations on this structure's mutable fields are > + * synchronized using either one of or a combination of the lock on = the > + * object that the page belongs to (O), the pool lock for the page = (P), > + * or the lock for either the free or paging queues (Q). If a = field is > + * annotated below with two of these locks, then holding either = lock is > + * sufficient for read access, but both locks are required for = write=20 > + * access. > + * > + * In contrast, the synchronization of accesses to the page's dirty = field > + * is machine dependent (M). In the machine-independent layer, the = lock > + * on the object that the page belongs to must be held in order to > + * operate on the field. However, the pmap layer is permitted to = set > + * all bits within the field without holding that lock. Therefore, = if > + * the underlying architecture does not support atomic = read-modify-write > + * operations on the field's type, then the machine-independent = layer > + * must also hold the page queues lock when performing = read-modify-write > + * operations and the pmap layer must hold the page queues lock = when > + * setting the field. In the machine-independent layer, the > + * implementation of read-modify-write operations on the field is > + * encapsulated in vm_page_clear_dirty_mask(). > */ >=20 > TAILQ_HEAD(pglist, vm_page); > @@ -120,18 +136,19 @@ struct vm_page { > u_char busy; /* page busy count (O) */ > /* NOTE that these must support one bit per DEV_BSIZE in a = page!!! */ > /* so, on normal X86 kernels, they must be at least 8 bits wide = */ > + /* In reality, support for 32KB pages is not fully implemented. = */ > #if PAGE_SIZE =3D=3D 4096 > u_char valid; /* map of valid DEV_BSIZE chunks = (O) */ > - u_char dirty; /* map of dirty DEV_BSIZE chunks = (O) */ > + u_char dirty; /* map of dirty DEV_BSIZE chunks = (M) */ > #elif PAGE_SIZE =3D=3D 8192 > u_short valid; /* map of valid DEV_BSIZE chunks = (O) */ > - u_short dirty; /* map of dirty DEV_BSIZE chunks = (O) */ > + u_short dirty; /* map of dirty DEV_BSIZE chunks = (M) */ > #elif PAGE_SIZE =3D=3D 16384 > u_int valid; /* map of valid DEV_BSIZE chunks = (O) */ > - u_int dirty; /* map of dirty DEV_BSIZE chunks = (O) */ > + u_int dirty; /* map of dirty DEV_BSIZE chunks = (M) */ > #elif PAGE_SIZE =3D=3D 32768 > u_long valid; /* map of valid DEV_BSIZE chunks = (O) */ > - u_long dirty; /* map of dirty DEV_BSIZE chunks = (O) */ > + u_long dirty; /* map of dirty DEV_BSIZE chunks = (M) */ > #endif > }; >=20 --=20 Bjoern A. Zeeb You have to have visions! Stop bit received. Insert coin for new address family.