Index | Thread | Search

From:
Kirill A. Korinsky <kirill@korins.ky>
Subject:
Re: sys/uvm: avoid waiting with the object lock held in uvn_get()
To:
Mark Kettenis <mark.kettenis@xs4all.nl>
Cc:
tech@openbsd.org
Date:
Sat, 08 Aug 2026 21:03:36 +0200

Download raw body.

Thread
On Sat, 08 Aug 2026 20:39:53 +0200,
Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
> 
> > Date: Sat, 08 Aug 2026 20:05:30 +0200
> > From: Kirill A. Korinsky <kirill@korins.ky>
> > 
> > tech@,
> > 
> > uvm_wait() requires all locks to be released, but uvn_get() calls it with
> > uobj->vmobjlock held when uvm_pagealloc() fails. The page daemon may need
> > this lock to reclaim the object's pages; waiting for free memory while
> > retaining it can ends with deadlock.
> > 
> > Dropping and reacquiring the lock around uvm_wait() is not safe either: the
> > fault maps are already unlocked, so the mapping and vnode object state may
> > change while the thread sleeps.
> > 
> > So, eelease vmobjlock and return VM_PAGER_AGAIN instead; the fault handler
> > backs off, restarts the fault, and revalidates its state before retrying
> > again.
> > 
> > Ok?
> 
> The problem with that strategy is that it may result in us faulting in
> a tight loop, preventing the system from making much progress.
> 
> Maybe it is better to release the lock, call uvm_wait(), and then
> return VM_PAGER_AGAIN?
> 

What actually make perfect sense.

We know that here no memory, so, we uvm_wait(), and only after that, let
return to the caller to revalidate the state.

Thanks!

Ok?

gIndex: sys/uvm/uvm_vnode.c
===================================================================
RCS file: /home/cvs/src/sys/uvm/uvm_vnode.c,v
diff -u -p -r1.151 uvm_vnode.c
--- sys/uvm/uvm_vnode.c	29 Dec 2025 16:07:14 -0000	1.151
+++ sys/uvm/uvm_vnode.c	8 Aug 2026 18:55:03 -0000
@@ -1029,10 +1029,9 @@ uvn_get(struct uvm_object *uobj, voff_t 
 
 				/* out of RAM? */
 				if (ptmp == NULL) {
+					rw_exit(uobj->vmobjlock);
 					uvm_wait("uvn_getpage");
-
-					/* goto top of pps while loop */
-					continue;
+					return VM_PAGER_AGAIN;
 				}
 
 				/*


-- 
wbr, Kirill