Subject: Re: [RFC 1/2] net: Introduce recvmmsg socket syscall

From: Arnaldo Carvalho de Melo <[email-masked]>
Date: Thu, 21 May 2009 13:55:15 -0300

Em Thu, May 21, 2009 at 09:38:47AM -0700, Caitlin Bestler escreveu:
> > +
> > +       while (datagrams < vlen) {
> > +               err = __sys_recvmsg(sock, (struct msghdr __user *)entry, flags);
> > +               if (err < 0)
> > +                       goto out_put;
> > +               err = __put_user(err, &entry->msg_len);
> > +               if (err)
> > +                       goto out_put;
> > +               ++entry;
> > +               ++datagrams;
> > +       }
> >  out_put:
> >        fput_light(sock->file, fput_needed);
> >  out:
> > +       /*
> > +        * We may return less entries than requested (vlen) if the
> > +        * sock is non block and there aren't enough datagrams.
> > +        */
> > +       if (err == 0 || (err == -EAGAIN && (flags & MSG_DONTWAIT)))
> > +               return datagrams;
> >        return err;
> >  }
> >
 
> There is an assumption here that unless MSG_DONTWAIT is set, or there
> is an error, that the caller will be willing to wait indefinitely for
> N messages to show up -- and that it is never worth waking up the
> caller earlier with less than N messages.
 
> I think an application would more typically want to wait at most m
> msecs after the first message is received to see if any other messages
> can be delivered at the same time.

> A busy server could simply use DONTWAIT in a polling loop every cycle,
> but it would be nice to be able to wait indefinitely for *any* of your
> clients to send you a message.
 
> Further, with some sockets there are some messages that are more equal
> than others.

> Although valid messages, with no errors, they should be delivered to
> user-mode immediately.

> The example that leaps to my mind immediately are SCTP Events,
> particularly with one-to-many sockets. You could be waiting for N
> messages, knowing that a specific peer has been asked to send N
> messages. The 2nd message could be an SCTP event announcing that the
> specific association has been torn down (and hence the remaining
> messages will not be arriving).  Waiting for a different association
> to send enough messages to complete the request will not provide very
> prompt service.

Good points, that will require some sort of change to sk->sk_rcvtimeo
handling so that the timeout for each datagram are deduced from the
configured timeout for the socket, so that the existing code doesn't
have to be changed.

I.e. recvmmsg would save the value of sk->sk_rcvtimeo at entry and
restore at exit, and would somehow go on subtracting the time
sock_recvmsg() took from it so that the following call finds a reduced
sk->sk_rcvtimeo iif it was configured in the first place and the socket
is in blocking mode.

How does that sound?

- Arnaldo