Index | Thread | Search

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

Download raw body.

Thread
> 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?


> Index: 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 17:52:53 -0000
> @@ -1029,10 +1029,8 @@ uvn_get(struct uvm_object *uobj, voff_t 
>  
>  				/* out of RAM? */
>  				if (ptmp == NULL) {
> -					uvm_wait("uvn_getpage");
> -
> -					/* goto top of pps while loop */
> -					continue;
> +					rw_exit(uobj->vmobjlock);
> +					return VM_PAGER_AGAIN;
>  				}
>  
>  				/*
> 
> -- 
> wbr, Kirill
> 
>