From 50f3447786e09bb6c7bc4255c01a7339193a66a0 Mon Sep 17 00:00:00 2001
From: Hang Su <darcy.sh@antfin.com>
Date: Tue, 30 Jul 2019 10:53:55 +0800
Subject: Combine multiple epoll events copies

Allocate a larger memory buffer and combine multiple copies into one copy,
to reduce the number of copies from kernel memory to user memory.

Signed-off-by: Hang Su <darcy.sh@antfin.com>
---
 pkg/sentry/syscalls/linux/sys_epoll.go | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

(limited to 'pkg/sentry/syscalls')

diff --git a/pkg/sentry/syscalls/linux/sys_epoll.go b/pkg/sentry/syscalls/linux/sys_epoll.go
index 4a2b9f061..65b4a227b 100644
--- a/pkg/sentry/syscalls/linux/sys_epoll.go
+++ b/pkg/sentry/syscalls/linux/sys_epoll.go
@@ -107,19 +107,20 @@ func EpollCtl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc
 // copyOutEvents copies epoll events from the kernel to user memory.
 func copyOutEvents(t *kernel.Task, addr usermem.Addr, e []epoll.Event) error {
 	const itemLen = 12
-	if _, ok := addr.AddLength(uint64(len(e)) * itemLen); !ok {
+	buffLen := len(e) * itemLen
+	if _, ok := addr.AddLength(uint64(buffLen)); !ok {
 		return syserror.EFAULT
 	}
 
-	b := t.CopyScratchBuffer(itemLen)
+	b := t.CopyScratchBuffer(buffLen)
 	for i := range e {
-		usermem.ByteOrder.PutUint32(b[0:], e[i].Events)
-		usermem.ByteOrder.PutUint32(b[4:], uint32(e[i].Data[0]))
-		usermem.ByteOrder.PutUint32(b[8:], uint32(e[i].Data[1]))
-		if _, err := t.CopyOutBytes(addr, b); err != nil {
-			return err
-		}
-		addr += itemLen
+		usermem.ByteOrder.PutUint32(b[i*itemLen:], e[i].Events)
+		usermem.ByteOrder.PutUint32(b[i*itemLen+4:], uint32(e[i].Data[0]))
+		usermem.ByteOrder.PutUint32(b[i*itemLen+8:], uint32(e[i].Data[1]))
+	}
+
+	if _, err := t.CopyOutBytes(addr, b); err != nil {
+		return err
 	}
 
 	return nil
-- 
cgit v1.2.3