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 >_at__at_ -1884,7 +1884,8 _at__at_ 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) >_at__at_ -1898,7 +1899,8 _at__at_ 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; > >Received on Wed Feb 20 2008 - 06:40:28 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:27 UTC