diff options
author | Anton Blanchard <anton@samba.org> | 2011-05-02 16:21:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-05 14:10:14 -0400 |
commit | 228e548e602061b08ee8e8966f567c12aa079682 (patch) | |
tree | 4c79ecf071d6174d42da1557812a4646d0aaa5af /net/compat.c | |
parent | 1c5cae815d19ffe02bdfda1260949ef2b1806171 (diff) |
net: Add sendmmsg socket system call
This patch adds a multiple message send syscall and is the send
version of the existing recvmmsg syscall. This is heavily
based on the patch by Arnaldo that added recvmmsg.
I wrote a microbenchmark to test the performance gains of using
this new syscall:
http://ozlabs.org/~anton/junkcode/sendmmsg_test.c
The test was run on a ppc64 box with a 10 Gbit network card. The
benchmark can send both UDP and RAW ethernet packets.
64B UDP
batch pkts/sec
1 804570
2 872800 (+ 8 %)
4 916556 (+14 %)
8 939712 (+17 %)
16 952688 (+18 %)
32 956448 (+19 %)
64 964800 (+20 %)
64B raw socket
batch pkts/sec
1 1201449
2 1350028 (+12 %)
4 1461416 (+22 %)
8 1513080 (+26 %)
16 1541216 (+28 %)
32 1553440 (+29 %)
64 1557888 (+30 %)
We see a 20% improvement in throughput on UDP send and 30%
on raw socket send.
[ Add sparc syscall entries. -DaveM ]
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/compat.c')
-rw-r--r-- | net/compat.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/net/compat.c b/net/compat.c index 3649d5895361..c578d9382e19 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -722,11 +722,11 @@ EXPORT_SYMBOL(compat_mc_getsockopt); | |||
722 | 722 | ||
723 | /* Argument list sizes for compat_sys_socketcall */ | 723 | /* Argument list sizes for compat_sys_socketcall */ |
724 | #define AL(x) ((x) * sizeof(u32)) | 724 | #define AL(x) ((x) * sizeof(u32)) |
725 | static unsigned char nas[20] = { | 725 | static unsigned char nas[21] = { |
726 | AL(0), AL(3), AL(3), AL(3), AL(2), AL(3), | 726 | AL(0), AL(3), AL(3), AL(3), AL(2), AL(3), |
727 | AL(3), AL(3), AL(4), AL(4), AL(4), AL(6), | 727 | AL(3), AL(3), AL(4), AL(4), AL(4), AL(6), |
728 | AL(6), AL(2), AL(5), AL(5), AL(3), AL(3), | 728 | AL(6), AL(2), AL(5), AL(5), AL(3), AL(3), |
729 | AL(4), AL(5) | 729 | AL(4), AL(5), AL(4) |
730 | }; | 730 | }; |
731 | #undef AL | 731 | #undef AL |
732 | 732 | ||
@@ -735,6 +735,13 @@ asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, uns | |||
735 | return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); | 735 | return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); |
736 | } | 736 | } |
737 | 737 | ||
738 | asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, | ||
739 | unsigned vlen, unsigned int flags) | ||
740 | { | ||
741 | return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, | ||
742 | flags | MSG_CMSG_COMPAT); | ||
743 | } | ||
744 | |||
738 | asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) | 745 | asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) |
739 | { | 746 | { |
740 | return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); | 747 | return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); |
@@ -780,7 +787,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args) | |||
780 | u32 a[6]; | 787 | u32 a[6]; |
781 | u32 a0, a1; | 788 | u32 a0, a1; |
782 | 789 | ||
783 | if (call < SYS_SOCKET || call > SYS_RECVMMSG) | 790 | if (call < SYS_SOCKET || call > SYS_SENDMMSG) |
784 | return -EINVAL; | 791 | return -EINVAL; |
785 | if (copy_from_user(a, args, nas[call])) | 792 | if (copy_from_user(a, args, nas[call])) |
786 | return -EFAULT; | 793 | return -EFAULT; |
@@ -839,6 +846,9 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args) | |||
839 | case SYS_SENDMSG: | 846 | case SYS_SENDMSG: |
840 | ret = compat_sys_sendmsg(a0, compat_ptr(a1), a[2]); | 847 | ret = compat_sys_sendmsg(a0, compat_ptr(a1), a[2]); |
841 | break; | 848 | break; |
849 | case SYS_SENDMMSG: | ||
850 | ret = compat_sys_sendmmsg(a0, compat_ptr(a1), a[2], a[3]); | ||
851 | break; | ||
842 | case SYS_RECVMSG: | 852 | case SYS_RECVMSG: |
843 | ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]); | 853 | ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]); |
844 | break; | 854 | break; |