From: Martin Pieuchot Subject: Re: pdaemon, interrupts and ci_idepth To: Mark Kettenis Cc: tech@openbsd.org Date: Sat, 2 Nov 2024 09:51:03 +0100 On 22/10/24(Tue) 21:01, Mark Kettenis wrote: > > Date: Sat, 19 Oct 2024 15:23:32 +0200 > > From: Martin Pieuchot > > > > When a system is OOM and has only its reserved pages available, it is > > not helpful to let interrupt handlers steal such memory from the page > > daemon. > > > > I've seen iwm(4)'s interrupt handler allocate memory reserved for the > > pagedaemon because checking against `curproc' is not good enough. So > > the diff below use the MD `ci_idepth' variable to prevent such scenario. > > If this is acceptable, I'd be happy to rename `ci_intrdepth' used by > > some architectures to `ci_idepth'. > > > > Ok? > > Yes, this makes sense. But this does require some MD work first. > > Also I wonder if it makes sense to abstract the > > (curproc == uvm.pagedaemon_proc && curcpu()->ci_idepth == 0) > > and > > (curproc == syncerproc && curcpu()->ci_idepth == 0) > > conditions into inline functions, such that that first multi-line > condition becomes a bit easier to understand... Here's where I am now. sparc64 and landisk still lack `ci_idepth'. The last chunk is for correctness and might find unexpected bugs. Index: uvm/uvm_pmemrange.c =================================================================== RCS file: /cvs/src/sys/uvm/uvm_pmemrange.c,v diff -u -p -r1.68 uvm_pmemrange.c --- uvm/uvm_pmemrange.c 2 Oct 2024 10:17:28 -0000 1.68 +++ uvm/uvm_pmemrange.c 2 Nov 2024 08:48:05 -0000 @@ -81,6 +81,20 @@ int uvm_pmr_pg_to_memtype(struct vm_page void uvm_pmr_print(void); #endif +static inline int +in_pagedaemon(int allowsyncer) +{ +#if !defined(__sparc64__) && !defined(__landisk__) + if (curcpu()->ci_idepth > 0) + return 0; +#endif + if (curproc == uvm.pagedaemon_proc) + return 1; + if (allowsyncer && (curproc == syncerproc)) + return 1; + return 0; +} + /* * Memory types. The page flags are used to derive what the current memory * type of a page is. @@ -967,7 +981,7 @@ again: } if ((uvmexp.free <= (uvmexp.reserve_pagedaemon + count)) && - (curproc != uvm.pagedaemon_proc) && (curproc != syncerproc)) { + !in_pagedaemon(1)) { uvm_unlock_fpageq(); if (flags & UVM_PLA_WAITOK) { uvm_wait("uvm_pmr_getpages"); @@ -2094,6 +2108,10 @@ uvm_wait_pla(paddr_t low, paddr_t high, { struct uvm_pmalloc pma; const char *wmsg = "pmrwait"; + +#if !defined(__sparc64__) && !defined(__landisk__) + KASSERT(curcpu()->ci_idepth == 0); +#endif if (curproc == uvm.pagedaemon_proc) { /*