Skip to content

Commit 228e548

Browse files
antonblancharddavem330
authored andcommitted
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>
1 parent 1c5cae8 commit 228e548

File tree

16 files changed

+192
-52
lines changed

16 files changed

+192
-52
lines changed

arch/powerpc/include/asm/systbl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,3 +352,4 @@ SYSCALL_SPU(name_to_handle_at)
352352
COMPAT_SYS_SPU(open_by_handle_at)
353353
COMPAT_SYS_SPU(clock_adjtime)
354354
SYSCALL_SPU(syncfs)
355+
COMPAT_SYS_SPU(sendmmsg)

arch/powerpc/include/asm/unistd.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,11 @@
371371
#define __NR_open_by_handle_at 346
372372
#define __NR_clock_adjtime 347
373373
#define __NR_syncfs 348
374+
#define __NR_sendmmsg 349
374375

375376
#ifdef __KERNEL__
376377

377-
#define __NR_syscalls 349
378+
#define __NR_syscalls 350
378379

379380
#define __NR__exit __NR_exit
380381
#define NR_syscalls __NR_syscalls

arch/sparc/include/asm/unistd.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,9 @@
404404
#define __NR_open_by_handle_at 333
405405
#define __NR_clock_adjtime 334
406406
#define __NR_syncfs 335
407+
#define __NR_sendmmsg 336
407408

408-
#define NR_syscalls 336
409+
#define NR_syscalls 337
409410

410411
#ifdef __32bit_syscall_numbers__
411412
/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,

arch/sparc/kernel/systbls_32.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,4 @@ sys_call_table:
8484
/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
8585
/*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
8686
/*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
87-
/*335*/ .long sys_syncfs
87+
/*335*/ .long sys_syncfs, sys_sendmmsg

arch/sparc/kernel/systbls_64.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ sys_call_table32:
8585
/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv
8686
.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init
8787
/*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime
88-
.word sys_syncfs
88+
.word sys_syncfs, compat_sys_sendmmsg
8989

9090
#endif /* CONFIG_COMPAT */
9191

@@ -162,4 +162,4 @@ sys_call_table:
162162
/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
163163
.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
164164
/*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
165-
.word sys_syncfs
165+
.word sys_syncfs, sys_sendmmsg

arch/x86/ia32/ia32entry.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,4 +848,5 @@ ia32_sys_call_table:
848848
.quad compat_sys_open_by_handle_at
849849
.quad compat_sys_clock_adjtime
850850
.quad sys_syncfs
851+
.quad compat_sys_sendmmsg /* 345 */
851852
ia32_syscall_end:

arch/x86/include/asm/unistd_32.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,10 +350,11 @@
350350
#define __NR_open_by_handle_at 342
351351
#define __NR_clock_adjtime 343
352352
#define __NR_syncfs 344
353+
#define __NR_sendmmsg 345
353354

354355
#ifdef __KERNEL__
355356

356-
#define NR_syscalls 345
357+
#define NR_syscalls 346
357358

358359
#define __ARCH_WANT_IPC_PARSE_VERSION
359360
#define __ARCH_WANT_OLD_READDIR

arch/x86/include/asm/unistd_64.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,8 @@ __SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at)
677677
__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime)
678678
#define __NR_syncfs 306
679679
__SYSCALL(__NR_syncfs, sys_syncfs)
680+
#define __NR_sendmmsg 307
681+
__SYSCALL(__NR_sendmmsg, sys_sendmmsg)
680682

681683
#ifndef __NO_STUBS
682684
#define __ARCH_WANT_OLD_READDIR

arch/x86/kernel/syscall_table_32.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,3 +344,4 @@ ENTRY(sys_call_table)
344344
.long sys_open_by_handle_at
345345
.long sys_clock_adjtime
346346
.long sys_syncfs
347+
.long sys_sendmmsg /* 345 */

include/linux/net.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#define SYS_RECVMSG 17 /* sys_recvmsg(2) */
4343
#define SYS_ACCEPT4 18 /* sys_accept4(2) */
4444
#define SYS_RECVMMSG 19 /* sys_recvmmsg(2) */
45+
#define SYS_SENDMMSG 20 /* sys_sendmmsg(2) */
4546

4647
typedef enum {
4748
SS_FREE = 0, /* not allocated */

include/linux/socket.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,5 +333,7 @@ struct timespec;
333333

334334
extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
335335
unsigned int flags, struct timespec *timeout);
336+
extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
337+
unsigned int vlen, unsigned int flags);
336338
#endif /* not kernel and not glibc */
337339
#endif /* _LINUX_SOCKET_H */

include/linux/syscalls.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,8 @@ asmlinkage long sys_send(int, void __user *, size_t, unsigned);
610610
asmlinkage long sys_sendto(int, void __user *, size_t, unsigned,
611611
struct sockaddr __user *, int);
612612
asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
613+
asmlinkage long sys_sendmmsg(int fd, struct mmsghdr __user *msg,
614+
unsigned int vlen, unsigned flags);
613615
asmlinkage long sys_recv(int, void __user *, size_t, unsigned);
614616
asmlinkage long sys_recvfrom(int, void __user *, size_t, unsigned,
615617
struct sockaddr __user *, int __user *);

include/net/compat.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ extern int compat_sock_get_timestampns(struct sock *, struct timespec __user *);
4343
extern int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *);
4444
extern int verify_compat_iovec(struct msghdr *, struct iovec *, struct sockaddr *, int);
4545
extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr __user *,unsigned);
46+
extern asmlinkage long compat_sys_sendmmsg(int, struct compat_mmsghdr __user *,
47+
unsigned, unsigned);
4648
extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned);
4749
extern asmlinkage long compat_sys_recvmmsg(int, struct compat_mmsghdr __user *,
4850
unsigned, unsigned,

kernel/sys_ni.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ cond_syscall(sys_getsockopt);
4646
cond_syscall(compat_sys_getsockopt);
4747
cond_syscall(sys_shutdown);
4848
cond_syscall(sys_sendmsg);
49+
cond_syscall(sys_sendmmsg);
4950
cond_syscall(compat_sys_sendmsg);
51+
cond_syscall(compat_sys_sendmmsg);
5052
cond_syscall(sys_recvmsg);
5153
cond_syscall(sys_recvmmsg);
5254
cond_syscall(compat_sys_recvmsg);

net/compat.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -722,11 +722,11 @@ EXPORT_SYMBOL(compat_mc_getsockopt);
722722

723723
/* Argument list sizes for compat_sys_socketcall */
724724
#define AL(x) ((x) * sizeof(u32))
725-
static unsigned char nas[20] = {
725+
static unsigned char nas[21] = {
726726
AL(0), AL(3), AL(3), AL(3), AL(2), AL(3),
727727
AL(3), AL(3), AL(4), AL(4), AL(4), AL(6),
728728
AL(6), AL(2), AL(5), AL(5), AL(3), AL(3),
729-
AL(4), AL(5)
729+
AL(4), AL(5), AL(4)
730730
};
731731
#undef AL
732732

@@ -735,6 +735,13 @@ asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, uns
735735
return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
736736
}
737737

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+
738745
asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
739746
{
740747
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)
780787
u32 a[6];
781788
u32 a0, a1;
782789

783-
if (call < SYS_SOCKET || call > SYS_RECVMMSG)
790+
if (call < SYS_SOCKET || call > SYS_SENDMMSG)
784791
return -EINVAL;
785792
if (copy_from_user(a, args, nas[call]))
786793
return -EFAULT;
@@ -839,6 +846,9 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
839846
case SYS_SENDMSG:
840847
ret = compat_sys_sendmsg(a0, compat_ptr(a1), a[2]);
841848
break;
849+
case SYS_SENDMMSG:
850+
ret = compat_sys_sendmmsg(a0, compat_ptr(a1), a[2], a[3]);
851+
break;
842852
case SYS_RECVMSG:
843853
ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]);
844854
break;

0 commit comments

Comments
 (0)