From cd6f26290a1d679f454aab6567ce5971b699721e Mon Sep 17 00:00:00 2001 From: mpi Date: Mon, 30 Aug 2021 16:59:17 +0000 Subject: [PATCH] Fix a locking assertion in error path. In amap_copy() make the new amap share the source amap's lock right in the begining and only allocate a new one if no anon have been referenced. Issue reported by Thomas L. on bugs@. ok tb@ --- sys/uvm/uvm_amap.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/sys/uvm/uvm_amap.c b/sys/uvm/uvm_amap.c index f5076a5c350..39c58fde83a 100644 --- a/sys/uvm/uvm_amap.c +++ b/sys/uvm/uvm_amap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_amap.c,v 1.89 2021/03/26 13:40:05 mpi Exp $ */ +/* $OpenBSD: uvm_amap.c,v 1.90 2021/08/30 16:59:17 mpi Exp $ */ /* $NetBSD: uvm_amap.c,v 1.27 2000/11/25 06:27:59 chs Exp $ */ /* @@ -618,6 +618,13 @@ amap_copy(struct vm_map *map, struct vm_map_entry *entry, int waitf, return; srcamap = entry->aref.ar_amap; + /* + * Make the new amap share the source amap's lock, and then lock + * both. + */ + amap->am_lock = srcamap->am_lock; + rw_obj_hold(amap->am_lock); + amap_lock(srcamap); /* @@ -655,7 +662,7 @@ amap_copy(struct vm_map *map, struct vm_map_entry *entry, int waitf, chunk = amap_chunk_get(amap, lcv, 1, PR_NOWAIT); if (chunk == NULL) { - amap_unlock(srcamap); + /* amap_wipeout() releases the lock. */ amap->am_ref = 0; amap_wipeout(amap); return; @@ -695,10 +702,10 @@ amap_copy(struct vm_map *map, struct vm_map_entry *entry, int waitf, * If we referenced any anons, then share the source amap's lock. * Otherwise, we have nothing in common, so allocate a new one. */ - KASSERT(amap->am_lock == NULL); - if (amap->am_nused != 0) { - amap->am_lock = srcamap->am_lock; - rw_obj_hold(amap->am_lock); + KASSERT(amap->am_lock == srcamap->am_lock); + if (amap->am_nused == 0) { + rw_obj_free(amap->am_lock); + amap->am_lock = NULL; } amap_unlock(srcamap); -- 2.20.1