Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Nov 2013 20:24:29 +1100
From:      Jan Mikkelsen <janm@transactionware.com>
To:        Andriy Gapon <avg@freebsd.org>
Cc:        freebsd-stable@FreeBSD.org, Steven Hartland <smh@FreeBSD.org>, hartzell@alerce.com
Subject:   Re: Help with filing a [maybe] ZFS/mmap bug.
Message-ID:  <4B5798F5-269A-4E71-9799-E1B4E0C1545F@transactionware.com>
In-Reply-To: <52889105.7040404@FreeBSD.org>
References:  <20967.760.95825.310085@gargle.gargle.HOWL><51E80B30.1090004@FreeBSD.org><20968.10645.880772.30501@gargle.gargle.HOWL><520202E5.30300@FreeBSD.org><20994.55913.93606.436124@gargle.gargle.HOWL><FEE7BDCF7F494EE1BA0BE9424275AA91@multiplay.co.uk> <21111.12085.958991.356982@gargle.gargle.HOWL> <4EB902F80CE84DD2BF36C85EF4CE8EF8@multiplay.co.uk> <5284B8A5.8040604@FreeBSD.org> <52889105.7040404@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help

On 17 Nov 2013, at 8:48 pm, Andriy Gapon <avg@freebsd.org> wrote:

> on 14/11/2013 13:48 Andriy Gapon said the following:
>> HOWEVER.  I think that there is a bug that I introduced in r246293.
>> Specifically I changed
>> 	vm_page_undirty(pp);
>> to
>> 	pmap_remove_write(pp);
>> 	vm_page_clear_dirty(pp, off, nbytes);
>>=20
>> vm_page_undirty() would be a very serious (and probably obvious) bug, =
if it were
>> not a NOP in effect.  The details are explained in the commit =
message.
>> But when I used vm_page_clear_dirty I completely missed the fact that =
*extends*
>> the range to DEV_BSIZE aligned boundaries[*].  So, given the =
described behavior
>> and that pmap_remove_write clears the page modified bit, it is =
possible that the
>> data dirty data in the extended areas will be marked as clean.
>=20
> Here is a patch (for head) that should fix the described above issue:
>=20
> diff --git =
a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
> b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
> index 2e2cbd6..4fcd571 100644
> --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
> +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
> @@ -328,6 +328,20 @@ page_busy(vnode_t *vp, int64_t start, int64_t =
off, int64_t
> nbytes)
> {
> 	vm_object_t obj;
> 	vm_page_t pp;
> +	int64_t end;
> +
> +	/*
> +	 * At present vm_page_clear_dirty extends the cleared range to =
DEV_BSIZE
> +	 * aligned boundaries, if the range is not aligned.  As a result =
a
> +	 * DEV_BSIZE subrange with partially dirty data may get marked =
as clean.
> +	 * It may happen that all DEV_BSIZE subranges are marked clean =
and thus
> +	 * the whole page would be considred clean despite have some =
dirty data.
> +	 * For this reason we should shrink the range to DEV_BSIZE =
aligned
> +	 * boundaries before calling vm_page_clear_dirty.
> +	 */
> +	end =3D rounddown2(off + nbytes, DEV_BSIZE);
> +	off =3D roundup2(off, DEV_BSIZE);
> +	nbytes =3D end - off;
>=20
> 	obj =3D vp->v_object;
> 	zfs_vmobject_assert_wlocked(obj);
> @@ -362,7 +376,8 @@ page_busy(vnode_t *vp, int64_t start, int64_t off, =
int64_t
> nbytes)
> 			ASSERT3U(pp->valid, =3D=3D, VM_PAGE_BITS_ALL);
> 			vm_object_pip_add(obj, 1);
> 			pmap_remove_write(pp);
> -			vm_page_clear_dirty(pp, off, nbytes);
> +			if (nbytes !=3D 0)
> +				vm_page_clear_dirty(pp, off, nbytes);
> 		}
> 		break;
> 	}


9.2 does not seem to have a rounddown2() macro.




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4B5798F5-269A-4E71-9799-E1B4E0C1545F>