Date: Sun, 03 Dec 2000 16:26:26 -0500 (EST) From: Bosko Milekic <bmilekic@technokratis.com> To: Terry Lambert <tlambert@primenet.com> Cc: dg@root.com, Andrew Gallatin <gallatin@cs.duke.edu>, "Kenneth D. Merry" <ken@kdm.org>, arch@FreeBSD.ORG Subject: Re: zero copy code review Message-ID: <Pine.BSF.4.21.0012031610070.98081-100000@jehovah.technokratis.com> In-Reply-To: <200012032006.NAA00585@usr05.primenet.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 3 Dec 2000, Terry Lambert wrote:
[...]
> There's a real easy fix for this:
>
>
> m_get_not_broken( flag, type)
> int flag, type;
> {
> struct mbuf *m;
>
> do {
> m = m_get( flag, type);
> } while( flag == M_WAIT && m == NULL);
>
> return( m);
> }
>
> I think the idea that the M_WAIT flag should be broken so that
> it can be safely used in interrupt mode is dumb.
I'm not sure I understand what you're putting forward with the above
comment, specifically what you're referring to when you say "broken."
Are you trying to say that "M_WAIT is broken because it doesn't wait
forever?" If that's what you're trying to say, the explanation is simple.
If you "wait indefinetely," or spin as you're doing above, then what
you're doing is pretty much useless. Let me explain why and how you can
test my hypothesis without changing a single line of code.
First of all, the amount of time spent waiting with M_WAIT is
completely tunable with the kern.ipc.mbuf_wait sysctl. If you want to
wait indefinetely, just set it to 0.
Second of all, the default value is 32. The reason for that is that
it is typically sufficient if you're going to get anything in the first
place. Basically, if you're short on mbufs and you're hoping one will be
freed then, in the general case (I've established this through various
testing), on a relatively generic machine, with moderately heavy network
load, you're going to get one back within the 32 ticks. If it isn't
sufficient, you can tune from 32 to 64 to whatever it is you feel is
appropriate. The only case where you won't be getting back what you need
in the default time, usually, is when the main mbuf consumer is a process
which is, in effect, sucking up all resources (allocating them for
itself) -- think local DoS. In that case, even after you wait 32 ticks,
64 ticks, or infinity ticks, you're likely to not get anything and even
if you happen to get ONE mbuf, then it's even worse 'cause all that's
happened is that the offending process has swallowed yet another mbuf and
prevented the other (essential) system components to allocate.
So, in the latter case, if you have a non-offending process calling
sendfile(2) and trying to allocate an mbuf, it can wait all day if you
want it to, and it will never get anything until the offending process is
killed. So, better to have the process return from the kernel and deal
with the temporary failure. The same goes for the offending process that
will keep exhausting mbufs in a tight loop; think of what would happen
once the offending process hits the hard limit and exhausts mbufs. It
will just be stuck waiting/looping indefinetely in the kernel and will
not be killable because it will not be able to receive any signals posted
to it until it returns from the kernel.
Basically, what I'm telling you is: M_WAIT behavior is not broken in
FreeBSD, it is entirely tunable and it is better, in the general case, to
NOT have M_WAIT mean 'wait indefinetely.'
>
> Terry Lambert
> terry@lambert.org
> ---
> Any opinions in this posting are my own and not those of my present
> or previous employers.
Regards,
Bosko Milekic
bmilekic@technokratis.com
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0012031610070.98081-100000>
