All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
To: Stefano Garzarella <sgarzare@redhat.com>,
	Stefan Hajnoczi <stefanha@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	Jason Wang <jasowang@redhat.com>,
	"David S. Miller" <davem@davemloft.net>,
	"edumazet@google.com" <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Krasnov Arseniy <oxffffaa@gmail.com>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"kvm@vger.kernel.org" <kvm@vger.kernel.org>,
	"virtualization@lists.linux-foundation.org" 
	<virtualization@lists.linux-foundation.org>,
	"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
	kernel <kernel@sberdevices.ru>
Subject: [RFC PATCH v3 10/11] test/vsock: add receive zerocopy tests
Date: Sun, 6 Nov 2022 19:51:55 +0000	[thread overview]
Message-ID: <c1f3ff9d-0386-fa8b-5660-e0c49991c4dc@sberdevices.ru> (raw)
In-Reply-To: <f60d7e94-795d-06fd-0321-6972533700c5@sberdevices.ru>

This adds tests for zerocopy feature: one test checks data transmission
with simple integrity control. Second test covers 'error' branches in
zerocopy logic(to check invalid arguments handling).

Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
---
 tools/include/uapi/linux/virtio_vsock.h   |  15 +
 tools/include/uapi/linux/vm_sockets.h     |   8 +
 tools/testing/vsock/Makefile              |   2 +-
 tools/testing/vsock/util.c                |  27 +-
 tools/testing/vsock/util.h                |   4 +
 tools/testing/vsock/vsock_test.c          |  21 +
 tools/testing/vsock/vsock_test_zerocopy.c | 530 ++++++++++++++++++++++
 tools/testing/vsock/vsock_test_zerocopy.h |  14 +
 8 files changed, 617 insertions(+), 4 deletions(-)
 create mode 100644 tools/include/uapi/linux/virtio_vsock.h
 create mode 100644 tools/include/uapi/linux/vm_sockets.h
 create mode 100644 tools/testing/vsock/vsock_test_zerocopy.c
 create mode 100644 tools/testing/vsock/vsock_test_zerocopy.h

diff --git a/tools/include/uapi/linux/virtio_vsock.h b/tools/include/uapi/linux/virtio_vsock.h
new file mode 100644
index 000000000000..f393062e0394
--- /dev/null
+++ b/tools/include/uapi/linux/virtio_vsock.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _UAPI_LINUX_VIRTIO_VSOCK_H
+#define _UAPI_LINUX_VIRTIO_VSOCK_H
+#include <linux/types.h>
+
+struct virtio_vsock_usr_hdr {
+	u32 flags;
+	u32 len;
+} __attribute__((packed));
+
+struct virtio_vsock_usr_hdr_pref {
+	u32 poll_value;
+	u32 hdr_num;
+} __attribute__((packed));
+#endif /* _UAPI_LINUX_VIRTIO_VSOCK_H */
diff --git a/tools/include/uapi/linux/vm_sockets.h b/tools/include/uapi/linux/vm_sockets.h
new file mode 100644
index 000000000000..cac0bc3a7041
--- /dev/null
+++ b/tools/include/uapi/linux/vm_sockets.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _UAPI_LINUX_VM_SOCKETS_H
+#define _UAPI_LINUX_VM_SOCKETS_H
+
+#define SO_VM_SOCKETS_MAP_RX 9
+#define SO_VM_SOCKETS_ZEROCOPY 10
+
+#endif /* _UAPI_LINUX_VM_SOCKETS_H */
diff --git a/tools/testing/vsock/Makefile b/tools/testing/vsock/Makefile
index f8293c6910c9..7172c21fbd8d 100644
--- a/tools/testing/vsock/Makefile
+++ b/tools/testing/vsock/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 all: test
 test: vsock_test vsock_diag_test
-vsock_test: vsock_test.o timeout.o control.o util.o
+vsock_test: vsock_test.o vsock_test_zerocopy.o timeout.o control.o util.o
 vsock_diag_test: vsock_diag_test.o timeout.o control.o util.o
 
 CFLAGS += -g -O2 -Werror -Wall -I. -I../../include -I../../../usr/include -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -D_GNU_SOURCE
diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index 351903836774..7ae5219d0fe8 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -84,7 +84,8 @@ void vsock_wait_remote_close(int fd)
 }
 
 /* Connect to <cid, port> and return the file descriptor. */
-static int vsock_connect(unsigned int cid, unsigned int port, int type)
+static int vsock_connect(unsigned int cid, unsigned int port, int type,
+			 int optname, void *optval, socklen_t optlen)
 {
 	union {
 		struct sockaddr sa;
@@ -103,6 +104,13 @@ static int vsock_connect(unsigned int cid, unsigned int port, int type)
 
 	fd = socket(AF_VSOCK, type, 0);
 
+	if (optval) {
+		if (setsockopt(fd, AF_VSOCK, optname, optval, optlen)) {
+			close(fd);
+			return -1;
+		}
+	}
+
 	timeout_begin(TIMEOUT);
 	do {
 		ret = connect(fd, &addr.sa, sizeof(addr.svm));
@@ -122,12 +130,25 @@ static int vsock_connect(unsigned int cid, unsigned int port, int type)
 
 int vsock_stream_connect(unsigned int cid, unsigned int port)
 {
-	return vsock_connect(cid, port, SOCK_STREAM);
+	return vsock_connect(cid, port, SOCK_STREAM, 0, NULL, 0);
+}
+
+int vsock_stream_connect_opt(unsigned int cid, unsigned int port,
+			     int optname, void *optval, socklen_t optlen)
+{
+	return vsock_connect(cid, port, SOCK_STREAM, optname, optval, optlen);
 }
 
 int vsock_seqpacket_connect(unsigned int cid, unsigned int port)
 {
-	return vsock_connect(cid, port, SOCK_SEQPACKET);
+	return vsock_connect(cid, port, SOCK_SEQPACKET, 0, NULL, 0);
+}
+
+int vsock_seqpacket_connect_opt(unsigned int cid, unsigned int port,
+				int optname, void *optval, socklen_t optlen)
+{
+	return vsock_connect(cid, port, SOCK_SEQPACKET, optname, optval,
+			     optlen);
 }
 
 /* Listen on <cid, port> and return the first incoming connection.  The remote
diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
index 988cc69a4642..23f9f0c6853d 100644
--- a/tools/testing/vsock/util.h
+++ b/tools/testing/vsock/util.h
@@ -36,7 +36,11 @@ struct test_case {
 void init_signals(void);
 unsigned int parse_cid(const char *str);
 int vsock_stream_connect(unsigned int cid, unsigned int port);
+int vsock_stream_connect_opt(unsigned int cid, unsigned int port,
+			     int optname, void *optval, socklen_t optlen);
 int vsock_seqpacket_connect(unsigned int cid, unsigned int port);
+int vsock_seqpacket_connect_opt(unsigned int cid, unsigned int port,
+				int optname, void *optval, socklen_t optlen);
 int vsock_stream_accept(unsigned int cid, unsigned int port,
 			struct sockaddr_vm *clientaddrp);
 int vsock_seqpacket_accept(unsigned int cid, unsigned int port,
diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
index bb4e8657f1d6..a6ed076e42f4 100644
--- a/tools/testing/vsock/vsock_test.c
+++ b/tools/testing/vsock/vsock_test.c
@@ -23,6 +23,7 @@
 #include "timeout.h"
 #include "control.h"
 #include "util.h"
+#include "vsock_test_zerocopy.h"
 
 static void test_stream_connection_reset(const struct test_opts *opts)
 {
@@ -904,6 +905,26 @@ static struct test_case test_cases[] = {
 		.run_client = test_stream_poll_rcvlowat_client,
 		.run_server = test_stream_poll_rcvlowat_server,
 	},
+	{
+		.name = "SOCK_STREAM zerocopy receive",
+		.run_client = test_stream_zerocopy_rx_client,
+		.run_server = test_stream_zerocopy_rx_server,
+	},
+	{
+		.name = "SOCK_SEQPACKET zerocopy receive",
+		.run_client = test_seqpacket_zerocopy_rx_client,
+		.run_server = test_seqpacket_zerocopy_rx_server,
+	},
+	{
+		.name = "SOCK_STREAM zerocopy receive loop poll",
+		.run_client = test_stream_zerocopy_rx_client_loop_poll,
+		.run_server = test_stream_zerocopy_rx_server_loop_poll,
+	},
+	{
+		.name = "SOCK_STREAM zerocopy invalid",
+		.run_client = test_stream_zerocopy_rx_inv_client,
+		.run_server = test_stream_zerocopy_rx_inv_server,
+	},
 	{},
 };
 
diff --git a/tools/testing/vsock/vsock_test_zerocopy.c b/tools/testing/vsock/vsock_test_zerocopy.c
new file mode 100644
index 000000000000..1876f14c0cec
--- /dev/null
+++ b/tools/testing/vsock/vsock_test_zerocopy.c
@@ -0,0 +1,530 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *
+ *
+ * Copyright (C) 2022 Sberdevices, Inc.
+ *
+ * Author: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <uapi/linux/virtio_vsock.h>
+#include <uapi/linux/vm_sockets.h>
+#include <sys/mman.h>
+#include <poll.h>
+#include <unistd.h>
+
+#include "timeout.h"
+#include "control.h"
+#include "util.h"
+#include "vsock_test_zerocopy.h"
+
+#define PAGE_SIZE	 4096
+#define RX_MAPPING_PAGES 3
+
+#define TX_BUF_SIZE	40000
+#define TX_SEND_LOOPS	3
+
+static void test_connectible_zerocopy_rx_client(const struct test_opts *opts,
+						bool stream)
+{
+	unsigned long remote_hash;
+	unsigned long curr_hash;
+	unsigned long total_sum;
+	unsigned long msg_bytes;
+	unsigned long zc_on;
+	size_t rx_map_len;
+	void *rx_va;
+	int fd;
+
+	zc_on = 1;
+
+	if (stream)
+		fd = vsock_stream_connect_opt(opts->peer_cid, 1234,
+					      SO_VM_SOCKETS_ZEROCOPY,
+					      (void *)&zc_on, sizeof(zc_on));
+	else
+		fd = vsock_seqpacket_connect_opt(opts->peer_cid, 1234,
+						 SO_VM_SOCKETS_ZEROCOPY,
+						 (void *)&zc_on, sizeof(zc_on));
+	if (fd < 0) {
+		perror("connect");
+		exit(EXIT_FAILURE);
+	}
+
+	rx_map_len = PAGE_SIZE * RX_MAPPING_PAGES;
+
+	rx_va = mmap(NULL, rx_map_len, PROT_READ, MAP_SHARED, fd, 0);
+	if (rx_va == MAP_FAILED) {
+		perror("mmap");
+		exit(EXIT_FAILURE);
+	}
+
+	total_sum = 0;
+	msg_bytes = 0;
+	curr_hash = 0;
+
+	while (1) {
+		struct pollfd fds = { 0 };
+		int leave_loop;
+		int res;
+
+		fds.fd = fd;
+		fds.events = POLLIN | POLLERR | POLLHUP |
+			     POLLRDHUP | POLLNVAL;
+
+		res = poll(&fds, 1, -1);
+
+		if (res < 0) {
+			perror("poll");
+			exit(EXIT_FAILURE);
+		}
+
+		if (fds.revents & POLLERR) {
+			perror("poll error");
+			exit(EXIT_FAILURE);
+		}
+
+		leave_loop = 0;
+
+		if (fds.revents & POLLIN) {
+			struct virtio_vsock_usr_hdr_pref *poll_hdr;
+			struct virtio_vsock_usr_hdr *data_hdr;
+			unsigned char *data_va;
+			unsigned char *end_va;
+			socklen_t len;
+			int hdr_cnt;
+
+			poll_hdr = (struct virtio_vsock_usr_hdr_pref *)rx_va;
+			len = sizeof(rx_va);
+
+			if (getsockopt(fd, AF_VSOCK,
+				       SO_VM_SOCKETS_MAP_RX,
+				       &rx_va, &len) < 0) {
+				perror("getsockopt");
+				exit(EXIT_FAILURE);
+			}
+
+			data_hdr = (struct virtio_vsock_usr_hdr *)(poll_hdr + 1);
+			/* Skip headers page for data. */
+			data_va = rx_va + PAGE_SIZE;
+			end_va = (unsigned char *)(rx_va + rx_map_len);
+			hdr_cnt = 0;
+
+			while (data_va != end_va) {
+				int data_len = data_hdr->len;
+
+				if (!data_hdr->len) {
+					if (fds.revents & (POLLHUP | POLLRDHUP) &&
+					    !hdr_cnt)
+						leave_loop = 1;
+
+					break;
+				}
+
+				while (data_len > 0) {
+					int i;
+					int to_read = (data_len < PAGE_SIZE) ?
+						       data_len : PAGE_SIZE;
+
+					for (i = 0; i < to_read; i++)
+						total_sum += data_va[i];
+
+					data_va += PAGE_SIZE;
+					data_len -= PAGE_SIZE;
+				}
+
+				if (!stream) {
+					msg_bytes += data_hdr->len;
+
+					if (data_hdr->flags) {
+						curr_hash += msg_bytes;
+						curr_hash = djb2(&curr_hash,
+								 sizeof(curr_hash));
+						msg_bytes = 0;
+					}
+				}
+
+				data_hdr++;
+				hdr_cnt++;
+			}
+
+			if (madvise((void *)rx_va,
+				    rx_map_len,
+				    MADV_DONTNEED)) {
+				perror("madvise");
+				exit(EXIT_FAILURE);
+			}
+
+			if (leave_loop)
+				break;
+		}
+	}
+
+	curr_hash += total_sum;
+	curr_hash = djb2(&curr_hash, sizeof(curr_hash));
+
+	if (munmap(rx_va, rx_map_len)) {
+		perror("munmap");
+		exit(EXIT_FAILURE);
+	}
+
+	remote_hash = control_readulong(NULL);
+
+	if (curr_hash != remote_hash) {
+		fprintf(stderr, "sum mismatch %lu != %lu\n",
+				curr_hash, remote_hash);
+		exit(EXIT_FAILURE);
+	}
+
+	close(fd);
+}
+
+void test_seqpacket_zerocopy_rx_client(const struct test_opts *opts)
+{
+	test_connectible_zerocopy_rx_client(opts, false);
+}
+
+void test_stream_zerocopy_rx_client(const struct test_opts *opts)
+{
+	test_connectible_zerocopy_rx_client(opts, true);
+}
+
+static void test_connectible_zerocopy_rx_server(const struct test_opts *opts,
+						bool stream)
+{
+	size_t max_buf_size = TX_BUF_SIZE;
+	unsigned long curr_hash;
+	long total_sum = 0;
+	int n = TX_SEND_LOOPS;
+	int fd;
+
+	if (stream)
+		fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
+	else
+		fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
+
+	if (fd < 0) {
+		perror("accept");
+		exit(EXIT_FAILURE);
+	}
+
+	curr_hash = 0;
+
+	while (n) {
+		unsigned char *data;
+		size_t send_size;
+		size_t buf_size;
+		int i;
+
+		buf_size = 1 + (rand() % max_buf_size);
+
+		data = malloc(buf_size);
+
+		if (!data) {
+			perror("malloc");
+			exit(EXIT_FAILURE);
+		}
+
+		for (i = 0; i < buf_size; i++) {
+			data[i] = rand() & 0xff;
+			total_sum += data[i];
+		}
+
+		send_size = write(fd, data, buf_size);
+
+		if (send_size != buf_size) {
+			perror("write");
+			exit(EXIT_FAILURE);
+		}
+
+		if (!stream) {
+			curr_hash += send_size;
+			curr_hash = djb2(&curr_hash, sizeof(curr_hash));
+		}
+
+		free(data);
+		n--;
+	}
+
+	curr_hash += total_sum;
+	curr_hash = djb2(&curr_hash, sizeof(curr_hash));
+	control_writeulong(curr_hash);
+
+	close(fd);
+}
+
+void test_stream_zerocopy_rx_server(const struct test_opts *opts)
+{
+	test_connectible_zerocopy_rx_server(opts, true);
+}
+
+void test_seqpacket_zerocopy_rx_server(const struct test_opts *opts)
+{
+	test_connectible_zerocopy_rx_server(opts, false);
+}
+
+void test_stream_zerocopy_rx_client_loop_poll(const struct test_opts *opts)
+{
+	unsigned long remote_sum;
+	unsigned long total_sum;
+	unsigned long zc_on = 1;
+	size_t rx_map_len;
+	u32 poll_value = 0;
+	void *rx_va;
+	int fd;
+
+	fd = vsock_stream_connect_opt(opts->peer_cid, 1234,
+					SO_VM_SOCKETS_ZEROCOPY,
+					(void *)&zc_on, sizeof(zc_on));
+	if (fd < 0) {
+		perror("connect");
+		exit(EXIT_FAILURE);
+	}
+
+	rx_map_len = PAGE_SIZE * RX_MAPPING_PAGES;
+
+	rx_va = mmap(NULL, rx_map_len, PROT_READ, MAP_SHARED, fd, 0);
+	if (rx_va == MAP_FAILED) {
+		perror("mmap");
+		exit(EXIT_FAILURE);
+	}
+
+	total_sum = 0;
+
+	while (1) {
+		volatile struct virtio_vsock_usr_hdr_pref *poll_hdr;
+		struct virtio_vsock_usr_hdr *data_hdr;
+		unsigned char *data_va;
+		unsigned char *end_va;
+		int leave_loop;
+		socklen_t len;
+		int hdr_cnt;
+
+		poll_hdr = (struct virtio_vsock_usr_hdr_pref *)rx_va;
+
+		if (poll_value != ~0) {
+			do {
+				poll_value = poll_hdr->poll_value;
+			} while (!poll_value);
+		}
+
+		len = sizeof(rx_va);
+
+		if (getsockopt(fd, AF_VSOCK,
+				SO_VM_SOCKETS_MAP_RX,
+				&rx_va, &len) < 0) {
+			perror("getsockopt");
+			exit(EXIT_FAILURE);
+		}
+
+		data_va = rx_va + PAGE_SIZE;
+		end_va = (unsigned char *)(rx_va + rx_map_len);
+		data_hdr = (struct virtio_vsock_usr_hdr *)(poll_hdr + 1);
+		hdr_cnt = 0;
+		leave_loop = 0;
+
+		while (data_va != end_va) {
+			int data_len = data_hdr->len;
+
+			if (!data_hdr->len) {
+				/* Zero length in first header and there will
+				 * be no more data, leave processing loop.
+				 */
+				if (!hdr_cnt && (poll_value == ~0))
+					leave_loop = 1;
+
+				break;
+			}
+
+			while (data_len > 0) {
+				int i;
+				int to_read = (data_len < PAGE_SIZE) ?
+					       data_len : PAGE_SIZE;
+
+				for (i = 0; i < to_read; i++)
+					total_sum += data_va[i];
+
+				data_va += PAGE_SIZE;
+				data_len -= PAGE_SIZE;
+			}
+
+			data_hdr++;
+			hdr_cnt++;
+		}
+
+		if (madvise((void *)rx_va + PAGE_SIZE,
+			    rx_map_len - PAGE_SIZE,
+			    MADV_DONTNEED)) {
+			perror("madvise");
+			exit(EXIT_FAILURE);
+		}
+
+		if (leave_loop)
+			break;
+	}
+
+	if (munmap(rx_va, rx_map_len)) {
+		perror("munmap");
+		exit(EXIT_FAILURE);
+	}
+
+	remote_sum = control_readulong(NULL);
+
+	if (total_sum != remote_sum) {
+		fprintf(stderr, "loop sum mismatch %lu != %lu\n",
+				total_sum, remote_sum);
+		exit(EXIT_FAILURE);
+	}
+
+	close(fd);
+}
+
+void test_stream_zerocopy_rx_server_loop_poll(const struct test_opts *opts)
+{
+	size_t max_buf_size = TX_BUF_SIZE;
+	unsigned long total_sum;
+	int n = TX_SEND_LOOPS;
+	int fd;
+
+	fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
+	if (fd < 0) {
+		perror("accept");
+		exit(EXIT_FAILURE);
+	}
+
+	total_sum = 0;
+
+	while (n) {
+		unsigned char *data;
+		size_t buf_size;
+		int i;
+
+		buf_size = 1 + (rand() % max_buf_size);
+
+		data = malloc(buf_size);
+
+		if (!data) {
+			perror("malloc");
+			exit(EXIT_FAILURE);
+		}
+
+		for (i = 0; i < buf_size; i++) {
+			data[i] = rand() & 0xff;
+			total_sum += data[i];
+		}
+
+		if (write(fd, data, buf_size) != buf_size) {
+			perror("write");
+			exit(EXIT_FAILURE);
+		}
+
+		free(data);
+		n--;
+	}
+
+	control_writeulong(total_sum);
+
+	close(fd);
+}
+
+void test_stream_zerocopy_rx_inv_client(const struct test_opts *opts)
+{
+	size_t map_size = PAGE_SIZE * 5;
+	unsigned long zc_on = 1;
+	socklen_t len;
+	void *map_va;
+	int fd;
+
+	/* Try zerocopy with disable option. */
+	fd = vsock_stream_connect_opt(opts->peer_cid, 1234, SO_VM_SOCKETS_ZEROCOPY,
+			(void *)&zc_on, sizeof(zc_on));
+	if (fd < 0) {
+		perror("connect");
+		exit(EXIT_FAILURE);
+	}
+
+	len = sizeof(map_va);
+	map_va = 0;
+
+	/* Try zerocopy with invalid mapping address. */
+	if (getsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_MAP_RX,
+			&map_va, &len) == 0) {
+		perror("getsockopt");
+		exit(EXIT_FAILURE);
+	}
+
+	/* Try zerocopy with valid, but not socket mapping. */
+	map_va = mmap(NULL, map_size, PROT_READ,
+		       MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+	if (map_va == MAP_FAILED) {
+		perror("anon mmap");
+		exit(EXIT_FAILURE);
+	}
+
+	if (getsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_MAP_RX,
+			&map_va, &len) == 0) {
+		perror("getsockopt");
+		exit(EXIT_FAILURE);
+	}
+
+	if (munmap(map_va, map_size)) {
+		perror("munmap");
+		exit(EXIT_FAILURE);
+	}
+
+	/* Try zerocopy with valid, but too small mapping. */
+	map_va = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, 0);
+	if (map_va != MAP_FAILED) {
+		perror("socket mmap small");
+		exit(EXIT_FAILURE);
+	}
+
+	if (getsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_MAP_RX,
+			&map_va, &len) == 0) {
+		perror("getsockopt");
+		exit(EXIT_FAILURE);
+	}
+
+	/* Try zerocopy with valid mapping, but not from first byte. */
+	map_va = mmap(NULL, map_size, PROT_READ, MAP_SHARED, fd, 0);
+	if (map_va == MAP_FAILED) {
+		perror("socket mmap");
+		exit(EXIT_FAILURE);
+	}
+
+	map_va += PAGE_SIZE;
+
+	if (getsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_MAP_RX,
+			&map_va, &len) == 0) {
+		perror("getsockopt");
+		exit(EXIT_FAILURE);
+	}
+
+	if (munmap(map_va - PAGE_SIZE, map_size)) {
+		perror("munmap");
+		exit(EXIT_FAILURE);
+	}
+
+	control_writeln("DONE");
+
+	close(fd);
+}
+
+void test_stream_zerocopy_rx_inv_server(const struct test_opts *opts)
+{
+	int fd;
+
+	fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
+
+	if (fd < 0) {
+		perror("accept");
+		exit(EXIT_FAILURE);
+	}
+
+	control_expectln("DONE");
+
+	close(fd);
+}
+
diff --git a/tools/testing/vsock/vsock_test_zerocopy.h b/tools/testing/vsock/vsock_test_zerocopy.h
new file mode 100644
index 000000000000..a818bd65b376
--- /dev/null
+++ b/tools/testing/vsock/vsock_test_zerocopy.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef VSOCK_TEST_ZEROCOPY_H
+#define VSOCK_TEST_ZEROCOPY_H
+
+void test_stream_zerocopy_rx_client(const struct test_opts *opts);
+void test_stream_zerocopy_rx_server(const struct test_opts *opts);
+void test_seqpacket_zerocopy_rx_client(const struct test_opts *opts);
+void test_seqpacket_zerocopy_rx_server(const struct test_opts *opts);
+void test_stream_zerocopy_rx_client_loop_poll(const struct test_opts *opts);
+void test_stream_zerocopy_rx_server_loop_poll(const struct test_opts *opts);
+void test_stream_zerocopy_rx_inv_client(const struct test_opts *opts);
+void test_stream_zerocopy_rx_inv_server(const struct test_opts *opts);
+
+#endif /* VSOCK_TEST_ZEROCOPY_H */
-- 
2.35.0

  parent reply	other threads:[~2022-11-06 19:52 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-06 19:33 [RFC PATCH v3 00/11] virtio/vsock: experimental zerocopy receive Arseniy Krasnov
2022-11-06 19:36 ` [RFC PATCH v3 01/11] virtio/vsock: rework packet allocation logic Arseniy Krasnov
2022-11-06 19:50   ` Christophe JAILLET
2022-11-07  5:23     ` Arseniy Krasnov
2022-11-07 21:24       ` Christophe JAILLET
2022-11-07 21:31         ` Arseniy Krasnov
2022-11-11 20:35   ` Bobby Eshleman
2022-11-06 19:38 ` [RFC PATCH v3 02/11] virtio/vsock: update, 'virtio_transport_recv_pkt()' Arseniy Krasnov
2022-11-06 19:40 ` [RFC PATCH v3 03/11] af_vsock: add zerocopy receive logic Arseniy Krasnov
2022-11-11 13:55   ` Stefano Garzarella
2022-11-11 13:55     ` Stefano Garzarella
2022-11-06 19:41 ` [RFC PATCH v3 04/11] virtio/vsock: add transport zerocopy callback Arseniy Krasnov
2022-11-10 11:15   ` Arseniy Krasnov
2022-11-06 19:43 ` [RFC PATCH v3 05/11] vhost/vsock: switch packet's buffer allocation Arseniy Krasnov
2022-11-06 19:45 ` [RFC PATCH v3 06/11] vhost/vsock: enable zerocopy callback Arseniy Krasnov
2022-11-06 19:47 ` [RFC PATCH v3 07/11] virtio/vsock: " Arseniy Krasnov
2022-11-06 19:48 ` [RFC PATCH v3 08/11] test/vsock: rework message bound test Arseniy Krasnov
2022-11-11 14:00   ` Stefano Garzarella
2022-11-11 14:00     ` Stefano Garzarella
2022-11-06 19:50 ` [RFC PATCH v3 09/11] test/vsock: add big message test Arseniy Krasnov
2022-11-06 19:51 ` Arseniy Krasnov [this message]
2022-11-06 19:54 ` [RFC PATCH v3 11/11] test/vsock: vsock_rx_perf utility Arseniy Krasnov
2022-11-11 13:47 ` [RFC PATCH v3 00/11] virtio/vsock: experimental zerocopy receive Stefano Garzarella
2022-11-11 13:47   ` Stefano Garzarella
2022-11-11 14:06   ` Stefano Garzarella
2022-11-11 14:06     ` Stefano Garzarella
2022-11-11 18:35     ` Arseniy Krasnov
2022-11-11 20:45   ` Bobby Eshleman
2022-11-12 11:40     ` Arseniy Krasnov
2022-11-13 10:04       ` Arseniy Krasnov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c1f3ff9d-0386-fa8b-5660-e0c49991c4dc@sberdevices.ru \
    --to=avkrasnov@sberdevices.ru \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=jasowang@redhat.com \
    --cc=kernel@sberdevices.ru \
    --cc=kuba@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=oxffffaa@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=sgarzare@redhat.com \
    --cc=stefanha@redhat.com \
    --cc=virtualization@lists.linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.