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.

Reply via email to