Commit 916d72c1 authored by Pavel Begunkov's avatar Pavel Begunkov Committed by Jens Axboe

selftests/net: return back io_uring zc send tests

Enable io_uring zerocopy send tests back and fix them up to follow the
new inteface.
Signed-off-by: default avatarPavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/c8e5018c516093bdad0b6e19f2f9847dea17e4d2.1662027856.git.asml.silence@gmail.comSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent b48c312b
...@@ -36,8 +36,6 @@ ...@@ -36,8 +36,6 @@
#include <sys/un.h> #include <sys/un.h>
#include <sys/wait.h> #include <sys/wait.h>
#if 0
#define NOTIF_TAG 0xfffffffULL #define NOTIF_TAG 0xfffffffULL
#define NONZC_TAG 0 #define NONZC_TAG 0
#define ZC_TAG 1 #define ZC_TAG 1
...@@ -49,7 +47,6 @@ enum { ...@@ -49,7 +47,6 @@ enum {
MODE_MIXED = 3, MODE_MIXED = 3,
}; };
static bool cfg_flush = false;
static bool cfg_cork = false; static bool cfg_cork = false;
static int cfg_mode = MODE_ZC_FIXED; static int cfg_mode = MODE_ZC_FIXED;
static int cfg_nr_reqs = 8; static int cfg_nr_reqs = 8;
...@@ -168,21 +165,6 @@ static int io_uring_register_buffers(struct io_uring *ring, ...@@ -168,21 +165,6 @@ static int io_uring_register_buffers(struct io_uring *ring,
return (ret < 0) ? -errno : ret; return (ret < 0) ? -errno : ret;
} }
static int io_uring_register_notifications(struct io_uring *ring,
unsigned nr,
struct io_uring_notification_slot *slots)
{
int ret;
struct io_uring_notification_register r = {
.nr_slots = nr,
.data = (unsigned long)slots,
};
ret = syscall(__NR_io_uring_register, ring->ring_fd,
IORING_REGISTER_NOTIFIERS, &r, sizeof(r));
return (ret < 0) ? -errno : ret;
}
static int io_uring_mmap(int fd, struct io_uring_params *p, static int io_uring_mmap(int fd, struct io_uring_params *p,
struct io_uring_sq *sq, struct io_uring_cq *cq) struct io_uring_sq *sq, struct io_uring_cq *cq)
{ {
...@@ -299,11 +281,10 @@ static inline void io_uring_prep_send(struct io_uring_sqe *sqe, int sockfd, ...@@ -299,11 +281,10 @@ static inline void io_uring_prep_send(struct io_uring_sqe *sqe, int sockfd,
static inline void io_uring_prep_sendzc(struct io_uring_sqe *sqe, int sockfd, static inline void io_uring_prep_sendzc(struct io_uring_sqe *sqe, int sockfd,
const void *buf, size_t len, int flags, const void *buf, size_t len, int flags,
unsigned slot_idx, unsigned zc_flags) unsigned zc_flags)
{ {
io_uring_prep_send(sqe, sockfd, buf, len, flags); io_uring_prep_send(sqe, sockfd, buf, len, flags);
sqe->opcode = (__u8) IORING_OP_SENDZC_NOTIF; sqe->opcode = (__u8) IORING_OP_SEND_ZC;
sqe->notification_idx = slot_idx;
sqe->ioprio = zc_flags; sqe->ioprio = zc_flags;
} }
...@@ -376,7 +357,6 @@ static int do_setup_tx(int domain, int type, int protocol) ...@@ -376,7 +357,6 @@ static int do_setup_tx(int domain, int type, int protocol)
static void do_tx(int domain, int type, int protocol) static void do_tx(int domain, int type, int protocol)
{ {
struct io_uring_notification_slot b[1] = {{.tag = NOTIF_TAG}};
struct io_uring_sqe *sqe; struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe; struct io_uring_cqe *cqe;
unsigned long packets = 0, bytes = 0; unsigned long packets = 0, bytes = 0;
...@@ -392,10 +372,6 @@ static void do_tx(int domain, int type, int protocol) ...@@ -392,10 +372,6 @@ static void do_tx(int domain, int type, int protocol)
if (ret) if (ret)
error(1, ret, "io_uring: queue init"); error(1, ret, "io_uring: queue init");
ret = io_uring_register_notifications(&ring, 1, b);
if (ret)
error(1, ret, "io_uring: tx ctx registration");
iov.iov_base = payload; iov.iov_base = payload;
iov.iov_len = cfg_payload_len; iov.iov_len = cfg_payload_len;
...@@ -411,9 +387,8 @@ static void do_tx(int domain, int type, int protocol) ...@@ -411,9 +387,8 @@ static void do_tx(int domain, int type, int protocol)
for (i = 0; i < cfg_nr_reqs; i++) { for (i = 0; i < cfg_nr_reqs; i++) {
unsigned zc_flags = 0; unsigned zc_flags = 0;
unsigned buf_idx = 0; unsigned buf_idx = 0;
unsigned slot_idx = 0;
unsigned mode = cfg_mode; unsigned mode = cfg_mode;
unsigned msg_flags = 0; unsigned msg_flags = MSG_WAITALL;
if (cfg_mode == MODE_MIXED) if (cfg_mode == MODE_MIXED)
mode = rand() % 3; mode = rand() % 3;
...@@ -425,13 +400,10 @@ static void do_tx(int domain, int type, int protocol) ...@@ -425,13 +400,10 @@ static void do_tx(int domain, int type, int protocol)
cfg_payload_len, msg_flags); cfg_payload_len, msg_flags);
sqe->user_data = NONZC_TAG; sqe->user_data = NONZC_TAG;
} else { } else {
if (cfg_flush) { compl_cqes++;
zc_flags |= IORING_RECVSEND_NOTIF_FLUSH;
compl_cqes++;
}
io_uring_prep_sendzc(sqe, fd, payload, io_uring_prep_sendzc(sqe, fd, payload,
cfg_payload_len, cfg_payload_len,
msg_flags, slot_idx, zc_flags); msg_flags, zc_flags);
if (mode == MODE_ZC_FIXED) { if (mode == MODE_ZC_FIXED) {
sqe->ioprio |= IORING_RECVSEND_FIXED_BUF; sqe->ioprio |= IORING_RECVSEND_FIXED_BUF;
sqe->buf_index = buf_idx; sqe->buf_index = buf_idx;
...@@ -444,51 +416,57 @@ static void do_tx(int domain, int type, int protocol) ...@@ -444,51 +416,57 @@ static void do_tx(int domain, int type, int protocol)
if (ret != cfg_nr_reqs) if (ret != cfg_nr_reqs)
error(1, ret, "submit"); error(1, ret, "submit");
if (cfg_cork)
do_setsockopt(fd, IPPROTO_UDP, UDP_CORK, 0);
for (i = 0; i < cfg_nr_reqs; i++) { for (i = 0; i < cfg_nr_reqs; i++) {
ret = io_uring_wait_cqe(&ring, &cqe); ret = io_uring_wait_cqe(&ring, &cqe);
if (ret) if (ret)
error(1, ret, "wait cqe"); error(1, ret, "wait cqe");
if (cqe->user_data == NOTIF_TAG) { if (cqe->user_data != NONZC_TAG &&
cqe->user_data != ZC_TAG)
error(1, -EINVAL, "invalid cqe->user_data");
if (cqe->flags & IORING_CQE_F_NOTIF) {
if (cqe->flags & IORING_CQE_F_MORE)
error(1, -EINVAL, "invalid notif flags");
compl_cqes--; compl_cqes--;
i--; i--;
} else if (cqe->user_data != NONZC_TAG && } else if (cqe->res <= 0) {
cqe->user_data != ZC_TAG) { if (cqe->flags & IORING_CQE_F_MORE)
error(1, cqe->res, "invalid user_data"); error(1, cqe->res, "more with a failed send");
} else if (cqe->res <= 0 && cqe->res != -EAGAIN) {
error(1, cqe->res, "send failed"); error(1, cqe->res, "send failed");
} else { } else {
if (cqe->res > 0) { if (cqe->user_data == ZC_TAG &&
packets++; !(cqe->flags & IORING_CQE_F_MORE))
bytes += cqe->res; error(1, cqe->res, "missing more flag");
} packets++;
/* failed requests don't flush */ bytes += cqe->res;
if (cfg_flush &&
cqe->res <= 0 &&
cqe->user_data == ZC_TAG)
compl_cqes--;
} }
io_uring_cqe_seen(&ring); io_uring_cqe_seen(&ring);
} }
if (cfg_cork)
do_setsockopt(fd, IPPROTO_UDP, UDP_CORK, 0);
} while (gettimeofday_ms() < tstop); } while (gettimeofday_ms() < tstop);
if (close(fd))
error(1, errno, "close");
fprintf(stderr, "tx=%lu (MB=%lu), tx/s=%lu (MB/s=%lu)\n",
packets, bytes >> 20,
packets / (cfg_runtime_ms / 1000),
(bytes >> 20) / (cfg_runtime_ms / 1000));
while (compl_cqes) { while (compl_cqes) {
ret = io_uring_wait_cqe(&ring, &cqe); ret = io_uring_wait_cqe(&ring, &cqe);
if (ret) if (ret)
error(1, ret, "wait cqe"); error(1, ret, "wait cqe");
if (cqe->flags & IORING_CQE_F_MORE)
error(1, -EINVAL, "invalid notif flags");
if (!(cqe->flags & IORING_CQE_F_NOTIF))
error(1, -EINVAL, "missing notif flag");
io_uring_cqe_seen(&ring); io_uring_cqe_seen(&ring);
compl_cqes--; compl_cqes--;
} }
fprintf(stderr, "tx=%lu (MB=%lu), tx/s=%lu (MB/s=%lu)\n",
packets, bytes >> 20,
packets / (cfg_runtime_ms / 1000),
(bytes >> 20) / (cfg_runtime_ms / 1000));
if (close(fd))
error(1, errno, "close");
} }
static void do_test(int domain, int type, int protocol) static void do_test(int domain, int type, int protocol)
...@@ -502,8 +480,8 @@ static void do_test(int domain, int type, int protocol) ...@@ -502,8 +480,8 @@ static void do_test(int domain, int type, int protocol)
static void usage(const char *filepath) static void usage(const char *filepath)
{ {
error(1, 0, "Usage: %s [-f] [-n<N>] [-z0] [-s<payload size>] " error(1, 0, "Usage: %s (-4|-6) (udp|tcp) -D<dst_ip> [-s<payload size>] "
"(-4|-6) [-t<time s>] -D<dst_ip> udp", filepath); "[-t<time s>] [-n<batch>] [-p<port>] [-m<mode>]", filepath);
} }
static void parse_opts(int argc, char **argv) static void parse_opts(int argc, char **argv)
...@@ -521,7 +499,7 @@ static void parse_opts(int argc, char **argv) ...@@ -521,7 +499,7 @@ static void parse_opts(int argc, char **argv)
usage(argv[0]); usage(argv[0]);
cfg_payload_len = max_payload_len; cfg_payload_len = max_payload_len;
while ((c = getopt(argc, argv, "46D:p:s:t:n:fc:m:")) != -1) { while ((c = getopt(argc, argv, "46D:p:s:t:n:c:m:")) != -1) {
switch (c) { switch (c) {
case '4': case '4':
if (cfg_family != PF_UNSPEC) if (cfg_family != PF_UNSPEC)
...@@ -550,9 +528,6 @@ static void parse_opts(int argc, char **argv) ...@@ -550,9 +528,6 @@ static void parse_opts(int argc, char **argv)
case 'n': case 'n':
cfg_nr_reqs = strtoul(optarg, NULL, 0); cfg_nr_reqs = strtoul(optarg, NULL, 0);
break; break;
case 'f':
cfg_flush = 1;
break;
case 'c': case 'c':
cfg_cork = strtol(optarg, NULL, 0); cfg_cork = strtol(optarg, NULL, 0);
break; break;
...@@ -585,8 +560,6 @@ static void parse_opts(int argc, char **argv) ...@@ -585,8 +560,6 @@ static void parse_opts(int argc, char **argv)
if (cfg_payload_len > max_payload_len) if (cfg_payload_len > max_payload_len)
error(1, 0, "-s: payload exceeds max (%d)", max_payload_len); error(1, 0, "-s: payload exceeds max (%d)", max_payload_len);
if (cfg_mode == MODE_NONZC && cfg_flush)
error(1, 0, "-f: only zerocopy modes support notifications");
if (optind != argc - 1) if (optind != argc - 1)
usage(argv[0]); usage(argv[0]);
} }
...@@ -605,10 +578,3 @@ int main(int argc, char **argv) ...@@ -605,10 +578,3 @@ int main(int argc, char **argv)
error(1, 0, "unknown cfg_test %s", cfg_test); error(1, 0, "unknown cfg_test %s", cfg_test);
return 0; return 0;
} }
#else
int main(int argc, char **argv)
{
return 0;
}
#endif
...@@ -25,15 +25,11 @@ readonly path_sysctl_mem="net.core.optmem_max" ...@@ -25,15 +25,11 @@ readonly path_sysctl_mem="net.core.optmem_max"
# No arguments: automated test # No arguments: automated test
if [[ "$#" -eq "0" ]]; then if [[ "$#" -eq "0" ]]; then
IPs=( "4" "6" ) IPs=( "4" "6" )
protocols=( "tcp" "udp" )
for IP in "${IPs[@]}"; do for IP in "${IPs[@]}"; do
for proto in "${protocols[@]}"; do for mode in $(seq 1 3); do
for mode in $(seq 1 3); do $0 "$IP" udp -m "$mode" -t 1 -n 32
$0 "$IP" "$proto" -m "$mode" -t 1 -n 32 $0 "$IP" tcp -m "$mode" -t 1 -n 32
$0 "$IP" "$proto" -m "$mode" -t 1 -n 32 -f
$0 "$IP" "$proto" -m "$mode" -t 1 -n 32 -c -f
done
done done
done done
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment