@@ -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);
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> --- test/send-zerocopy.c | 58 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 8 deletions(-)