Please try the following if you are having strange SIGBUS problems/leaked wired memory and you are running programs that use mlockall(2). There were several distinct bugs that caused pages to never get unwired and completely unrelated processes to act as if mlockall(2) was called when they had not done so. Index: vm_fault.c =================================================================== RCS file: /usr/ncvs/src/sys/vm/vm_fault.c,v retrieving revision 1.186 diff -u -r1.186 vm_fault.c --- vm_fault.c 10 Mar 2004 04:44:43 -0000 1.186 +++ vm_fault.c 27 Apr 2004 21:45:53 -0000 _at__at_ -1065,6 +1065,14 _at__at_ return (KERN_SUCCESS); } +SYSCTL_NODE(_vm, OID_AUTO, fault_unwire, CTLFLAG_RW, 0, "vm_fault_unwire"); +static unsigned int vm_fault_unwire_noentry; +SYSCTL_UINT(_vm_fault_unwire, OID_AUTO, noentry, + CTLFLAG_RD, &vm_fault_unwire_noentry, 0, ""); +static unsigned int vm_fault_unwire_nopage; +SYSCTL_UINT(_vm_fault_unwire, OID_AUTO, nopage, + CTLFLAG_RD, &vm_fault_unwire_nopage, 0, ""); + /* * vm_fault_unwire: * _at__at_ -1075,28 +1083,56 _at__at_ vm_map_t map; vm_offset_t start, end; { - vm_paddr_t pa; + vm_map_entry_t entry; + vm_object_t object, object2; vm_offset_t va; + vm_page_t page; + vm_ooffset_t oidx; pmap_t pmap; pmap = vm_map_pmap(map); - - if (pmap != kernel_pmap) + if (!map->system_map) mtx_lock(&Giant); - /* - * Since the pages are wired down, we must be able to get their - * mappings from the physical map system. - */ - for (va = start; va < end; va += PAGE_SIZE) { - pa = pmap_extract(pmap, va); - if (pa != 0) { - pmap_change_wiring(pmap, va, FALSE); + for (entry = NULL, va = start; va < end; va += PAGE_SIZE) { + if (entry == NULL || va >= entry->end) { + if (vm_map_lookup_entry(map, va, &entry) == FALSE) { + atomic_add_int(&vm_fault_unwire_noentry, 1); + entry = NULL; + continue; + } + } + object = entry->object.vm_object; + oidx = OFF_TO_IDX(entry->offset + va - entry->start); + VM_OBJECT_LOCK(object); +nextobject: + page = vm_page_lookup(object, oidx); + if (page != NULL) { + /* + * The page itself may be wired, but if it was + * never accessed from anything other than + * vm_fault_prefault(), it won't exist in pmap. + */ + if (pmap_extract(pmap, va) != 0) + pmap_change_wiring(pmap, va, FALSE); vm_page_lock_queues(); - vm_page_unwire(PHYS_TO_VM_PAGE(pa), 1); + vm_page_unwire(page, 1); vm_page_unlock_queues(); + } else { + object2 = object->backing_object; + if (object2 == NULL) { + atomic_add_int(&vm_fault_unwire_nopage, 1); + } else { + VM_OBJECT_LOCK(object2); + oidx += + OFF_TO_IDX(object->backing_object_offset); + VM_OBJECT_UNLOCK(object); + object = object2; + goto nextobject; + } } + VM_OBJECT_UNLOCK(object); } - if (pmap != kernel_pmap) + if (!map->system_map) mtx_unlock(&Giant); } Index: vm_map.c =================================================================== RCS file: /usr/ncvs/src/sys/vm/vm_map.c,v retrieving revision 1.332 diff -u -r1.332 vm_map.c --- vm_map.c 6 Apr 2004 20:15:36 -0000 1.332 +++ vm_map.c 27 Apr 2004 22:43:58 -0000 _at__at_ -297,6 +297,7 _at__at_ vm_map_lock(&vm->vm_map); (void) vm_map_delete(&vm->vm_map, vm->vm_map.min_offset, vm->vm_map.max_offset); + vm_map_modflags(&vm->vm_map, 0, MAP_WIREFUTURE); vm_map_unlock(&vm->vm_map); pmap_release(vmspace_pmap(vm)); -- Brian Fundakowski Feldman \'[ FreeBSD ]''''''''''\ <> green_at_FreeBSD.org \ The Power to Serve! \ Opinions expressed are my own. \,,,,,,,,,,,,,,,,,,,,,,\Received on Tue Apr 27 2004 - 13:54:39 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:52 UTC