interesting kernel discussion

"Peter T. Breuer" <[email protected]> Mon, 14 Aug 2006 13:40:07 +0200 (MET DST)
Newsgroups gmane.linux.enbd.general
Message-ID <[email protected]>
There's a relevant, even interesting, discussion going on on LKML:

  Subject: Re: [RFC][PATCH 2/9] deadlock prevention core

  Peter Zijlstra <[email protected]>

  Newsgroups:
  gmane.linux.network,gmane.linux.kernel.mm,gmane.linux.kernel

  On Sun, 2006-08-13 at 18:53 -0700, Andrew Morton wrote:
  > On Sun, 13 Aug 2006 18:31:14 -0700
  > Daniel Phillips <[email protected]> wrote:
  >
  > > But to solve the whole problem
  >
  > What problem?  Has anyone come up with a testcase which others can
  > reproduce?

  Problem:

  Networked Block devices (NBD, iSCSI, AoE) can deadlock in the
  following manner:
  deplete normal memory because of memory pressure; deplete reserves by
  writeout over network (pageout happens under PF_MEMALLOC), little to no
  memory left for receiving those now crucial ACK packets.
  A few packets could still fit in memory, but are quickly gobbled up by
  non-crucial sockets and are left waiting on blocked user-space
  processes. All memory is depleted and progress stalled forever.

  (This affects swap and shared mmap)


I've always said that there is a problem with memory deadlock in the
socket layer in the kernel for remote devices, no matter what people say ..
(there was a time when it was claimed fixed by giving memory priority
to networking).  The above (PZ's) is merely a more or less generic
statement of what might go wrong and I'm neither convinced nor
unconvinced by the scenario depicted ... namely that when we run out 
of memory buffers we can't get any memory for tcp sockets in order
to push data out to the remote device (which might liberate memory
and get us out of the hole). The correct solution is to reserve memory
for the socket being used _in advance_. Or at least not start to send a
packet until a promise has been received that we have enough memory to
send it out with.

PZ says much the same:


  Our Solution:

  Mark some sockets with SOCK_MEMALLOC; which is essentially a promise to
  never block. When under memory pressure only deliver packets to these
  sockets, memory will still be used but never lost waiting on a blocked
  user space process.

  Also make sure the reserve is large enough so that writeout will never
  be able to completely deplete it.

  (It is here I still do not see Evgeniy's Network Tree Allocator work;
  where is the guarantee that you do not end up with all memory lost
  waiting on blocked sockets?)

This would fix things, I think, but it's not quite what I said. I said
let sends "always succeed" (at least in getting to the transmitting
device), and he says let sends "fail at once if they are going to fail".

If that's accepted in-kernel, I will add it to the socket options in
enbd LIKE A SHOT.

Peter