From patchwork Tue Jun 28 15:04:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Yudaken X-Patchwork-Id: 12898435 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7418C433EF for ; Tue, 28 Jun 2022 15:04:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347736AbiF1PEb (ORCPT ); Tue, 28 Jun 2022 11:04:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41044 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347731AbiF1PEb (ORCPT ); Tue, 28 Jun 2022 11:04:31 -0400 Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7EF141D301 for ; Tue, 28 Jun 2022 08:04:30 -0700 (PDT) Received: from pps.filterd (m0148460.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25SEdeX7030837 for ; Tue, 28 Jun 2022 08:04:29 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=facebook; bh=3BqJLcy2Q+zp0J5jZXaaXY8eyc8+JBIjWmpMaARdoD0=; b=kZIEL5ZJ6C+THkSJjv5HM0rsHdnhBy2wdWc4UB+ohCkwViDOZXkptYnNw8V2yI0/x44M ApVaz+2KW/64RCDiTGVsxSSEhE/r9XgzaZgc7hDcLaAJIZ55gfhWQCPpYn2de0B7eAuf AhX7rcr0+GVTVZY24iMSS+epcvsf/SNklWc= Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h03kf068x-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Tue, 28 Jun 2022 08:04:29 -0700 Received: from twshared18317.08.ash9.facebook.com (2620:10d:c085:108::4) by mail.thefacebook.com (2620:10d:c085:21d::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Tue, 28 Jun 2022 08:04:26 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id AE98A244BD55; Tue, 28 Jun 2022 08:04:18 -0700 (PDT) From: Dylan Yudaken To: Jens Axboe , Pavel Begunkov , CC: , Dylan Yudaken Subject: [PATCH liburing 1/4] add t_create_socket_pair Date: Tue, 28 Jun 2022 08:04:11 -0700 Message-ID: <20220628150414.1386435-2-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220628150414.1386435-1-dylany@fb.com> References: <20220628150414.1386435-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: 9zcwKbiL1ogZ3cj14sjn9890IdKhe_OD X-Proofpoint-ORIG-GUID: 9zcwKbiL1ogZ3cj14sjn9890IdKhe_OD X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-06-28_08,2022-06-28_01,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org This is a useful tool for making networking tests, and does not require a hard coded port which is useful Signed-off-by: Dylan Yudaken --- test/helpers.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/helpers.h | 5 +++ 2 files changed, 102 insertions(+) diff --git a/test/helpers.c b/test/helpers.c index 491822e..6fb1157 100644 --- a/test/helpers.c +++ b/test/helpers.c @@ -10,6 +10,10 @@ #include #include +#include +#include +#include + #include "helpers.h" #include "liburing.h" @@ -143,3 +147,96 @@ enum t_setup_ret t_register_buffers(struct io_uring *ring, fprintf(stderr, "buffer register failed: %s\n", strerror(-ret)); return ret; } + +int t_create_socket_pair(int fd[2], bool stream) +{ + int ret; + int type = stream ? SOCK_STREAM : SOCK_DGRAM; + int val; + struct sockaddr_in serv_addr; + struct sockaddr *paddr; + size_t paddrlen; + + type |= SOCK_CLOEXEC; + fd[0] = socket(AF_INET, type, 0); + if (fd[0] < 0) + return errno; + fd[1] = socket(AF_INET, type, 0); + if (fd[1] < 0) { + ret = errno; + close(fd[0]); + return ret; + } + + val = 1; + if (setsockopt(fd[0], SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))) + goto errno_cleanup; + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = 0; + inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr); + + paddr = (struct sockaddr *)&serv_addr; + paddrlen = sizeof(serv_addr); + + if (bind(fd[0], paddr, paddrlen)) { + fprintf(stderr, "bind failed\n"); + goto errno_cleanup; + } + + if (stream && listen(fd[0], 16)) { + fprintf(stderr, "listen failed\n"); + goto errno_cleanup; + } + + if (getsockname(fd[0], &serv_addr, (socklen_t *)&paddrlen)) { + fprintf(stderr, "getsockname failed\n"); + goto errno_cleanup; + } + inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr); + + if (connect(fd[1], &serv_addr, paddrlen)) { + fprintf(stderr, "connect failed\n"); + goto errno_cleanup; + } + + if (!stream) { + /* connect the other udp side */ + if (getsockname(fd[1], &serv_addr, (socklen_t *)&paddrlen)) { + fprintf(stderr, "getsockname failed\n"); + goto errno_cleanup; + } + inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr); + + if (connect(fd[0], &serv_addr, paddrlen)) { + fprintf(stderr, "connect failed\n"); + goto errno_cleanup; + } + return 0; + } + + /* for stream case we must accept and cleanup the listen socket */ + + ret = accept(fd[0], NULL, NULL); + if (ret < 0) + goto errno_cleanup; + + close(fd[0]); + fd[0] = ret; + + val = 1; + if (stream && setsockopt(fd[0], SOL_TCP, TCP_NODELAY, &val, sizeof(val))) + goto errno_cleanup; + val = 1; + if (stream && setsockopt(fd[1], SOL_TCP, TCP_NODELAY, &val, sizeof(val))) + goto errno_cleanup; + + return 0; + +errno_cleanup: + ret = errno; + close(fd[0]); + close(fd[1]); + return ret; +} diff --git a/test/helpers.h b/test/helpers.h index d0beb93..7cef3c1 100644 --- a/test/helpers.h +++ b/test/helpers.h @@ -52,6 +52,11 @@ void t_create_file_pattern(const char *file, size_t size, char pattern); */ struct iovec *t_create_buffers(size_t buf_num, size_t buf_size); +/* + * Helper for creating connected socket pairs + */ +int t_create_socket_pair(int fd[2], bool stream); + /* * Helper for setting up a ring and checking for user privs */ From patchwork Tue Jun 28 15:04:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Yudaken X-Patchwork-Id: 12898434 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60627C433EF for ; Tue, 28 Jun 2022 15:04:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347711AbiF1PE3 (ORCPT ); Tue, 28 Jun 2022 11:04:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41026 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347731AbiF1PE2 (ORCPT ); Tue, 28 Jun 2022 11:04:28 -0400 Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F2F92E0BE for ; Tue, 28 Jun 2022 08:04:28 -0700 (PDT) Received: from pps.filterd (m0109331.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25SAH5qc029521 for ; Tue, 28 Jun 2022 08:04:27 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=facebook; bh=8Mee8IHxkdAsrr2iwmEsmfJoqoSYM222IcJA+jf8psQ=; b=U+ah0x+GR8t6U4Yteg1NBrxMgiqxyrWwNxE++nJp9EdFcXNnWt7lrRjfqgBHRfP9UcEQ Y9auB4UiJn7/mT197g7ea+tqdReyhIuTaPhuFnl3klaBWdPtjLJkZJ1c7gdnwmlMkjJt z011JNaQh5WbIUBexY6O4EBDz+5fMKzU3wI= Received: from maileast.thefacebook.com ([163.114.130.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3gyg0af9sr-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Tue, 28 Jun 2022 08:04:27 -0700 Received: from twshared17349.03.ash7.facebook.com (2620:10d:c0a8:1b::d) by mail.thefacebook.com (2620:10d:c0a8:83::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Tue, 28 Jun 2022 08:04:26 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id B8EC2244BD57; Tue, 28 Jun 2022 08:04:18 -0700 (PDT) From: Dylan Yudaken To: Jens Axboe , Pavel Begunkov , CC: , Dylan Yudaken Subject: [PATCH liburing 2/4] add IORING_RECV_MULTISHOT to io_uring.h Date: Tue, 28 Jun 2022 08:04:12 -0700 Message-ID: <20220628150414.1386435-3-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220628150414.1386435-1-dylany@fb.com> References: <20220628150414.1386435-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: y_cwi_tKQQLhzGI6a8V8HdUWRLjT93v8 X-Proofpoint-ORIG-GUID: y_cwi_tKQQLhzGI6a8V8HdUWRLjT93v8 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-06-28_08,2022-06-28_01,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org copy from include/uapi/linux/io_uring.h Signed-off-by: Dylan Yudaken --- src/include/liburing/io_uring.h | 53 ++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h index 2f391c9..1e5bdb3 100644 --- a/src/include/liburing/io_uring.h +++ b/src/include/liburing/io_uring.h @@ -10,10 +10,7 @@ #include #include - -#ifdef __cplusplus -extern "C" { -#endif +#include /* * IO submission data structure (Submission Queue Entry) @@ -26,6 +23,7 @@ struct io_uring_sqe { union { __u64 off; /* offset into file */ __u64 addr2; + __u32 cmd_op; }; union { __u64 addr; /* pointer to buffer or iovecs */ @@ -65,8 +63,17 @@ struct io_uring_sqe { __s32 splice_fd_in; __u32 file_index; }; - __u64 addr3; - __u64 __pad2[1]; + union { + struct { + __u64 addr3; + __u64 __pad2[1]; + }; + /* + * If the ring is initialized with IORING_SETUP_SQE128, then + * this field is used for 80 bytes of arbitrary command data + */ + __u8 cmd[0]; + }; }; /* @@ -131,9 +138,12 @@ enum { * IORING_SQ_TASKRUN in the sq ring flags. Not valid with COOP_TASKRUN. */ #define IORING_SETUP_TASKRUN_FLAG (1U << 9) - #define IORING_SETUP_SQE128 (1U << 10) /* SQEs are 128 byte */ #define IORING_SETUP_CQE32 (1U << 11) /* CQEs are 32 byte */ +/* + * Only one task is allowed to submit requests + */ +#define IORING_SETUP_SINGLE_ISSUER (1U << 12) enum io_uring_op { IORING_OP_NOP, @@ -220,10 +230,13 @@ enum io_uring_op { * * IORING_POLL_UPDATE Update existing poll request, matching * sqe->addr as the old user_data field. + * + * IORING_POLL_LEVEL Level triggered poll. */ #define IORING_POLL_ADD_MULTI (1U << 0) #define IORING_POLL_UPDATE_EVENTS (1U << 1) #define IORING_POLL_UPDATE_USER_DATA (1U << 2) +#define IORING_POLL_ADD_LEVEL (1U << 3) /* * ASYNC_CANCEL flags. @@ -232,10 +245,12 @@ enum io_uring_op { * IORING_ASYNC_CANCEL_FD Key off 'fd' for cancelation rather than the * request 'user_data' * IORING_ASYNC_CANCEL_ANY Match any request + * IORING_ASYNC_CANCEL_FD_FIXED 'fd' passed in is a fixed descriptor */ #define IORING_ASYNC_CANCEL_ALL (1U << 0) #define IORING_ASYNC_CANCEL_FD (1U << 1) -#define IORING_ASYNC_CANCEL_ANY (1U << 2) +#define IORING_ASYNC_CANCEL_ANY (1U << 2) +#define IORING_ASYNC_CANCEL_FD_FIXED (1U << 3) /* * send/sendmsg and recv/recvmsg flags (sqe->addr2) @@ -244,8 +259,13 @@ enum io_uring_op { * or receive and arm poll if that yields an * -EAGAIN result, arm poll upfront and skip * the initial transfer attempt. + * + * IORING_RECV_MULTISHOT Multishot recv. Sets IORING_CQE_F_MORE if + * the handler will continue to report + * CQEs on behalf of the same SQE. */ #define IORING_RECVSEND_POLL_FIRST (1U << 0) +#define IORING_RECV_MULTISHOT (1U << 1) /* * accept flags stored in sqe->ioprio @@ -411,6 +431,9 @@ enum { IORING_REGISTER_PBUF_RING = 22, IORING_UNREGISTER_PBUF_RING = 23, + /* sync cancelation API */ + IORING_REGISTER_SYNC_CANCEL = 24, + /* this goes last */ IORING_REGISTER_LAST }; @@ -547,12 +570,14 @@ struct io_uring_getevents_arg { }; /* - * accept flags stored in sqe->ioprio + * Argument for IORING_REGISTER_SYNC_CANCEL */ -#define IORING_ACCEPT_MULTISHOT (1U << 0) - -#ifdef __cplusplus -} -#endif +struct io_uring_sync_cancel_reg { + __u64 addr; + __s32 fd; + __u32 flags; + struct __kernel_timespec timeout; + __u64 pad[4]; +}; #endif From patchwork Tue Jun 28 15:04:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Yudaken X-Patchwork-Id: 12898436 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 16D7FC43334 for ; Tue, 28 Jun 2022 15:04:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347731AbiF1PEc (ORCPT ); Tue, 28 Jun 2022 11:04:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41042 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347720AbiF1PEb (ORCPT ); Tue, 28 Jun 2022 11:04:31 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0DD64192A3 for ; Tue, 28 Jun 2022 08:04:30 -0700 (PDT) Received: from pps.filterd (m0044010.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25SAE6Vq013125 for ; Tue, 28 Jun 2022 08:04:29 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=facebook; bh=rJDn4mTH+FztlGFytSbqUBIqiZ4DyJ/3UGqMxMNnJTk=; b=VBBU4xKHhUjwSD/8TJ+GbEwNcRoQZl2SLBKSCZalqgfHvfFYduKpJLmARtQt9nOnYjGT IraYvGs/k40QowfwpxLG0Vz5GR+6knwECOk8mY3NVsZR9Wfj+CYfhVuK/vGuu+9GOAzb gJg2ALCFe9n/b5dhroPjlq7kJ2TmmPKz2zM= Received: from maileast.thefacebook.com ([163.114.130.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3gyxx31ytw-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Tue, 28 Jun 2022 08:04:29 -0700 Received: from twshared17349.03.ash7.facebook.com (2620:10d:c0a8:1b::d) by mail.thefacebook.com (2620:10d:c0a8:83::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Tue, 28 Jun 2022 08:04:26 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id C18C1244BD59; Tue, 28 Jun 2022 08:04:18 -0700 (PDT) From: Dylan Yudaken To: Jens Axboe , Pavel Begunkov , CC: , Dylan Yudaken Subject: [PATCH liburing 3/4] add recv-multishot test Date: Tue, 28 Jun 2022 08:04:13 -0700 Message-ID: <20220628150414.1386435-4-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220628150414.1386435-1-dylany@fb.com> References: <20220628150414.1386435-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: 028fMTDhAnRImmUgh-gjY-N-CWuMU_d- X-Proofpoint-ORIG-GUID: 028fMTDhAnRImmUgh-gjY-N-CWuMU_d- X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-06-28_08,2022-06-28_01,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org add a test for multishot receive functionality Signed-off-by: Dylan Yudaken --- test/Makefile | 1 + test/recv-multishot.c | 308 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 309 insertions(+) create mode 100644 test/recv-multishot.c diff --git a/test/Makefile b/test/Makefile index e3204a7..73a0001 100644 --- a/test/Makefile +++ b/test/Makefile @@ -124,6 +124,7 @@ test_srcs := \ read-write.c \ recv-msgall.c \ recv-msgall-stream.c \ + recv-multishot.c \ register-restrictions.c \ rename.c \ ringbuf-read.c \ diff --git a/test/recv-multishot.c b/test/recv-multishot.c new file mode 100644 index 0000000..38ec615 --- /dev/null +++ b/test/recv-multishot.c @@ -0,0 +1,308 @@ +// SPDX-License-Identifier: MIT + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "liburing.h" +#include "helpers.h" + + +enum early_error_t { + ERROR_NONE = 0, + ERROR_NOT_ENOUGH_BUFFERS = 1, + ERROR_EARLY_CLOSE_SENDER = 2, + ERROR_EARLY_CLOSE_RECEIVER = 3, +}; + +struct args { + bool recvmsg; + bool stream; + bool wait_each; + enum early_error_t early_error; +}; + +static int test(struct args *args) +{ + int const N = 8; + int const N_BUFFS = N * 64; + int const min_cqes = 2; + struct io_uring ring; + struct io_uring_cqe *cqe; + struct io_uring_sqe *sqe; + int fds[2], ret, i, j, total_sent_bytes = 0, total_recv_bytes = 0; + int send_buff[256]; + int *recv_buffs[N_BUFFS]; + int *at; + struct io_uring_cqe recv_cqe[N_BUFFS]; + int recv_cqes = 0; + bool early_error = false; + bool early_error_started = false; + struct msghdr msg = { }; + struct __kernel_timespec timeout = { + .tv_sec = 1, + }; + + + memset(recv_buffs, 0, sizeof(recv_buffs)); + + ret = io_uring_queue_init(32, &ring, 0); + if (ret) { + fprintf(stderr, "queue init failed: %d\n", ret); + return ret; + } + + ret = t_create_socket_pair(fds, args->stream); + if (ret) { + fprintf(stderr, "t_create_socket_pair failed: %d\n", ret); + return ret; + } + + for (i = 0; i < ARRAY_SIZE(send_buff); i++) + send_buff[i] = i; + + for (i = 0; i < ARRAY_SIZE(recv_buffs); i++) { + /* prepare some different sized buffers */ + int buffer_size = (i % 2 == 0 && args->stream) ? 1 : N * sizeof(int); + + recv_buffs[i] = malloc(sizeof(*at) * buffer_size); + + if (i > 2 && args->early_error == ERROR_NOT_ENOUGH_BUFFERS) + continue; + + sqe = io_uring_get_sqe(&ring); + io_uring_prep_provide_buffers(sqe, recv_buffs[i], + buffer_size * sizeof(*recv_buffs[i]), 1, 7, i); + if (io_uring_submit_and_wait_timeout(&ring, &cqe, 1, &timeout, NULL) != 0) { + fprintf(stderr, "provide buffers failed: %d\n", ret); + ret = -1; + goto cleanup; + } + io_uring_cqe_seen(&ring, cqe); + } + + sqe = io_uring_get_sqe(&ring); + if (args->recvmsg) { + memset(&msg, 0, sizeof(msg)); + msg.msg_namelen = sizeof(struct sockaddr_in); + io_uring_prep_recvmsg(sqe, fds[0], &msg, 0); + } else { + io_uring_prep_recv(sqe, fds[0], NULL, 0, 0); + } + sqe->flags |= IOSQE_BUFFER_SELECT; + sqe->buf_group = 7; + sqe->addr2 |= IORING_RECV_MULTISHOT; + io_uring_sqe_set_data64(sqe, 1234); + io_uring_submit(&ring); + + at = &send_buff[0]; + total_sent_bytes = 0; + for (i = 0; i < N; i++) { + int to_send = sizeof(*at) * (i+1); + + total_sent_bytes += to_send; + if (send(fds[1], at, to_send, 0) != to_send) { + if (early_error_started) + break; + fprintf(stderr, "send failed %d\n", errno); + ret = -1; + goto cleanup; + } + + if (i == 2) { + if (args->early_error == ERROR_EARLY_CLOSE_RECEIVER) { + /* allow previous sends to complete */ + usleep(1000); + + sqe = io_uring_get_sqe(&ring); + io_uring_prep_recv(sqe, fds[0], NULL, 0, 0); + io_uring_prep_cancel64(sqe, 1234, 0); + sqe->flags |= IOSQE_CQE_SKIP_SUCCESS; + io_uring_submit(&ring); + early_error_started = true; + } + if (args->early_error == ERROR_EARLY_CLOSE_SENDER) { + early_error_started = true; + shutdown(fds[1], SHUT_RDWR); + close(fds[1]); + } + } + at += (i+1); + + if (args->wait_each) { + ret = io_uring_wait_cqes(&ring, &cqe, 1, &timeout, NULL); + if (ret) { + fprintf(stderr, "wait_each failed: %d\n", ret); + ret = -1; + goto cleanup; + } + while (io_uring_peek_cqe(&ring, &cqe) == 0) { + recv_cqe[recv_cqes++] = *cqe; + if (cqe->flags & IORING_CQE_F_MORE) { + io_uring_cqe_seen(&ring, cqe); + } else { + early_error = true; + io_uring_cqe_seen(&ring, cqe); + } + } + if (early_error) + break; + } + } + + close(fds[1]); + + /* allow sends to finish */ + usleep(1000); + + if ((args->stream && !early_error) || recv_cqes < min_cqes) { + ret = io_uring_wait_cqes(&ring, &cqe, 1, &timeout, NULL); + if (ret && ret != -ETIME) { + fprintf(stderr, "wait final failed: %d\n", ret); + ret = -1; + goto cleanup; + } + } + + while (io_uring_peek_cqe(&ring, &cqe) == 0) { + recv_cqe[recv_cqes++] = *cqe; + io_uring_cqe_seen(&ring, cqe); + } + + ret = -1; + at = &send_buff[0]; + if (recv_cqes < min_cqes) { + fprintf(stderr, "not enough cqes: have=%d vs %d\n", recv_cqes, min_cqes); + goto cleanup; + } + for (i = 0; i < recv_cqes; i++) { + bool const is_last = i == recv_cqes - 1; + int *this_recv; + + cqe = &recv_cqe[i]; + + if (cqe->res <= 0 || (args->stream && is_last)) { + if (!is_last) { + fprintf(stderr, "not last cqe had error %d\n", i); + goto cleanup; + } + + switch (args->early_error) { + case ERROR_NOT_ENOUGH_BUFFERS: + if (cqe->res != -ENOBUFS) { + fprintf(stderr, + "ERROR_NOT_ENOUGH_BUFFERS: res %d\n", cqe->res); + goto cleanup; + } + break; + case ERROR_EARLY_CLOSE_RECEIVER: + if (cqe->res != -ECANCELED) { + fprintf(stderr, + "ERROR_EARLY_CLOSE_RECEIVER: res %d\n", cqe->res); + goto cleanup; + } + break; + case ERROR_NONE: + case ERROR_EARLY_CLOSE_SENDER: + if (cqe->res != 0) { + fprintf(stderr, "early error: res %d\n", cqe->res); + goto cleanup; + } + break; + }; + + if (cqe->flags & IORING_CQE_F_BUFFER) { + fprintf(stderr, "final BUFFER flag set\n"); + goto cleanup; + } + + if (cqe->flags & IORING_CQE_F_MORE) { + fprintf(stderr, "final MORE flag set\n"); + goto cleanup; + } + + continue; + } + + total_recv_bytes += cqe->res; + if (!(cqe->flags & IORING_CQE_F_BUFFER)) { + fprintf(stderr, "BUFFER flag not set\n"); + goto cleanup; + } + if (!(cqe->flags & IORING_CQE_F_MORE)) { + fprintf(stderr, "MORE flag not set\n"); + goto cleanup; + } + if (cqe->res % 4 != 0) { + /* + * doesn't seem to happen in practice, would need some + * work to remove this requirement + */ + fprintf(stderr, "unexpectedly aligned buffer cqe->res=%d\n", cqe->res); + goto cleanup; + } + + /* check buffer arrived in order (for tcp) */ + this_recv = recv_buffs[cqe->flags >> 16]; + for (j = 0; args->stream && j < cqe->res / 4; j++) { + int sent = *at++; + int recv = *this_recv++; + + if (sent != recv) { + fprintf(stderr, "recv=%d sent=%d\n", recv, sent); + goto cleanup; + } + } + } + + if (args->early_error == ERROR_NONE && total_recv_bytes < total_sent_bytes) { + fprintf(stderr, + "missing recv: recv=%d sent=%d\n", total_recv_bytes, total_sent_bytes); + goto cleanup; + } + + /* check the final one */ + cqe = &recv_cqe[recv_cqes-1]; + + ret = 0; +cleanup: + for (i = 0; i < ARRAY_SIZE(recv_buffs); i++) + free(recv_buffs[i]); + close(fds[0]); + close(fds[1]); + io_uring_queue_exit(&ring); + + return ret; +} + +int main(int argc, char *argv[]) +{ + int ret; + int loop; + + if (argc > 1) + return 0; + + for (loop = 0; loop < 32; loop++) { + struct args a = { + .early_error = loop & 0x03, + .stream = loop & 0x04, + .recvmsg = loop & 0x08, + .wait_each = loop & 0x10, + }; + ret = test(&a); + if (ret) { + fprintf(stderr, + "test stream=%d recvmsg=%d wait_each=%d early_error=%d failed\n", + a.stream, a.recvmsg, a.wait_each, a.early_error); + return ret; + } + } + return 0; +} From patchwork Tue Jun 28 15:04:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Yudaken X-Patchwork-Id: 12898432 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01C46C43334 for ; Tue, 28 Jun 2022 15:04:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346939AbiF1PE2 (ORCPT ); Tue, 28 Jun 2022 11:04:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41006 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346420AbiF1PE1 (ORCPT ); Tue, 28 Jun 2022 11:04:27 -0400 Received: from mx0a-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3112B1D301 for ; Tue, 28 Jun 2022 08:04:27 -0700 (PDT) Received: from pps.filterd (m0089730.ppops.net [127.0.0.1]) by m0089730.ppops.net (8.17.1.5/8.17.1.5) with ESMTP id 25SAAOQ2003859 for ; Tue, 28 Jun 2022 08:04:26 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=facebook; bh=8Zq7TPZKc2rvmmmyQR5vr3oisDAOQmxH+0ESBN1iBbc=; b=Fhsj9C0L3qXs+h3mxeR6O9FE/D2LMEWnowcPXmiVr8bgliBB9G1sFQya5X24l+Fdd9Tn HXFSTCSjxxbgXWfHd0X1ijvU517+uEgtmm0NzgV273Mxgv6KfxXRlQ+HcavRbN/p+y0m rtYuCSpiqxTjhZcdy2LXLBp2dMxhK8eFTuk= Received: from mail.thefacebook.com ([163.114.132.120]) by m0089730.ppops.net (PPS) with ESMTPS id 3gywp2adku-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Tue, 28 Jun 2022 08:04:26 -0700 Received: from twshared5640.09.ash9.facebook.com (2620:10d:c085:108::8) by mail.thefacebook.com (2620:10d:c085:21d::4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Tue, 28 Jun 2022 08:04:24 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id C659C244BD5B; Tue, 28 Jun 2022 08:04:18 -0700 (PDT) From: Dylan Yudaken To: Jens Axboe , Pavel Begunkov , CC: , Dylan Yudaken Subject: [PATCH liburing 4/4] add IORING_RECV_MULTISHOT docs Date: Tue, 28 Jun 2022 08:04:14 -0700 Message-ID: <20220628150414.1386435-5-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220628150414.1386435-1-dylany@fb.com> References: <20220628150414.1386435-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-ORIG-GUID: q-Nj-DRe5frUqJeMNUvz1iup8Neenh5F X-Proofpoint-GUID: q-Nj-DRe5frUqJeMNUvz1iup8Neenh5F X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-06-28_08,2022-06-28_01,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org add appropriate docs to io_uring_prep_recvmsg/io_uring_prep_recv man pages Signed-off-by: Dylan Yudaken --- man/io_uring_prep_recv.3 | 15 +++++++++++++++ man/io_uring_prep_recvmsg.3 | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/man/io_uring_prep_recv.3 b/man/io_uring_prep_recv.3 index 993e331..f929ec8 100644 --- a/man/io_uring_prep_recv.3 +++ b/man/io_uring_prep_recv.3 @@ -60,6 +60,21 @@ operation. If set, the socket still had data to be read after the operation completed. Both these flags are available since 5.19. .P +.TP +.B IORING_RECV_MULTISHOT +If set, io_uring will post a new CQE whenever data is available to read. +The CQE will try and fill a provided buffer. +The +.B IORING_CQE_F_MORE +flag will be set if the receive is still active and more CQEs will be posted. + +It is required that the +.B IOSQE_BUFFER_SELECT +flag is set and that +.B MSG_WAITALL +is not set. +.P + .SH RETURN VALUE None .SH ERRORS diff --git a/man/io_uring_prep_recvmsg.3 b/man/io_uring_prep_recvmsg.3 index 8c49411..74bfbc8 100644 --- a/man/io_uring_prep_recvmsg.3 +++ b/man/io_uring_prep_recvmsg.3 @@ -61,6 +61,21 @@ operation. If set, the socket still had data to be read after the operation completed. Both these flags are available since 5.19. .P +.TP +.B IORING_RECV_MULTISHOT +If set, io_uring will post a new CQE whenever data is available to read. +The CQE will try and fill a provided buffer. +The +.B IORING_CQE_F_MORE +flag will be set if the receive is still active and more CQEs will be posted. + +It is required that the +.B IOSQE_BUFFER_SELECT +flag is set and that +.B MSG_WAITALL +is not set. +.P + .SH RETURN VALUE None .SH ERRORS