Re: sys/uvm: unwind failed amap copies

Kirill A. Korinsky <[email protected]>
Newsgroups gmane.os.openbsd.tech
Message-ID <[email protected]>
On Sat, 08 Aug 2026 15:55:04 +0200,
Mark Kettenis <[email protected]> wrote:
> 
> > Date: Mon, 03 Aug 2026 01:23:08 +0200
> > From: Kirill A. Korinsky <[email protected]>
> 
> Hi Kirill,
> 
> > 
> > tech@,
> > 
> > I continue my hunt on hangs and crashes at my very small octeon.
> > 
> > Here the second finding from that a few days long sprint.
> > 
> > A PR_NOWAIT chunk allocation in amap_copy() may fail after earlier
> > chunks already contain copied anons; amap_free() requires an empty amap,
> > so direct cleanup trips its diagnostic assertion or leaves copied anon
> > references orphaned which may end who knows how.
> > 
> > Here, I use amap_wipeout() instead to reverse the partial copy, release
> > the shared lock, and free the temporary amap.
> > 
> > Thought?
> > 
> > Index: sys/uvm/uvm_amap.c
> > ===================================================================
> > RCS file: /home/cvs/src/sys/uvm/uvm_amap.c,v
> > diff -u -p -r1.99 uvm_amap.c
> > --- sys/uvm/uvm_amap.c	18 Jun 2026 13:14:26 -0000	1.99
> > +++ sys/uvm/uvm_amap.c	2 Aug 2026 23:08:35 -0000
> > @@ -640,10 +640,8 @@ amap_copy(struct vm_map *map, struct vm_
> >  
> >  		chunk = amap_chunk_get(amap, lcv, 1, PR_NOWAIT);
> >  		if (chunk == NULL) {
> > -			amap_unlock(srcamap);
> > -			/* Destroy the new amap. */
> > -			amap->am_ref--;
> > -			amap_free(amap);
> > +			amap->am_ref = 0;
> 
> Why do you set am_ref to zero here instead of just decreasing it?
> 

Well, we shouldn't be here with am_ref not 1 as far as I understand the
code, and that am_ref-- was a bit missleading.

But after think more, I see that it is bad idea to replace it to 0.

We shouldn't be here with am_ref non 1 never means that we actually won't be
here, and if we here with am_ref not 1, am_ref-- makes am_ref not 0 and it
will crash inside amap_wipeout() at KASSERT(amap->am_ref == 0).

So, here cleaner diff.

Ok?

Index: sys/uvm/uvm_amap.c
===================================================================
RCS file: /home/cvs/src/sys/uvm/uvm_amap.c,v
diff -u -p -r1.99 uvm_amap.c
--- sys/uvm/uvm_amap.c	18 Jun 2026 13:14:26 -0000	1.99
+++ sys/uvm/uvm_amap.c	8 Aug 2026 17:05:19 -0000
@@ -640,10 +640,9 @@ amap_copy(struct vm_map *map, struct vm_
 
 		chunk = amap_chunk_get(amap, lcv, 1, PR_NOWAIT);
 		if (chunk == NULL) {
-			amap_unlock(srcamap);
-			/* Destroy the new amap. */
+			/* amap_wipeout() releases the shared lock. */
 			amap->am_ref--;
-			amap_free(amap);
+			amap_wipeout(amap);
 			return;
 		}
 


-- 
wbr, Kirill
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.