Index: uvm_map.c =================================================================== RCS file: /cvs/src/sys/uvm/uvm_map.c,v diff -u -p -r1.330 uvm_map.c --- uvm_map.c 24 Jul 2024 12:17:31 -0000 1.330 +++ uvm_map.c 11 Oct 2024 10:12:14 -0000 @@ -5201,68 +5201,77 @@ out: boolean_t vm_map_lock_try_ln(struct vm_map *map, char *file, int line) { - boolean_t rv; + int rv; if (map->flags & VM_MAP_INTRSAFE) { - rv = mtx_enter_try(&map->mtx); + if (!mtx_enter_try(&map->mtx)) + return (FALSE); } else { + struct proc *busy; + mtx_enter(&map->flags_lock); - if ((map->flags & VM_MAP_BUSY) && (map->busy != curproc)) { - mtx_leave(&map->flags_lock); + busy = map->busy; + mtx_leave(&map->flags_lock); + if (busy != NULL && busy != curproc) return (FALSE); - } + + rv = rw_enter(&map->lock, RW_WRITE|RW_NOSLEEP); + if (rv != 0) + return (FALSE); + + /* to be sure, to be sure */ + mtx_enter(&map->flags_lock); + busy = map->busy; mtx_leave(&map->flags_lock); - rv = (rw_enter(&map->lock, RW_WRITE|RW_NOSLEEP) == 0); - /* check if the lock is busy and back out if we won the race */ - if (rv) { - mtx_enter(&map->flags_lock); - if ((map->flags & VM_MAP_BUSY) && - (map->busy != curproc)) { - rw_exit(&map->lock); - rv = FALSE; - } - mtx_leave(&map->flags_lock); + if (busy != NULL && busy != curproc) { + rw_exit(&map->lock); + return (FALSE); } } - if (rv) { - map->timestamp++; - LPRINTF(("map lock: %p (at %s %d)\n", map, file, line)); - uvm_tree_sanity(map, file, line); - uvm_tree_size_chk(map, file, line); - } + map->timestamp++; + LPRINTF(("map lock: %p (at %s %d)\n", map, file, line)); + uvm_tree_sanity(map, file, line); + uvm_tree_size_chk(map, file, line); - return (rv); + return (TRUE); } void vm_map_lock_ln(struct vm_map *map, char *file, int line) { - if ((map->flags & VM_MAP_INTRSAFE) == 0) { - do { - mtx_enter(&map->flags_lock); -tryagain: - while ((map->flags & VM_MAP_BUSY) && - (map->busy != curproc)) { - map->flags |= VM_MAP_WANTLOCK; - msleep_nsec(&map->flags, &map->flags_lock, + if (map->flags & VM_MAP_INTRSAFE) { + mtx_enter(&map->mtx); + } else { + mtx_enter(&map->flags_lock); + for (;;) { + while (map->busy != NULL && map->busy != curproc) { + map->nbusy++; + msleep_nsec(&map->busy, &map->mtx, PVM, vmmapbsy, INFSLP); + map->nbusy--; } mtx_leave(&map->flags_lock); - } while (rw_enter(&map->lock, RW_WRITE|RW_SLEEPFAIL) != 0); - /* check if the lock is busy and back out if we won the race */ - mtx_enter(&map->flags_lock); - if ((map->flags & VM_MAP_BUSY) && (map->busy != curproc)) { - rw_exit(&map->lock); - goto tryagain; + + rw_enter_write(&map->lock); + + /* to be sure, to be sure */ + mtx_enter(&map->flags_lock); + if (map->busy != NULL && map->busy != curproc) { + /* go around again */ + rw_exit_write(&map->lock); + } else { + /* we won */ + break; + } } mtx_leave(&map->flags_lock); - } else { - mtx_enter(&map->mtx); } - if (map->busy != curproc) + if (map->busy != curproc) { + KASSERT(map->busy == NULL); map->timestamp++; + } LPRINTF(("map lock: %p (at %s %d)\n", map, file, line)); uvm_tree_sanity(map, file, line); uvm_tree_size_chk(map, file, line); @@ -5312,27 +5321,24 @@ vm_map_busy_ln(struct vm_map *map, char KASSERT(rw_write_held(&map->lock)); KASSERT(map->busy == NULL); - mtx_enter(&map->flags_lock); map->busy = curproc; - map->flags |= VM_MAP_BUSY; - mtx_leave(&map->flags_lock); } void vm_map_unbusy_ln(struct vm_map *map, char *file, int line) { - int oflags; + unsigned int nbusy; KASSERT((map->flags & VM_MAP_INTRSAFE) == 0); KASSERT(map->busy == curproc); mtx_enter(&map->flags_lock); - oflags = map->flags; + nbusy = map->nbusy; map->busy = NULL; - map->flags &= ~(VM_MAP_BUSY|VM_MAP_WANTLOCK); mtx_leave(&map->flags_lock); - if (oflags & VM_MAP_WANTLOCK) - wakeup(&map->flags); + + if (nbusy > 0) + wakeup_n(&map->busy, nbusy); } void Index: uvm_map.h =================================================================== RCS file: /cvs/src/sys/uvm/uvm_map.h,v diff -u -p -r1.90 uvm_map.h --- uvm_map.h 18 Jun 2024 12:37:29 -0000 1.90 +++ uvm_map.h 11 Oct 2024 10:12:14 -0000 @@ -269,6 +269,7 @@ struct vm_map { int flags; /* flags */ unsigned int timestamp; /* Version number */ struct proc *busy; /* [v] thread holding map busy*/ + unsigned int nbusy; /* [v] waiters for busy */ vaddr_t min_offset; /* [I] First address in map. */ vaddr_t max_offset; /* [I] Last address in map. */ @@ -324,7 +325,6 @@ struct vm_map { #define VM_MAP_INTRSAFE 0x02 /* ro: interrupt safe map */ #define VM_MAP_WIREFUTURE 0x04 /* rw: wire future mappings */ #define VM_MAP_BUSY 0x08 /* rw: map is busy */ -#define VM_MAP_WANTLOCK 0x10 /* rw: want to write-lock */ #define VM_MAP_GUARDPAGES 0x20 /* rw: add guard pgs to map */ #define VM_MAP_ISVMSPACE 0x40 /* ro: map is a vmspace */ #define VM_MAP_PINSYSCALL_ONCE 0x100 /* rw: pinsyscall done */