Module Name: src Committed By: ad Date: Sun Jan 12 17:46:56 UTC 2020
Modified Files: src/sys/uvm: uvm_map.c uvm_map.h Log Message: - uvm_unmap_remove(): need to call pmap_update() with the object still locked, otherwise the page could gain a new identity and still be visible via a stale mapping. - Adjust reference counts with atomics. To generate a diff of this commit: cvs rdiff -u -r1.370 -r1.371 src/sys/uvm/uvm_map.c cvs rdiff -u -r1.76 -r1.77 src/sys/uvm/uvm_map.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/uvm/uvm_map.c diff -u src/sys/uvm/uvm_map.c:1.370 src/sys/uvm/uvm_map.c:1.371 --- src/sys/uvm/uvm_map.c:1.370 Sun Jan 5 15:57:15 2020 +++ src/sys/uvm/uvm_map.c Sun Jan 12 17:46:55 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_map.c,v 1.370 2020/01/05 15:57:15 para Exp $ */ +/* $NetBSD: uvm_map.c,v 1.371 2020/01/12 17:46:55 ad Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.370 2020/01/05 15:57:15 para Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.371 2020/01/12 17:46:55 ad Exp $"); #include "opt_ddb.h" #include "opt_pax.h" @@ -2240,7 +2240,7 @@ uvm_unmap_remove(struct vm_map *map, vad } /* - * Save the free space hint + * save the free space hint */ if (map->first_free != &map->header && map->first_free->start >= start) @@ -2314,6 +2314,18 @@ uvm_unmap_remove(struct vm_map *map, vad uvm_map_lock_entry(entry); pmap_remove(map->pmap, entry->start, entry->end); + + /* + * note: if map is dying, leave pmap_update() for + * pmap_destroy(), which will be called later. + */ + + if ((map->flags & VM_MAP_DYING) == 0) { + pmap_update(vm_map_pmap(map)); + } else { + KASSERT(vm_map_pmap(map) != pmap_kernel()); + } + uvm_map_unlock_entry(entry); } @@ -2358,16 +2370,6 @@ uvm_unmap_remove(struct vm_map *map, vad entry = next; } - /* - * Note: if map is dying, leave pmap_update() for pmap_destroy(), - * which will be called later. - */ - if ((map->flags & VM_MAP_DYING) == 0) { - pmap_update(vm_map_pmap(map)); - } else { - KASSERT(vm_map_pmap(map) != pmap_kernel()); - } - uvm_map_check(map, "unmap_remove leave"); /* @@ -4254,14 +4256,10 @@ uvmspace_exec(struct lwp *l, vaddr_t sta void uvmspace_addref(struct vmspace *vm) { - struct vm_map *map = &vm->vm_map; - - KASSERT((map->flags & VM_MAP_DYING) == 0); - mutex_enter(&map->misc_lock); + KASSERT((vm->vm_map.flags & VM_MAP_DYING) == 0); KASSERT(vm->vm_refcnt > 0); - vm->vm_refcnt++; - mutex_exit(&map->misc_lock); + atomic_inc_uint(&vm->vm_refcnt); } /* @@ -4273,16 +4271,12 @@ uvmspace_free(struct vmspace *vm) { struct vm_map_entry *dead_entries; struct vm_map *map = &vm->vm_map; - int n; UVMHIST_FUNC("uvmspace_free"); UVMHIST_CALLED(maphist); UVMHIST_LOG(maphist,"(vm=%#jx) ref=%jd", (uintptr_t)vm, vm->vm_refcnt, 0, 0); - mutex_enter(&map->misc_lock); - n = --vm->vm_refcnt; - mutex_exit(&map->misc_lock); - if (n > 0) + if (atomic_dec_uint_nv(&vm->vm_refcnt) > 0) return; /* @@ -4777,15 +4771,14 @@ uvm_unmap1(struct vm_map *map, vaddr_t s /* * uvm_map_reference: add reference to a map * - * => map need not be locked (we use misc_lock). + * => map need not be locked */ void uvm_map_reference(struct vm_map *map) { - mutex_enter(&map->misc_lock); - map->ref_count++; - mutex_exit(&map->misc_lock); + + atomic_inc_uint(&map->ref_count); } void Index: src/sys/uvm/uvm_map.h diff -u src/sys/uvm/uvm_map.h:1.76 src/sys/uvm/uvm_map.h:1.77 --- src/sys/uvm/uvm_map.h:1.76 Sun Jan 5 15:57:15 2020 +++ src/sys/uvm/uvm_map.h Sun Jan 12 17:46:55 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_map.h,v 1.76 2020/01/05 15:57:15 para Exp $ */ +/* $NetBSD: uvm_map.h,v 1.77 2020/01/12 17:46:55 ad Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -209,7 +209,7 @@ struct vm_map { struct pmap * pmap; /* Physical map */ krwlock_t lock; /* Non-intrsafe lock */ struct lwp * busy; /* LWP holding map busy */ - kmutex_t misc_lock; /* Lock for ref_count, cv */ + kmutex_t misc_lock; /* Lock for cv, busy */ kcondvar_t cv; /* For signalling */ int flags; /* flags */ struct rb_tree rb_tree; /* Tree for entries */