Date: Wed, 20 Feb 2008 01:23:17 -0600 From: Alan Cox <alc@cs.rice.edu> To: Kostik Belousov <kostikbel@gmail.com> Cc: alc@freebsd.org, Michiel Boland <michiel@boland.org>, freebsd-current@freebsd.org Subject: Re: panic upon starting X in recent -CURRENTs (intel driver) Message-ID: <47BBD565.9040705@cs.rice.edu> In-Reply-To: <20080219132455.GD57756@deviant.kiev.zoral.com.ua> References: <Pine.GSO.4.64.0802011632120.15586@neerbosch.nijmegen.internl.net> <Pine.GSO.4.64.0802182330040.26002@neerbosch.nijmegen.internl.net> <20080219132455.GD57756@deviant.kiev.zoral.com.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
Kostik Belousov wrote:
>What happen there is that munmap() do the split for the /dev/mem mapping.
>This caused the OBJT_DEVICE ref_count to be bumped, and vm_map_entry_delete()
>called vm_object_page_remove(). The later called pmap_remove_all()
>unconditionally.
>
>pmap_remove_all has the KASSERT that fails exactly when supplied
>fictitious page. It becomes KASSERT in the rev. 1.106 of i386/pmap.c,
>committed 2008/01/08, it was under the PMAP_DIAGNOSTIC before.
>
>Since such page has md.pv_list empty anyway, this KASSERT seems to be
>only the statement of intent. The change below would prevent the panic
>by not calling pmap_remove_all from vm_object_page_remove for such pages.
>
>
>
In fact, md.pv_list is never initialized for fictitious pages. So, the
invocation of pmap_remove_all() has only worked 'til now because the
underlying memory is zeroed.
>Alan, do you have objections ? [Alternative seems to be a removal of the
>assertions from all pmap implementations, that also weaken the invariants
>for other callers that do skip fictitious pages].
>
>
I want to think this over. I'll e-mail you this weekend.
>diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
>index 21c0ac6..21ee10d 100644
>--- a/sys/vm/vm_object.c
>+++ b/sys/vm/vm_object.c
>@@ -1884,7 +1884,8 @@ again:
> */
> if ((wirings = p->wire_count) != 0 &&
> (wirings = pmap_page_wired_mappings(p)) != p->wire_count) {
>- pmap_remove_all(p);
>+ if ((p->flags & PG_FICTITIOUS) == 0)
>+ pmap_remove_all(p);
> /* Account for removal of managed, wired mappings. */
> p->wire_count -= wirings;
> if (!clean_only)
>@@ -1898,7 +1899,8 @@ again:
> if (p->valid & p->dirty)
> continue;
> }
>- pmap_remove_all(p);
>+ if ((p->flags & PG_FICTITIOUS) == 0)
>+ pmap_remove_all(p);
> /* Account for removal of managed, wired mappings. */
> if (wirings != 0)
> p->wire_count -= wirings;
>
>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?47BBD565.9040705>
