Skip site navigation (1)Skip section navigation (2)
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>