Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx> --- test/send-zerocopy.c | 58 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/test/send-zerocopy.c b/test/send-zerocopy.c index b51f421..adf730d 100644 --- a/test/send-zerocopy.c +++ b/test/send-zerocopy.c @@ -44,6 +44,7 @@ #define HOST "127.0.0.1" #define HOSTV6 "::1" +#define MAX_IOV 32 #define CORK_REQS 5 #define RX_TAG 10000 #define BUFFER_OFFSET 41 @@ -257,6 +258,8 @@ struct send_conf { bool use_sendmsg; bool tcp; bool zc; + bool iovec; + bool long_iovec; int buf_index; struct sockaddr_storage *addr; }; @@ -264,7 +267,7 @@ struct send_conf { static int do_test_inet_send(struct io_uring *ring, int sock_client, int sock_server, struct send_conf *conf) { - struct iovec iov[CORK_REQS]; + struct iovec iov[MAX_IOV]; struct msghdr msghdr[CORK_REQS]; const unsigned zc_flags = 0; struct io_uring_sqe *sqe; @@ -276,6 +279,8 @@ static int do_test_inet_send(struct io_uring *ring, int sock_client, int sock_se size_t chunk_size_last = send_size - chunk_size * (nr_reqs - 1); char *buf = buffers_iov[conf->buf_index].iov_base; + assert(MAX_IOV >= CORK_REQS); + if (conf->addr) { sa_family_t fam = ((struct sockaddr_in *)conf->addr)->sin_family; @@ -317,16 +322,46 @@ static int do_test_inet_send(struct io_uring *ring, int sock_client, int sock_se io_uring_prep_send_set_addr(sqe, (const struct sockaddr *)conf->addr, addr_len); } else { + struct iovec *io; + int iov_len; + if (conf->zc) io_uring_prep_sendmsg_zc(sqe, sock_client, &msghdr[i], msg_flags); else io_uring_prep_sendmsg(sqe, sock_client, &msghdr[i], msg_flags); + if (!conf->iovec) { + io = &iov[i]; + iov_len = 1; + iov[i].iov_len = cur_size; + iov[i].iov_base = buf + i * chunk_size; + } else { + char *it = buf; + int j; + + assert(nr_reqs == 1); + iov_len = conf->long_iovec ? MAX_IOV : 4; + io = iov; + + for (j = 0; j < iov_len; j++) + io[j].iov_len = 1; + /* first want to be easily advanced */ + io[0].iov_base = it; + it += io[0].iov_len; + /* this should cause retry */ + io[1].iov_len = chunk_size - iov_len + 1; + io[1].iov_base = it; + it += io[1].iov_len; + /* fill the rest */ + for (j = 2; j < iov_len; j++) { + io[j].iov_base = it; + it += io[j].iov_len; + } + } + memset(&msghdr[i], 0, sizeof(msghdr[i])); - iov[i].iov_len = cur_size; - iov[i].iov_base = buf + i * chunk_size; - msghdr[i].msg_iov = &iov[i]; - msghdr[i].msg_iovlen = 1; + msghdr[i].msg_iov = io; + msghdr[i].msg_iovlen = iov_len; if (conf->addr) { msghdr[i].msg_name = conf->addr; msghdr[i].msg_namelen = addr_len; @@ -423,7 +458,9 @@ static int test_inet_send(struct io_uring *ring) return 1; } - for (i = 0; i < 512; i++) { + for (i = 0; i < 2048; i++) { + bool regbuf; + conf.buf_index = i & 3; conf.fixed_buf = i & 4; conf.addr = (i & 8) ? &addr : NULL; @@ -432,10 +469,15 @@ static int test_inet_send(struct io_uring *ring) conf.force_async = i & 64; conf.use_sendmsg = i & 128; conf.zc = i & 256; + conf.iovec = i & 512; + conf.long_iovec = i & 1024; conf.tcp = tcp; + regbuf = conf.mix_register || conf.fixed_buf; + if (conf.iovec && (!conf.use_sendmsg || regbuf || conf.cork)) + continue; if (!conf.zc) { - if (conf.mix_register || conf.fixed_buf) + if (regbuf) continue; /* * Non zerocopy send w/ addr was added together with sendmsg_zc, @@ -454,7 +496,7 @@ static int test_inet_send(struct io_uring *ring) continue; if (!client_connect && conf.addr == NULL) continue; - if (conf.use_sendmsg && (conf.mix_register || conf.fixed_buf || !has_sendmsg)) + if (conf.use_sendmsg && (regbuf || !has_sendmsg)) continue; ret = do_test_inet_send(ring, sock_client, sock_server, &conf); -- 2.37.2