Yes, this is much better. although I think this problem related to big mmaps has been with us for a while.
and appears to avoid the problem with the offending test programs on my machines. I'm ok with that going in for the moment, although I want some of your time to look at that nasty shit we talked about :) I think we can make that a lot better with some NOCACHE.. On Wed, Feb 5, 2014 at 9:03 PM, Ted Unangst <t...@tedunangst.com> wrote: > On Wed, Feb 05, 2014 at 17:53, Bob Beck wrote: >> On Wed, Feb 5, 2014 at 3:17 PM, Ted Unangst <t...@tedunangst.com> wrote: >>> We are missing back pressure channels from uvm to the buf cache. The >>> buf cache will happily sit on 9000 free pages while uvm churns around >>> trying to scavenge up one more page. > >> Or are you in a situation here where the cache has *not* backed off? > > Talked to Bob and hashed out better ideas of the problem. The page > daemon does tell the buffer cache to make some room, but... > > If you have a huge mmap file, the pdaemon will try to flush it out via > VOP_WRITE, which circles back via ffs into buf_get, which eats those > previously freed pages, and then some, as the pagedaemon continues > pushing more and more of the mmap file out. > > We discussed some other changes and fixes that this situation has > clearly highlighted, but here's a slightly revised diff. It now uses > the correct bufbackoff() function to communicate uvm's needs. Any > other fix is rather precarious for this release, but as stated before, > this keeps the change to the deadlock paths. You were already dead, > but now you have a second chance. > > (We don't currently use the pmemrange argument; we'll have to adjust > accordingly when the bufcache becomes range aware.) > > Index: uvm_pdaemon.c > =================================================================== > RCS file: /cvs/src/sys/uvm/uvm_pdaemon.c,v > retrieving revision 1.64 > diff -u -p -r1.64 uvm_pdaemon.c > --- uvm_pdaemon.c 30 May 2013 16:29:46 -0000 1.64 > +++ uvm_pdaemon.c 6 Feb 2014 03:09:53 -0000 > @@ -117,6 +117,8 @@ uvm_wait(const char *wmsg) > */ > > if (curproc == uvm.pagedaemon_proc) { > + if (bufbackoff(NULL, 4) == 0) > + return; > /* > * now we have a problem: the pagedaemon wants to go to > * sleep until it frees more memory. but how can it > Index: uvm_pmemrange.c > =================================================================== > RCS file: /cvs/src/sys/uvm/uvm_pmemrange.c,v > retrieving revision 1.36 > diff -u -p -r1.36 uvm_pmemrange.c > --- uvm_pmemrange.c 29 Jan 2013 19:55:48 -0000 1.36 > +++ uvm_pmemrange.c 6 Feb 2014 03:10:32 -0000 > @@ -22,6 +22,7 @@ > #include <sys/malloc.h> > #include <sys/proc.h> /* XXX for atomic */ > #include <sys/kernel.h> > +#include <sys/mount.h> > > /* > * 2 trees: addr tree and size tree. > @@ -1883,6 +1884,13 @@ uvm_wait_pla(paddr_t low, paddr_t high, > const char *wmsg = "pmrwait"; > > if (curproc == uvm.pagedaemon_proc) { > + uvm_unlock_fpageq(); > + if (bufbackoff(NULL, atop(size)) == 0) { > + uvm_lock_fpageq(); > + return 0; > + } > + uvm_lock_fpageq(); > + > /* > * XXX detect pagedaemon deadlock - see comment in > * uvm_wait(), as this is exactly the same issue.