From patchwork Thu Jun 30 09:14:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Yudaken X-Patchwork-Id: 12901505 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 1BED1CCA47B for ; Thu, 30 Jun 2022 09:18:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234365AbiF3JSy (ORCPT ); Thu, 30 Jun 2022 05:18:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43572 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234077AbiF3JSW (ORCPT ); Thu, 30 Jun 2022 05:18:22 -0400 Received: from mx0a-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E5A7D326DA for ; Thu, 30 Jun 2022 02:17:12 -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 25U0LaTH020297 for ; Thu, 30 Jun 2022 02:17:12 -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=kw2hROxNXcVgX9A3AmrUD0BzmiuGRxXk9nFKvmlem4A=; b=f6XQyX43BMfn5WIk1xOdDmHogXBrTaXkeA7qc8OuN9mAQkrYAVNExJW9I8k82q+IDA8g DoX46B+5ee43PCiLWShqD8lA1XCvD9C9bwcmJvS9zcwer19DzvV8Cs0k189KOoxrlUX7 fIBXneIXSyrtfAAsIsFHLtT1T+N8aJ/W+dQ= Received: from maileast.thefacebook.com ([163.114.130.16]) by m0089730.ppops.net (PPS) with ESMTPS id 3gywp2qpfq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 02:17:12 -0700 Received: from twshared25107.07.ash9.facebook.com (2620:10d:c0a8:1b::d) by mail.thefacebook.com (2620:10d:c0a8:82::f) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Thu, 30 Jun 2022 02:17:11 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id A9F8F259A04B; Thu, 30 Jun 2022 02:14:23 -0700 (PDT) From: Dylan Yudaken To: Jens Axboe , Pavel Begunkov , CC: , Dylan Yudaken Subject: [PATCH v2 liburing 1/7] add t_create_socket_pair Date: Thu, 30 Jun 2022 02:14:16 -0700 Message-ID: <20220630091422.1463570-2-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630091422.1463570-1-dylany@fb.com> References: <20220630091422.1463570-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-ORIG-GUID: 4FWxrdUIpbLi2MrIyL_e5v7ISKhZA-oz X-Proofpoint-GUID: 4FWxrdUIpbLi2MrIyL_e5v7ISKhZA-oz 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-30_05,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 3179687..fbfd7d1 100644 --- a/test/helpers.h +++ b/test/helpers.h @@ -59,6 +59,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 Thu Jun 30 09:14:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Yudaken X-Patchwork-Id: 12901508 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 6ED23C433EF for ; Thu, 30 Jun 2022 09:21:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234127AbiF3JVK (ORCPT ); Thu, 30 Jun 2022 05:21:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52270 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233807AbiF3JVH (ORCPT ); Thu, 30 Jun 2022 05:21:07 -0400 Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 086D735857 for ; Thu, 30 Jun 2022 02:20:59 -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 25U0LasQ021139 for ; Thu, 30 Jun 2022 02:20:58 -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=0f4ahnYUt8ydoIxJ6zpxIt7S/r5MsLBAmpBaN1S109s=; b=crXECv0gQkxAWtMWm5+fiRSas1oCR8tohOZNoDt5P1jGZR9Rzta/Jo2zqP7Ly6X6VqEZ 5XtANItKvsXVt6DsY7d4XLsn6Vv4YQg7iNEPVO5kdGaOacfZ56moWsVR0zS+eVUbDXkC HsfCcAl8l0tum1okoAVppI3tt5oEqPfnFQI= Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h0dgqs9bc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 02:20:57 -0700 Received: from twshared5640.09.ash9.facebook.com (2620:10d:c085:108::4) 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; Thu, 30 Jun 2022 02:20:56 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id B3B08259A04D; Thu, 30 Jun 2022 02:14:23 -0700 (PDT) From: Dylan Yudaken To: Jens Axboe , Pavel Begunkov , CC: , Dylan Yudaken Subject: [PATCH v2 liburing 2/7] add IORING_RECV_MULTISHOT to io_uring.h Date: Thu, 30 Jun 2022 02:14:17 -0700 Message-ID: <20220630091422.1463570-3-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630091422.1463570-1-dylany@fb.com> References: <20220630091422.1463570-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-ORIG-GUID: nYE2n4dLR1FwExaQEYAZdpPKQBMYD5U5 X-Proofpoint-GUID: nYE2n4dLR1FwExaQEYAZdpPKQBMYD5U5 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-30_05,2022-06-28_01,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org copy relevant part from include/uapi/linux/io_uring.h from for-5.20/io_uring branch Signed-off-by: Dylan Yudaken --- src/include/liburing/io_uring.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h index 0fd1f98..de42c54 100644 --- a/src/include/liburing/io_uring.h +++ b/src/include/liburing/io_uring.h @@ -244,8 +244,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 From patchwork Thu Jun 30 09:14:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Yudaken X-Patchwork-Id: 12901507 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 8CF84C43334 for ; Thu, 30 Jun 2022 09:21:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234191AbiF3JVH (ORCPT ); Thu, 30 Jun 2022 05:21:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234220AbiF3JVF (ORCPT ); Thu, 30 Jun 2022 05:21:05 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 28CA839B9D for ; Thu, 30 Jun 2022 02:20:57 -0700 (PDT) Received: from pps.filterd (m0044012.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25U0LdkC009999 for ; Thu, 30 Jun 2022 02:20:57 -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=ZxZLzix8Bi9Yk7IFNr2jDz73SkvYYif0j2TCkCI4q4A=; b=Cj8ubWHSadxNTZKSuAaNNz7y9u2RFXQ+MprisCWPvW9Rl5KM4ui1fKEGretJNuLKcCpf ketJgz/AHp0ahcZjsCkLwmOprXz9ctG2TLxMTbw5zlIo2KDLjFsNvJeDCZ8CTLqwGMZa 85YZDIccQglg5hBhBp3yVv6auOXYY6bohZ8= Received: from maileast.thefacebook.com ([163.114.130.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h0tdsd1hu-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 02:20:57 -0700 Received: from twshared22934.08.ash9.facebook.com (2620:10d:c0a8:1b::d) by mail.thefacebook.com (2620:10d:c0a8:83::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Thu, 30 Jun 2022 02:20:55 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id BCAC0259A051; Thu, 30 Jun 2022 02:14:23 -0700 (PDT) From: Dylan Yudaken To: Jens Axboe , Pavel Begunkov , CC: , Dylan Yudaken Subject: [PATCH v2 liburing 3/7] add io_uring_prep_(recv|recvmsg)_multishot Date: Thu, 30 Jun 2022 02:14:18 -0700 Message-ID: <20220630091422.1463570-4-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630091422.1463570-1-dylany@fb.com> References: <20220630091422.1463570-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-ORIG-GUID: 6FCWZ-n9FMBjmGu48LknjY9vvUYh6FP9 X-Proofpoint-GUID: 6FCWZ-n9FMBjmGu48LknjY9vvUYh6FP9 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-30_05,2022-06-28_01,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org Add a nice API for multishot recv and recvmsg. Signed-off-by: Dylan Yudaken --- src/include/liburing.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/include/liburing.h b/src/include/liburing.h index bb2fb87..d6db6e4 100644 --- a/src/include/liburing.h +++ b/src/include/liburing.h @@ -416,6 +416,14 @@ static inline void io_uring_prep_recvmsg(struct io_uring_sqe *sqe, int fd, sqe->msg_flags = flags; } +static inline void io_uring_prep_recvmsg_multishot(struct io_uring_sqe *sqe, + int fd, struct msghdr *msg, + unsigned flags) +{ + io_uring_prep_recvmsg(sqe, fd, msg, flags); + sqe->addr2 |= IORING_RECV_MULTISHOT; +} + static inline void io_uring_prep_sendmsg(struct io_uring_sqe *sqe, int fd, const struct msghdr *msg, unsigned flags) @@ -674,6 +682,14 @@ static inline void io_uring_prep_recv(struct io_uring_sqe *sqe, int sockfd, sqe->msg_flags = (__u32) flags; } +static inline void io_uring_prep_recv_multishot(struct io_uring_sqe *sqe, + int sockfd, void *buf, + size_t len, int flags) +{ + io_uring_prep_recv(sqe, sockfd, buf, len, flags); + sqe->addr2 |= IORING_RECV_MULTISHOT; +} + static inline void io_uring_prep_openat2(struct io_uring_sqe *sqe, int dfd, const char *path, struct open_how *how) { From patchwork Thu Jun 30 09:14:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Yudaken X-Patchwork-Id: 12901499 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 38C6DCCA47B for ; Thu, 30 Jun 2022 09:18:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234221AbiF3JSt (ORCPT ); Thu, 30 Jun 2022 05:18:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44086 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234117AbiF3JSW (ORCPT ); Thu, 30 Jun 2022 05:18:22 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 53F2530568 for ; Thu, 30 Jun 2022 02:17:12 -0700 (PDT) Received: from pps.filterd (m0044012.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25U0LcSe009946 for ; Thu, 30 Jun 2022 02:17:12 -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=irR6SvpVZVmqNleVY//aMIwUIQ3Atk0PQieAabl6Uxg=; b=cihsG1edLd8eUXc7vD+ndkkYosOhHYC1u0oaqsRFqOO3j8t2CzqI8KO5YBHXnXgvr6qB NmHhryDWw5u3X/R5bt8zwEZ79dPNr5TITa4LasESKrbInXwhty+5v6ezrmXBPFrbH7mN ttU5rSpDaM66OjvXq+Ku8tqNClcnqPlivZ4= Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h0tdsd116-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 02:17:12 -0700 Received: from snc-exhub201.TheFacebook.com (2620:10d:c085:21d::7) by snc-exhub102.TheFacebook.com (2620:10d:c085:11d::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Thu, 30 Jun 2022 02:17:11 -0700 Received: from twshared5640.09.ash9.facebook.com (2620:10d:c085:108::4) by mail.thefacebook.com (2620:10d:c085:21d::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Thu, 30 Jun 2022 02:17:11 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id C1E0C259A054; Thu, 30 Jun 2022 02:14:23 -0700 (PDT) From: Dylan Yudaken To: Jens Axboe , Pavel Begunkov , CC: , Dylan Yudaken Subject: [PATCH v2 liburing 4/7] add IORING_RECV_MULTISHOT docs Date: Thu, 30 Jun 2022 02:14:19 -0700 Message-ID: <20220630091422.1463570-5-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630091422.1463570-1-dylany@fb.com> References: <20220630091422.1463570-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-ORIG-GUID: YhpJ0m5Zaj5LPWiylp9gmMpaE34U1zmn X-Proofpoint-GUID: YhpJ0m5Zaj5LPWiylp9gmMpaE34U1zmn 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-30_05,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 | 22 ++++++++++++++++++++++ man/io_uring_prep_recv_multishot.3 | 1 + man/io_uring_prep_recvmsg.3 | 20 ++++++++++++++++++++ man/io_uring_prep_recvmsg_multishot.3 | 1 + 4 files changed, 44 insertions(+) create mode 120000 man/io_uring_prep_recv_multishot.3 create mode 120000 man/io_uring_prep_recvmsg_multishot.3 diff --git a/man/io_uring_prep_recv.3 b/man/io_uring_prep_recv.3 index 993e331..bcd3145 100644 --- a/man/io_uring_prep_recv.3 +++ b/man/io_uring_prep_recv.3 @@ -14,6 +14,12 @@ io_uring_prep_recv \- prepare a recv request .BI " void *" buf "," .BI " size_t " len "," .BI " int " flags ");" +.PP +.BI "void io_uring_prep_recv_multishot(struct io_uring_sqe *" sqe "," +.BI " int " sockfd "," +.BI " void *" buf "," +.BI " size_t " len "," +.BI " int " flags ");" .fi .SH DESCRIPTION .PP @@ -36,6 +42,22 @@ This function prepares an async request. See that man page for details on the arguments specified to this prep helper. +The multishot version allows the application to issue a single receive request, +which repeatedly posts a CQE when data is available. It requires length to be 0 +, the +.B IOSQE_BUFFER_SELECT +flag to be set and no +.B MSG_WAITALL +flag to be set. +Therefore each CQE will take a buffer out of a provided buffer pool for receiving. +The application should check the flags of each CQE, regardless of it's result. +If a posted CQE does not have the +.B IORING_CQE_F_MORE +flag set then the multishot receive will be done and the application should issue a +new request. +Multishot variants are available since kernel 5.20. + + After calling this function, additional io_uring internal modifier flags may be set in the SQE .I off diff --git a/man/io_uring_prep_recv_multishot.3 b/man/io_uring_prep_recv_multishot.3 new file mode 120000 index 0000000..71fe277 --- /dev/null +++ b/man/io_uring_prep_recv_multishot.3 @@ -0,0 +1 @@ +io_uring_prep_recv.3 \ No newline at end of file diff --git a/man/io_uring_prep_recvmsg.3 b/man/io_uring_prep_recvmsg.3 index 8c49411..24c68ce 100644 --- a/man/io_uring_prep_recvmsg.3 +++ b/man/io_uring_prep_recvmsg.3 @@ -15,6 +15,11 @@ io_uring_prep_recvmsg \- prepare a recvmsg request .BI " int " fd "," .BI " struct msghdr *" msg "," .BI " unsigned " flags ");" +.PP +.BI "void io_uring_prep_recvmsg_multishot(struct io_uring_sqe *" sqe "," +.BI " int " fd "," +.BI " struct msghdr *" msg "," +.BI " unsigned " flags ");" .fi .SH DESCRIPTION .PP @@ -37,6 +42,21 @@ This function prepares an async request. See that man page for details on the arguments specified to this prep helper. +The multishot version allows the application to issue a single receive request, +which repeatedly posts a CQE when data is available. It requires length to be 0 +, the +.B IOSQE_BUFFER_SELECT +flag to be set and no +.B MSG_WAITALL +flag to be set. +Therefore each CQE will take a buffer out of a provided buffer pool for receiving. +The application should check the flags of each CQE, regardless of it's result. +If a posted CQE does not have the +.B IORING_CQE_F_MORE +flag set then the multishot receive will be done and the application should issue a +new request. +Multishot variants are available since kernel 5.20. + After calling this function, additional io_uring internal modifier flags may be set in the SQE .I off diff --git a/man/io_uring_prep_recvmsg_multishot.3 b/man/io_uring_prep_recvmsg_multishot.3 new file mode 120000 index 0000000..cd9566f --- /dev/null +++ b/man/io_uring_prep_recvmsg_multishot.3 @@ -0,0 +1 @@ +io_uring_prep_recvmsg.3 \ No newline at end of file From patchwork Thu Jun 30 09:14:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Yudaken X-Patchwork-Id: 12901506 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 93DB7CCA481 for ; Thu, 30 Jun 2022 09:18:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233757AbiF3JS4 (ORCPT ); Thu, 30 Jun 2022 05:18:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234241AbiF3JS0 (ORCPT ); Thu, 30 Jun 2022 05:18:26 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A3387201A5 for ; Thu, 30 Jun 2022 02:17:21 -0700 (PDT) Received: from pps.filterd (m0148461.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25U4dbep001372 for ; Thu, 30 Jun 2022 02:17:21 -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=0Kdm69wPWm8gnba0Ex79OTnKsCnfQtGcYVgZAiRSJW4=; b=hMyMcxeQd7Wkab96eCykp9uFgnnXUJd/tCtdDwfkOE/6/Z9mi7PIrr9L++0PgWO1VRrM msz3LrkkaRKQ81Vw9bp74oFC2wU61DKnnS4MVr2P2kMbo2tE+Ob5FEaDVZPjrRpUxtPy LmBlnV6q8jGs/zeCtaDBqsYrr8Ro/I6WU3Y= Received: from maileast.thefacebook.com ([163.114.130.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h150e94n6-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 02:17:21 -0700 Received: from twshared18317.08.ash9.facebook.com (2620:10d:c0a8:1b::d) by mail.thefacebook.com (2620:10d:c0a8:82::e) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Thu, 30 Jun 2022 02:17:19 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id C779F259A056; Thu, 30 Jun 2022 02:14:23 -0700 (PDT) From: Dylan Yudaken To: Jens Axboe , Pavel Begunkov , CC: , Dylan Yudaken Subject: [PATCH v2 liburing 5/7] add recv-multishot test Date: Thu, 30 Jun 2022 02:14:20 -0700 Message-ID: <20220630091422.1463570-6-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630091422.1463570-1-dylany@fb.com> References: <20220630091422.1463570-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: 7Cg0kOx7YWvEb5W5O05DdCFmTnYBfrkT X-Proofpoint-ORIG-GUID: 7Cg0kOx7YWvEb5W5O05DdCFmTnYBfrkT 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-30_05,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 | 342 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 343 insertions(+) create mode 100644 test/recv-multishot.c diff --git a/test/Makefile b/test/Makefile index ad47d2d..e718583 100644 --- a/test/Makefile +++ b/test/Makefile @@ -125,6 +125,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..f1487b4 --- /dev/null +++ b/test/recv-multishot.c @@ -0,0 +1,342 @@ +// 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, + ERROR_EARLY_CLOSE_SENDER, + ERROR_EARLY_CLOSE_RECEIVER, + ERROR_EARLY_OVERFLOW, + ERROR_EARLY_LAST +}; + +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 N_CQE_OVERFLOW = 4; + 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)); + + if (args->early_error == ERROR_EARLY_OVERFLOW) { + struct io_uring_params params = { + .flags = IORING_SETUP_CQSIZE, + .cq_entries = N_CQE_OVERFLOW + }; + + ret = io_uring_queue_init_params(N_CQE_OVERFLOW, &ring, ¶ms); + } else { + 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_multishot(sqe, fds[0], &msg, 0); + } else { + io_uring_prep_recv_multishot(sqe, fds[0], NULL, 0, 0); + } + sqe->flags |= IOSQE_BUFFER_SELECT; + sqe->buf_group = 7; + 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++) { + cqe = &recv_cqe[i]; + + bool const is_last = i == recv_cqes - 1; + + bool const should_be_last = + (cqe->res <= 0) || + (args->stream && is_last) || + (args->early_error == ERROR_EARLY_OVERFLOW && + !args->wait_each && i == N_CQE_OVERFLOW); + int *this_recv; + + + if (should_be_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_OVERFLOW: + if (cqe->res < 0) { + fprintf(stderr, + "ERROR_EARLY_OVERFLOW: 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; + case ERROR_EARLY_LAST: + fprintf(stderr, "bad error_early\n"); + goto cleanup; + }; + + if (cqe->res <= 0 && 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; + } + + if (cqe->res <= 0) + continue; + } else { + if (!(cqe->flags & IORING_CQE_F_MORE)) { + fprintf(stderr, "MORE flag not set\n"); + goto cleanup; + } + } + + if (!(cqe->flags & IORING_CQE_F_BUFFER)) { + fprintf(stderr, "BUFFER flag not set\n"); + goto cleanup; + } + + total_recv_bytes += cqe->res; + 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; + int early_error = 0; + + if (argc > 1) + return 0; + + for (loop = 0; loop < 7; loop++) { + struct args a = { + .stream = loop & 0x01, + .recvmsg = loop & 0x02, + .wait_each = loop & 0x4, + }; + for (early_error = 0; early_error < ERROR_EARLY_LAST; early_error++) { + a.early_error = (enum early_error_t)early_error; + 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 Thu Jun 30 09:14:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Yudaken X-Patchwork-Id: 12901500 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 AA124C433EF for ; Thu, 30 Jun 2022 09:18:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234180AbiF3JSt (ORCPT ); Thu, 30 Jun 2022 05:18:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45118 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234215AbiF3JSY (ORCPT ); Thu, 30 Jun 2022 05:18:24 -0400 Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2AC4A3335F for ; Thu, 30 Jun 2022 02:17:15 -0700 (PDT) Received: from pps.filterd (m0109332.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25U0LaYq008138 for ; Thu, 30 Jun 2022 02:17:14 -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=qLdVoMa0kj/ezY488L/hv4CmRi0Qmg8ruKaqWcOmxtQ=; b=MoX18F58P8nxnYqXVhfqPXIRCCj/HD81uU2xaftehLsGD8w1YXPwv2axABPUCsuFdL/C wuPe7Sq1NnZjvs9nKtYKAwVLBDctMA63rUL7W4OvIXgeMIaxWDQmI2kI0MlnGl7blQku 5vEItnEVUYU1W1svoriKJ44voYjvQ/GZ7Zw= Received: from maileast.thefacebook.com ([163.114.130.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h0qgqxdw6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 02:17:14 -0700 Received: from twshared25478.08.ash9.facebook.com (2620:10d:c0a8:1b::d) by mail.thefacebook.com (2620:10d:c0a8:83::4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Thu, 30 Jun 2022 02:17:13 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id CCE25259A059; Thu, 30 Jun 2022 02:14:23 -0700 (PDT) From: Dylan Yudaken To: Jens Axboe , Pavel Begunkov , CC: , Dylan Yudaken Subject: [PATCH v2 liburing 6/7] add poll overflow test Date: Thu, 30 Jun 2022 02:14:21 -0700 Message-ID: <20220630091422.1463570-7-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630091422.1463570-1-dylany@fb.com> References: <20220630091422.1463570-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: 4zA1SvnqHKvQbJiFuXTLNzav8oZERDgN X-Proofpoint-ORIG-GUID: 4zA1SvnqHKvQbJiFuXTLNzav8oZERDgN 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-30_05,2022-06-28_01,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org Add a test that when CQE overflows, multishot poll doesn't give out of order completions. Signed-off-by: Dylan Yudaken --- test/Makefile | 1 + test/poll-mshot-overflow.c | 128 +++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 test/poll-mshot-overflow.c diff --git a/test/Makefile b/test/Makefile index e718583..9590e1e 100644 --- a/test/Makefile +++ b/test/Makefile @@ -117,6 +117,7 @@ test_srcs := \ poll-link.c \ poll-many.c \ poll-mshot-update.c \ + poll-mshot-overflow.c \ poll-ring.c \ poll-v-poll.c \ pollfree.c \ diff --git a/test/poll-mshot-overflow.c b/test/poll-mshot-overflow.c new file mode 100644 index 0000000..078df04 --- /dev/null +++ b/test/poll-mshot-overflow.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: MIT + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "liburing.h" + +int check_final_cqe(struct io_uring *ring) +{ + struct io_uring_cqe *cqe; + int count = 0; + bool signalled_no_more = false; + + while (!io_uring_peek_cqe(ring, &cqe)) { + if (cqe->user_data == 1) { + count++; + if (signalled_no_more) { + fprintf(stderr, "signalled no more!\n"); + return 1; + } + if (!(cqe->flags & IORING_CQE_F_MORE)) + signalled_no_more = true; + } else if (cqe->user_data != 3) { + fprintf(stderr, "%d: got unexpected %d\n", count, (int)cqe->user_data); + return 1; + } + io_uring_cqe_seen(ring, cqe); + } + + if (!count) { + fprintf(stderr, "no cqe\n"); + return 1; + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + struct io_uring_cqe *cqe; + struct io_uring_sqe *sqe; + struct io_uring ring; + int pipe1[2]; + int ret, i; + + if (argc > 1) + return 0; + + if (pipe(pipe1) != 0) { + perror("pipe"); + return 1; + } + + struct io_uring_params params = { + .flags = IORING_SETUP_CQSIZE, + .cq_entries = 2 + }; + + ret = io_uring_queue_init_params(2, &ring, ¶ms); + if (ret) { + fprintf(stderr, "ring setup failed: %d\n", ret); + return 1; + } + + sqe = io_uring_get_sqe(&ring); + if (!sqe) { + fprintf(stderr, "get sqe failed\n"); + return 1; + } + io_uring_prep_poll_multishot(sqe, pipe1[0], POLLIN); + io_uring_sqe_set_data64(sqe, 1); + + if (io_uring_cq_ready(&ring)) { + fprintf(stderr, "unexpected cqe\n"); + return 1; + } + + for (i = 0; i < 2; i++) { + sqe = io_uring_get_sqe(&ring); + io_uring_prep_nop(sqe); + io_uring_sqe_set_data64(sqe, 2); + io_uring_submit(&ring); + } + + do { + errno = 0; + ret = write(pipe1[1], "foo", 3); + } while (ret == -1 && errno == EINTR); + + if (ret <= 0) { + fprintf(stderr, "write failed: %d\n", errno); + return 1; + } + + /* should have 2 cqe + 1 overflow now, so take out two cqes */ + for (i = 0; i < 2; i++) { + if (io_uring_peek_cqe(&ring, &cqe)) { + fprintf(stderr, "unexpectedly no cqe\n"); + return 1; + } + if (cqe->user_data != 2) { + fprintf(stderr, "unexpected user_data\n"); + return 1; + } + io_uring_cqe_seen(&ring, cqe); + } + + /* now remove the poll */ + sqe = io_uring_get_sqe(&ring); + io_uring_prep_poll_remove(sqe, 1); + io_uring_sqe_set_data64(sqe, 3); + ret = io_uring_submit(&ring); + + if (ret != 1) { + fprintf(stderr, "bad poll remove\n"); + return 1; + } + + ret = check_final_cqe(&ring); + + return ret; +} From patchwork Thu Jun 30 09:14:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Yudaken X-Patchwork-Id: 12901511 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 DB263C433EF for ; Thu, 30 Jun 2022 09:21:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233092AbiF3JVZ (ORCPT ); Thu, 30 Jun 2022 05:21:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52638 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234240AbiF3JVR (ORCPT ); Thu, 30 Jun 2022 05:21:17 -0400 Received: from mx0a-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C971833EA9 for ; Thu, 30 Jun 2022 02:21:14 -0700 (PDT) Received: from pps.filterd (m0001303.ppops.net [127.0.0.1]) by m0001303.ppops.net (8.17.1.5/8.17.1.5) with ESMTP id 25U0LXUK009461 for ; Thu, 30 Jun 2022 02:21:08 -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=kwN9dS1xhM6SCKWqFGDi17BlRioTEFB/ozRN/PThJXM=; b=ais6d/3EpXv29nvJOzJ07WwXwEFeXltqaMHz+L4YOjq/xuYO4I5AAF5arijeZ5lvxoOr /IP/qaWne3vYfJZYyXH102AfWjET9rtz+7S5LsJPMG8sp37tZ4A6RCwmQb017BuHY85a d+JN2D6ok3tAKcDwgM4oVpQ8RET4AiOC5Tc= Received: from mail.thefacebook.com ([163.114.132.120]) by m0001303.ppops.net (PPS) with ESMTPS id 3h10tfjbvj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 02:21:08 -0700 Received: from snc-exhub201.TheFacebook.com (2620:10d:c085:21d::7) by snc-exhub204.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; Thu, 30 Jun 2022 02:21:07 -0700 Received: from twshared5640.09.ash9.facebook.com (2620:10d:c085:208::f) by mail.thefacebook.com (2620:10d:c085:21d::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Thu, 30 Jun 2022 02:21:07 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id D6631259A05C; Thu, 30 Jun 2022 02:14:23 -0700 (PDT) From: Dylan Yudaken To: Jens Axboe , Pavel Begunkov , CC: , Dylan Yudaken Subject: [PATCH v2 liburing 7/7] add accept with overflow test Date: Thu, 30 Jun 2022 02:14:22 -0700 Message-ID: <20220630091422.1463570-8-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630091422.1463570-1-dylany@fb.com> References: <20220630091422.1463570-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: yetBQQsOwIuPhjvBRHC2ruJN_CngLfce X-Proofpoint-ORIG-GUID: yetBQQsOwIuPhjvBRHC2ruJN_CngLfce 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-30_05,2022-06-28_01,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org add test to exercise the overflow codepath for multishot accept. this doesn't actually fail previously, but does at least exerceise the codepath and ensure that some invariants hold wrt flags and IORING_CQE_F_MORE. Signed-off-by: Dylan Yudaken --- test/accept.c | 129 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 101 insertions(+), 28 deletions(-) diff --git a/test/accept.c b/test/accept.c index 77e3ebc..0463173 100644 --- a/test/accept.c +++ b/test/accept.c @@ -24,6 +24,9 @@ #include "liburing.h" #define MAX_FDS 32 +#define NOP_USER_DATA (1LLU << 50) +#define INITIAL_USER_DATA 1000 + static int no_accept; static int no_accept_multi; @@ -39,6 +42,7 @@ struct accept_test_args { bool queue_accept_before_connect; bool multishot; int extra_loops; + bool overflow; }; static void close_fds(int fds[], int nr) @@ -86,6 +90,24 @@ static void queue_recv(struct io_uring *ring, int fd, bool fixed) sqe->flags |= IOSQE_FIXED_FILE; } +static void queue_accept_multishot(struct io_uring *ring, int fd, + int idx, bool fixed) +{ + struct io_uring_sqe *sqe = io_uring_get_sqe(ring); + int ret; + + if (fixed) + io_uring_prep_multishot_accept_direct(sqe, fd, + NULL, NULL, + 0); + else + io_uring_prep_multishot_accept(sqe, fd, NULL, NULL, 0); + + io_uring_sqe_set_data64(sqe, idx); + ret = io_uring_submit(ring); + assert(ret != -1); +} + static void queue_accept_conn(struct io_uring *ring, int fd, struct accept_test_args args) { @@ -93,40 +115,51 @@ static void queue_accept_conn(struct io_uring *ring, int fd, int ret; int fixed_idx = args.fixed ? 0 : -1; int count = 1 + args.extra_loops; - bool multishot = args.multishot; + + if (args.multishot) { + queue_accept_multishot(ring, fd, INITIAL_USER_DATA, args.fixed); + return; + } while (count--) { sqe = io_uring_get_sqe(ring); if (fixed_idx < 0) { - if (!multishot) - io_uring_prep_accept(sqe, fd, NULL, NULL, 0); - else - io_uring_prep_multishot_accept(sqe, fd, NULL, - NULL, 0); + io_uring_prep_accept(sqe, fd, NULL, NULL, 0); } else { - if (!multishot) - io_uring_prep_accept_direct(sqe, fd, NULL, NULL, - 0, fixed_idx); - else - io_uring_prep_multishot_accept_direct(sqe, fd, - NULL, NULL, - 0); + io_uring_prep_accept_direct(sqe, fd, NULL, NULL, + 0, fixed_idx); } - ret = io_uring_submit(ring); assert(ret != -1); } } -static int accept_conn(struct io_uring *ring, int fixed_idx, bool multishot) +static int accept_conn(struct io_uring *ring, int fixed_idx, int *multishot, int fd) { - struct io_uring_cqe *cqe; + struct io_uring_cqe *pcqe; + struct io_uring_cqe cqe; int ret; - ret = io_uring_wait_cqe(ring, &cqe); - assert(!ret); - ret = cqe->res; - io_uring_cqe_seen(ring, cqe); + do { + ret = io_uring_wait_cqe(ring, &pcqe); + assert(!ret); + cqe = *pcqe; + io_uring_cqe_seen(ring, pcqe); + } while (cqe.user_data == NOP_USER_DATA); + + if (*multishot) { + if (!(cqe.flags & IORING_CQE_F_MORE)) { + (*multishot)++; + queue_accept_multishot(ring, fd, *multishot, fixed_idx == 0); + } else { + if (cqe.user_data != *multishot) { + fprintf(stderr, "received multishot after told done!\n"); + return -ECANCELED; + } + } + } + + ret = cqe.res; if (fixed_idx >= 0) { if (ret > 0) { @@ -203,6 +236,32 @@ static int set_client_fd(struct sockaddr_in *addr) return fd; } +static void cause_overflow(struct io_uring *ring) +{ + int i, ret; + + for (i = 0; i < *ring->cq.kring_entries; i++) { + struct io_uring_sqe *sqe = io_uring_get_sqe(ring); + + io_uring_prep_nop(sqe); + io_uring_sqe_set_data64(sqe, NOP_USER_DATA); + ret = io_uring_submit(ring); + assert(ret != -1); + } + +} + +static void clear_overflow(struct io_uring *ring) +{ + struct io_uring_cqe *cqe; + + while (!io_uring_peek_cqe(ring, &cqe)) { + if (cqe->user_data != NOP_USER_DATA) + break; + io_uring_cqe_seen(ring, cqe); + } +} + static int test_loop(struct io_uring *ring, struct accept_test_args args, int recv_s0, @@ -215,15 +274,22 @@ static int test_loop(struct io_uring *ring, bool multishot = args.multishot; uint32_t multishot_mask = 0; int nr_fds = multishot ? MAX_FDS : 1; + int multishot_idx = multishot ? INITIAL_USER_DATA : 0; - for (i = 0; i < nr_fds; i++) + if (args.overflow) + cause_overflow(ring); + + for (i = 0; i < nr_fds; i++) { c_fd[i] = set_client_fd(addr); + if (args.overflow && i == nr_fds / 2) + clear_overflow(ring); + } if (!args.queue_accept_before_connect) queue_accept_conn(ring, recv_s0, args); for (i = 0; i < nr_fds; i++) { - s_fd[i] = accept_conn(ring, fixed ? 0 : -1, multishot); + s_fd[i] = accept_conn(ring, fixed ? 0 : -1, &multishot_idx, recv_s0); if (s_fd[i] == -EINVAL) { if (args.accept_should_error) goto out; @@ -527,14 +593,15 @@ static int test_accept(int count, bool before) return ret; } -static int test_multishot_accept(int count, bool before) +static int test_multishot_accept(int count, bool before, bool overflow) { struct io_uring m_io_uring; int ret; struct accept_test_args args = { .queue_accept_before_connect = before, .multishot = true, - .extra_loops = count - 1 + .extra_loops = count - 1, + .overflow = overflow }; if (no_accept_multi) @@ -779,15 +846,21 @@ int main(int argc, char *argv[]) return ret; } - ret = test_multishot_accept(1, false); + ret = test_multishot_accept(1, true, true); + if (ret) { + fprintf(stderr, "test_multishot_accept(1, false, true) failed\n"); + return ret; + } + + ret = test_multishot_accept(1, false, false); if (ret) { - fprintf(stderr, "test_multishot_accept(1, false) failed\n"); + fprintf(stderr, "test_multishot_accept(1, false, false) failed\n"); return ret; } - ret = test_multishot_accept(1, true); + ret = test_multishot_accept(1, true, false); if (ret) { - fprintf(stderr, "test_multishot_accept(1, true) failed\n"); + fprintf(stderr, "test_multishot_accept(1, true, false) failed\n"); return ret; }