Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Jun 1998 03:50:02 -0700 (PDT)
From:      Craig Metz <cmetz@inner.net>
To:        freebsd-bugs@FreeBSD.ORG
Subject:   Re: kern/6837: in_setpeeraddr() and in_setsockaddr() block on memory 
Message-ID:  <199806031050.DAA21239@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/6837; it has been noted by GNATS.

From: Craig Metz <cmetz@inner.net>
To: dg@root.com
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: kern/6837: in_setpeeraddr() and in_setsockaddr() block on memory 
Date: Wed, 03 Jun 1998 06:37:39 -0300

 In message <199806030337.UAA19868@implode.root.com>, you write:
 >>These two functions now MALLOC their address parameter inline rather
 >>than having the address buffer passed in. They do so with M_WAITOK,
 >>which will tsleep() the process indefinitely waiting for the memory.
 >>Granted, if you're that short on memory on a BSD system, you'll have
 >>bigger problems, but IMO these functions should kick ENOBUFS back up the
 >>stack and get out of kernel mode (thus freeing up some other buffer
 >>memory) rather than block the process.
 >
 >   Why do you think it should be that way? It won't be an indefinate wait,
 >just a wait until memory is freed up which shouldn't be for very long.
 
   I guess it's a bit of a philosophical thing.
 
   If you return ENOBUFS, the app is able to choose what it does about not
 having enough memory to complete the operation. Most will quit, thus freeing up
 the memory associated with them and helping the global out-of-memory problem
 (even if kernel memory is a separate pool, there's almost always some kernel
 memory associated with the process). Some will back out transactions, or return
 a network failure, or sleep/spin for a while and then try again. But that way,
 a well-written app has the choice.
 
   If you do it M_WAIT style, the kernel tsleep()s the process, and the app
 doesn't have any choice. It sleeps, possibly for a long time. By the time it
 wakes up, given many typical places where getpeername()/getsockname() are used,
 the returned value will be irrelevant.
 
   Consider the case that so many people break^H^H^H^H^Hdesign their operating
 systems for these days, the web. WWW servers typically call getpeername() and
 getsockname() early in an incoming connection. If the call fails, the server
 can close the connection, freeing up some kernel memory, and the client will
 usually return an error. If the call sleeps, the connection will hang, and the
 client will simply retry. If I'm not mistaken, unless it's doing asynchronous
 I/O, the process won't be awakened by the connection close event, so it sits
 there until memory becomes available, holding some itself. Meanwhile, the
 client is firing off a new TCP connection and causing another getpeername()/
 getsockname() call, which may be able to grab newly-freed memory before the
 first process can wake up.
 
   The other, far easier to explain answer, is that we're putting some code in
 there for IPv6 support that makes the malloc() happen at splnet(), and
 tsleep()ing at such a priority is not good.
 
 									-Craig

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199806031050.DAA21239>