Subject: Re: fixing send(2) semantics (kern/29750)
To: Emmanuel Dreyfus <manu@netbsd.org>
From: Bill Studenmund <wrstuden@netbsd.org>
List: tech-kern
Date: 03/27/2005 20:56:03
--SkvwRMAIpAhPCcCJ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Sun, Mar 27, 2005 at 08:37:38AM +0200, Emmanuel Dreyfus wrote:
> Jonathan Stone <jonathan@dsg.stanford.edu> wrote:
>=20
> > I think you'd be better off to fix your application, instead of
> > pursuing a (well-meant, but deeply misguided) attempt to "fix" the
> > BSD networking code.
>=20
> About fixing the app to workaround the current bhavior of send(2): I
> don't see any workaround for the problem at the application level. I'm
> interested if you have one.=20

Throttle your application. You need to try to send data at a specific=20
rate, which is chosen to suit your clients.

> The app needs to send UDP packets as fast as possible. I want to use the
> full network bandwidth for sending UDP packets. The only congestion that
> exists here is internal to the machine because the CPU can put more
> entries in the interface queue than the network can handle.

I know others have gone over this, but it's an important point. You are
assuming that the clients receive packets as fast as the sender sends
them, which isn't always true. So "as fast as possible" doesn't
necessarily mean "as fast as the NIC can."

> How can I fix the app? Without sleeping between sends, I get ENOBUFS, I
> have to retry the send, and that slows down the app enough so that it
> canot maintain the interface queue full, and thus it cannot use the full
> network bandwidth either.=20

Here's my suggestion:

1) Switch to kqueue
2) Add a kevent filter of type EVFILT_TIMER set for one ms.
3) Create a filter processor. This filter processor will get told
	how many ms have passed since its last call (in the 'data'
	field of the event).

A) Send X packets (about 12k bytes in this case) for each tick.

B) Keep a count of "bytes to send." For each tick, add X bytes. Then keep
sending packets as long as you have bytes (in the "count") to send. =20
Exactly what you do when your count isn't a full packet is a policy
decision (do you send until you don't have enough to send, or do you send
until you get a negative count), though it won't really matter after the
first tick.

This way, you will send data at the desired rate regardless of queue=20
status and without changing the kernel.

Take care,

Bill

--SkvwRMAIpAhPCcCJ
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (NetBSD)

iD8DBQFCR45jWz+3JHUci9cRAudHAJ0Yu8/RkqKIj2Qi4fFbGJVpFksk0wCeLGFo
CvUuKijFKW+s2y5Yonf0iSM=
=+L9R
-----END PGP SIGNATURE-----

--SkvwRMAIpAhPCcCJ--