Re: sendmmsg() Expected Behavior?

2014-10-24 Thread Valdis . Kletnieks
On Thu, 23 Oct 2014 23:41:41 -0400, valdis.kletni...@vt.edu said:

 Why were you expecting recvmsg() to return more than one message?

Bah. Ignore that.  you said recvmmsg() with *two* m's.


pgpYuxOQ9HTPG.pgp
Description: PGP signature
___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


sendmmsg() Expected Behavior?

2014-10-23 Thread Hei Chan
Hi,

I am on CentOS 6.5 with kernel version kernel-2.6.32-431.el6.

I was trying to find the implementation of recvmmsg(), and hopefully, I am not 
looking at the wrong source 
~/rpmbuild/BUILD/kernel-2.6.32-431.el6/linux-2.6.32-431.el6.x86_64/net/socket.c.
 If I am, please kindly point me to the right source.

int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
   unsigned int flags, struct timespec *timeout)
{
int fput_needed, err, datagrams;
struct socket *sock;
struct mmsghdr __user *entry;
struct compat_mmsghdr __user *compat_entry;
struct msghdr msg_sys;
struct timespec end_time;

if (timeout 
poll_select_set_timeout(end_time, timeout-tv_sec,
timeout-tv_nsec))
return -EINVAL;

datagrams = 0;

sock = sockfd_lookup_light(fd, err, fput_needed);
if (!sock)
return err;

err = sock_error(sock-sk);
if (err)
goto out_put;

entry = mmsg;
compat_entry = (struct compat_mmsghdr __user *)mmsg;

while (datagrams  vlen) {
/*
 * No need to ask LSM for more than the first datagram.
 */
if (MSG_CMSG_COMPAT  flags) {
err = __sys_recvmsg(sock, (struct msghdr __user 
*)compat_entry,
msg_sys, flags, datagrams);
if (err  0)
break;
err = __put_user(err, compat_entry-msg_len);
++compat_entry;
} else {
err = __sys_recvmsg(sock, (struct msghdr __user *)entry,
msg_sys, flags, datagrams);
if (err  0)
break;
err = put_user(err, entry-msg_len);
++entry;
}

if (err)
break;
++datagrams;

if (timeout) {
ktime_get_ts(timeout);
*timeout = timespec_sub(end_time, *timeout);
if (timeout-tv_sec  0) {
timeout-tv_sec = timeout-tv_nsec = 0;
break;
}

/* Timeout, return less than vlen datagrams */
if (timeout-tv_nsec == 0  timeout-tv_sec == 0)
break;
}

/* Out of band data, return right away */
if (msg_sys.msg_flags  MSG_OOB)
break;
}

out_put:
fput_light(sock-file, fput_needed);

if (err == 0)
return datagrams;

if (datagrams != 0) {
/*
 * We may return less entries than requested (vlen) if the
 * sock is non block and there aren't enough datagrams...
 */
if (err != -EAGAIN) {
/*
 * ... or  if recvmsg returns an error after we
 * received some datagrams, where we record the
 * error to return on the next call or if the
 * app asks about it using getsockopt(SO_ERROR).
 */
sock-sk-sk_err = -err;
}

return datagrams;
}

return err;
}

Let's say there are 2 packets at the socket, and I try:

timespec t = {0, 0};
recvmmsg(fd, mmsg, vlen, 0, t);

Then, because of these lines:

if (timeout-tv_nsec == 0  timeout-tv_sec == 0)
break;

recvmmsg() will just return 1 packet instead of 2. Am I right?

It seems defecting the one of the main purposes of recvmmsg() -- trying to 
reduce # of system calls when there are packet queued.

Maybe I miss something?

I created a small test case that it waits for epoll callback, sleeps for 2-5 
seconds and then calls recvmmsg() with timeout=0 (not null; just like above).

Then, I found that recvmmsg() doesn't return all the packets that queued in 1 
single call.

___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


Re: sendmmsg() Expected Behavior?

2014-10-23 Thread Valdis . Kletnieks
On Thu, 23 Oct 2014 19:43:07 -0700, Hei Chan said:

 Then, I found that recvmmsg() doesn't return all the packets that queued in 1
 single call.

You want to receive *all* of them?  Call recv() with a *buf and a len
big enough to get a *lot* of msgs, and pass MSG_ALL in the flags.

Why were you expecting recvmsg() to return more than one message?



pgpImNQccMDXF.pgp
Description: PGP signature
___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


Re: sendmmsg() Expected Behavior?

2014-10-23 Thread Hei Chan
First of all, I apologize for the wrong subject.  It should be recvmmsg() not 
sendmmsg().

Based on the source code (in my previous email), it doesn't seem like MSG_ALL 
has any effect (I don't know MSG_ALL exists either).

Yes, I expect (or at least wish) recvmmsg() will return as many packet as 
possible before timeout, and if timeout is zero, it should keep trying to fill 
up the buffer until it is full or there is no more packet.

The reason I expect or wish such behavior is that the main idea behind 
recvmmsg() is that application can reduce the number system call, and so the 
throughput will go up and latency will go down.

Otherwise, the user could just simply use recvmsg() to mimic what recvmmsg() is 
doing.

I don't expect recvmsg() returns more than 1 message but I do expect and wish 
recvmmsg() returns more than 1 message.




On Friday, October 24, 2014 11:41 AM, valdis.kletni...@vt.edu 
valdis.kletni...@vt.edu wrote:
On Thu, 23 Oct 2014 19:43:07 -0700, Hei Chan said:




 Then, I found that recvmmsg() doesn't return all the packets that queued in 1
 single call.

You want to receive *all* of them?  Call recv() with a *buf and a len
big enough to get a *lot* of msgs, and pass MSG_ALL in the flags.

Why were you expecting recvmsg() to return more than one message?


___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies