diff options
author | Sowmini Varadhan <sowmini.varadhan@oracle.com> | 2018-02-15 13:49:38 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-02-16 16:04:17 -0500 |
commit | dfb8434b0a94651dac7adf373900561d8f6499e4 (patch) | |
tree | 484a63f508f2d92be4c2dd7796382748e7f75f57 /tools/testing/selftests/net/msg_zerocopy.c | |
parent | b16ac920403e5623150e428e7f5429e8eb607308 (diff) |
selftests/net: add zerocopy support for PF_RDS test case
Send a cookie with sendmsg() on PF_RDS sockets, and process the
returned batched cookies in do_recv_completion()
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Acked-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools/testing/selftests/net/msg_zerocopy.c')
-rw-r--r-- | tools/testing/selftests/net/msg_zerocopy.c | 68 |
1 files changed, 64 insertions, 4 deletions
diff --git a/tools/testing/selftests/net/msg_zerocopy.c b/tools/testing/selftests/net/msg_zerocopy.c index 7a5b35362f84..5cc2a53bb71c 100644 --- a/tools/testing/selftests/net/msg_zerocopy.c +++ b/tools/testing/selftests/net/msg_zerocopy.c | |||
@@ -168,17 +168,39 @@ static int do_accept(int fd) | |||
168 | return fd; | 168 | return fd; |
169 | } | 169 | } |
170 | 170 | ||
171 | static bool do_sendmsg(int fd, struct msghdr *msg, bool do_zerocopy) | 171 | static void add_zcopy_cookie(struct msghdr *msg, uint32_t cookie) |
172 | { | ||
173 | struct cmsghdr *cm; | ||
174 | |||
175 | if (!msg->msg_control) | ||
176 | error(1, errno, "NULL cookie"); | ||
177 | cm = (void *)msg->msg_control; | ||
178 | cm->cmsg_len = CMSG_LEN(sizeof(cookie)); | ||
179 | cm->cmsg_level = SOL_RDS; | ||
180 | cm->cmsg_type = RDS_CMSG_ZCOPY_COOKIE; | ||
181 | memcpy(CMSG_DATA(cm), &cookie, sizeof(cookie)); | ||
182 | } | ||
183 | |||
184 | static bool do_sendmsg(int fd, struct msghdr *msg, bool do_zerocopy, int domain) | ||
172 | { | 185 | { |
173 | int ret, len, i, flags; | 186 | int ret, len, i, flags; |
187 | static uint32_t cookie; | ||
188 | char ckbuf[CMSG_SPACE(sizeof(cookie))]; | ||
174 | 189 | ||
175 | len = 0; | 190 | len = 0; |
176 | for (i = 0; i < msg->msg_iovlen; i++) | 191 | for (i = 0; i < msg->msg_iovlen; i++) |
177 | len += msg->msg_iov[i].iov_len; | 192 | len += msg->msg_iov[i].iov_len; |
178 | 193 | ||
179 | flags = MSG_DONTWAIT; | 194 | flags = MSG_DONTWAIT; |
180 | if (do_zerocopy) | 195 | if (do_zerocopy) { |
181 | flags |= MSG_ZEROCOPY; | 196 | flags |= MSG_ZEROCOPY; |
197 | if (domain == PF_RDS) { | ||
198 | memset(&msg->msg_control, 0, sizeof(msg->msg_control)); | ||
199 | msg->msg_controllen = CMSG_SPACE(sizeof(cookie)); | ||
200 | msg->msg_control = (struct cmsghdr *)ckbuf; | ||
201 | add_zcopy_cookie(msg, ++cookie); | ||
202 | } | ||
203 | } | ||
182 | 204 | ||
183 | ret = sendmsg(fd, msg, flags); | 205 | ret = sendmsg(fd, msg, flags); |
184 | if (ret == -1 && errno == EAGAIN) | 206 | if (ret == -1 && errno == EAGAIN) |
@@ -194,6 +216,10 @@ static bool do_sendmsg(int fd, struct msghdr *msg, bool do_zerocopy) | |||
194 | if (do_zerocopy && ret) | 216 | if (do_zerocopy && ret) |
195 | expected_completions++; | 217 | expected_completions++; |
196 | } | 218 | } |
219 | if (do_zerocopy && domain == PF_RDS) { | ||
220 | msg->msg_control = NULL; | ||
221 | msg->msg_controllen = 0; | ||
222 | } | ||
197 | 223 | ||
198 | return true; | 224 | return true; |
199 | } | 225 | } |
@@ -220,7 +246,9 @@ static void do_sendmsg_corked(int fd, struct msghdr *msg) | |||
220 | msg->msg_iov[0].iov_len = payload_len + extra_len; | 246 | msg->msg_iov[0].iov_len = payload_len + extra_len; |
221 | extra_len = 0; | 247 | extra_len = 0; |
222 | 248 | ||
223 | do_sendmsg(fd, msg, do_zerocopy); | 249 | do_sendmsg(fd, msg, do_zerocopy, |
250 | (cfg_dst_addr.ss_family == AF_INET ? | ||
251 | PF_INET : PF_INET6)); | ||
224 | } | 252 | } |
225 | 253 | ||
226 | do_setsockopt(fd, IPPROTO_UDP, UDP_CORK, 0); | 254 | do_setsockopt(fd, IPPROTO_UDP, UDP_CORK, 0); |
@@ -316,6 +344,26 @@ static int do_setup_tx(int domain, int type, int protocol) | |||
316 | return fd; | 344 | return fd; |
317 | } | 345 | } |
318 | 346 | ||
347 | static int do_process_zerocopy_cookies(struct sock_extended_err *serr, | ||
348 | uint32_t *ckbuf, size_t nbytes) | ||
349 | { | ||
350 | int ncookies, i; | ||
351 | |||
352 | if (serr->ee_errno != 0) | ||
353 | error(1, 0, "serr: wrong error code: %u", serr->ee_errno); | ||
354 | ncookies = serr->ee_data; | ||
355 | if (ncookies > SO_EE_ORIGIN_MAX_ZCOOKIES) | ||
356 | error(1, 0, "Returned %d cookies, max expected %d\n", | ||
357 | ncookies, SO_EE_ORIGIN_MAX_ZCOOKIES); | ||
358 | if (nbytes != ncookies * sizeof(uint32_t)) | ||
359 | error(1, 0, "Expected %d cookies, got %ld\n", | ||
360 | ncookies, nbytes/sizeof(uint32_t)); | ||
361 | for (i = 0; i < ncookies; i++) | ||
362 | if (cfg_verbose >= 2) | ||
363 | fprintf(stderr, "%d\n", ckbuf[i]); | ||
364 | return ncookies; | ||
365 | } | ||
366 | |||
319 | static bool do_recv_completion(int fd) | 367 | static bool do_recv_completion(int fd) |
320 | { | 368 | { |
321 | struct sock_extended_err *serr; | 369 | struct sock_extended_err *serr; |
@@ -324,10 +372,17 @@ static bool do_recv_completion(int fd) | |||
324 | uint32_t hi, lo, range; | 372 | uint32_t hi, lo, range; |
325 | int ret, zerocopy; | 373 | int ret, zerocopy; |
326 | char control[100]; | 374 | char control[100]; |
375 | uint32_t ckbuf[SO_EE_ORIGIN_MAX_ZCOOKIES]; | ||
376 | struct iovec iov; | ||
327 | 377 | ||
328 | msg.msg_control = control; | 378 | msg.msg_control = control; |
329 | msg.msg_controllen = sizeof(control); | 379 | msg.msg_controllen = sizeof(control); |
330 | 380 | ||
381 | iov.iov_base = ckbuf; | ||
382 | iov.iov_len = (SO_EE_ORIGIN_MAX_ZCOOKIES * sizeof(ckbuf[0])); | ||
383 | msg.msg_iov = &iov; | ||
384 | msg.msg_iovlen = 1; | ||
385 | |||
331 | ret = recvmsg(fd, &msg, MSG_ERRQUEUE); | 386 | ret = recvmsg(fd, &msg, MSG_ERRQUEUE); |
332 | if (ret == -1 && errno == EAGAIN) | 387 | if (ret == -1 && errno == EAGAIN) |
333 | return false; | 388 | return false; |
@@ -346,6 +401,11 @@ static bool do_recv_completion(int fd) | |||
346 | cm->cmsg_level, cm->cmsg_type); | 401 | cm->cmsg_level, cm->cmsg_type); |
347 | 402 | ||
348 | serr = (void *) CMSG_DATA(cm); | 403 | serr = (void *) CMSG_DATA(cm); |
404 | |||
405 | if (serr->ee_origin == SO_EE_ORIGIN_ZCOOKIE) { | ||
406 | completions += do_process_zerocopy_cookies(serr, ckbuf, ret); | ||
407 | return true; | ||
408 | } | ||
349 | if (serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY) | 409 | if (serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY) |
350 | error(1, 0, "serr: wrong origin: %u", serr->ee_origin); | 410 | error(1, 0, "serr: wrong origin: %u", serr->ee_origin); |
351 | if (serr->ee_errno != 0) | 411 | if (serr->ee_errno != 0) |
@@ -470,7 +530,7 @@ static void do_tx(int domain, int type, int protocol) | |||
470 | if (cfg_cork) | 530 | if (cfg_cork) |
471 | do_sendmsg_corked(fd, &msg); | 531 | do_sendmsg_corked(fd, &msg); |
472 | else | 532 | else |
473 | do_sendmsg(fd, &msg, cfg_zerocopy); | 533 | do_sendmsg(fd, &msg, cfg_zerocopy, domain); |
474 | 534 | ||
475 | while (!do_poll(fd, POLLOUT)) { | 535 | while (!do_poll(fd, POLLOUT)) { |
476 | if (cfg_zerocopy) | 536 | if (cfg_zerocopy) |