From patchwork Thu Jun 30 16:49: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: 12902028 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 0C425CCA47B for ; Thu, 30 Jun 2022 16:49:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233264AbiF3Qtz (ORCPT ); Thu, 30 Jun 2022 12:49:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52224 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235650AbiF3Qty (ORCPT ); Thu, 30 Jun 2022 12:49:54 -0400 Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9541A34BB5 for ; Thu, 30 Jun 2022 09:49:53 -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 25U7Upi3009340 for ; Thu, 30 Jun 2022 09:49:52 -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=53oXaBrbyxbuR+jliZ3ScyXLbRt6PukSFMYajnLqWxc=; b=TmHAkKEgh+udU2eznRuTfKjTnYMq/vTTv/euE1vDsMxygBQ4zLnIQekklxlbUOxa7JsM xC/1R3Pq9F+E/XkXEvh30WWw4ugXc7j6PC8s0BSrFbZbiujhsr0E+n0XOC/FPce+cKK8 6Eyv0WSx6LpajNnI3tlsMo2cvlA6aCrBaxY= Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h17geuvcf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 09:49:52 -0700 Received: from snc-exhub201.TheFacebook.com (2620:10d:c085:21d::7) by snc-exhub101.TheFacebook.com (2620:10d:c085:11d::5) 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 09:49:49 -0700 Received: from twshared17349.03.ash7.facebook.com (2620:10d:c085:108::8) 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 09:49:49 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id 514E025D4CD3; Thu, 30 Jun 2022 09:49:24 -0700 (PDT) From: Dylan Yudaken To: CC: , , , "Dylan Yudaken" Subject: [PATCH v3 liburing 1/7] add t_create_socket_pair Date: Thu, 30 Jun 2022 09:49:12 -0700 Message-ID: <20220630164918.3958710-2-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630164918.3958710-1-dylany@fb.com> References: <20220630164918.3958710-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-ORIG-GUID: VXrd4jywbxi4VGTnZ9yGMG9YP9gnu0m7 X-Proofpoint-GUID: VXrd4jywbxi4VGTnZ9yGMG9YP9gnu0m7 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_12,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 | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/helpers.h | 5 +++ 2 files changed, 95 insertions(+) diff --git a/test/helpers.c b/test/helpers.c index 491822e..3660cc0 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,89 @@ 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; + + 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 16:49: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: 12902027 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 5B1AAC43334 for ; Thu, 30 Jun 2022 16:49:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235593AbiF3Qtx (ORCPT ); Thu, 30 Jun 2022 12:49:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52192 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233264AbiF3Qtw (ORCPT ); Thu, 30 Jun 2022 12:49:52 -0400 Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BEE3531374 for ; Thu, 30 Jun 2022 09:49:51 -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 25U7Upi2009340 for ; Thu, 30 Jun 2022 09:49:51 -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=b+n+AfiNzS4tGmcFnpgsj009ejDkyUpshpyvX+4lm6k1mPvWZVco36uCVDsQKXFXuQ4T oTIm1E2Mm77t0aRWTzgPTcFsJAS2h1NAwYJKzvtLwlurPDson3GTC/a4QNwiuy692inC Px9tDH4Q1Y3sYQc22blr+2TPyKUc9t6N8lo= Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h17geuvc7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 09:49:50 -0700 Received: from twshared17349.03.ash7.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; Thu, 30 Jun 2022 09:49:49 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id 87F7925D4CDF; Thu, 30 Jun 2022 09:49:25 -0700 (PDT) From: Dylan Yudaken To: CC: , , , Dylan Yudaken Subject: [PATCH v3 liburing 2/7] add IORING_RECV_MULTISHOT to io_uring.h Date: Thu, 30 Jun 2022 09:49:13 -0700 Message-ID: <20220630164918.3958710-3-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630164918.3958710-1-dylany@fb.com> References: <20220630164918.3958710-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-ORIG-GUID: 5Wme4hk-tpcf95Jwe2oV7v28HlyOipJV X-Proofpoint-GUID: 5Wme4hk-tpcf95Jwe2oV7v28HlyOipJV 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_12,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 16:49: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: 12902026 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 DB3BAC43334 for ; Thu, 30 Jun 2022 16:49:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235557AbiF3Qtu (ORCPT ); Thu, 30 Jun 2022 12:49:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52152 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235593AbiF3Qtu (ORCPT ); Thu, 30 Jun 2022 12:49:50 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 71AC63524C for ; Thu, 30 Jun 2022 09:49:49 -0700 (PDT) Received: from pps.filterd (m0109333.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25UGWx9O000854 for ; Thu, 30 Jun 2022 09:49:48 -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=rDGGGVXRxy5C3BGY4+nMwdTChVhKn5+cJFeh1y/UOIY=; b=HxxH6QzW27G0hft6O7I08/py2w0tsEgwwzju/iYorw9NtazAHpzyfl3x4vUFNhw9sWpp GP15lmwaI0U7/v+PI3R4watuRSIxnO/BR8b03TjLxo7KHj2ipOBxtvGC0jI2T0nJFRM/ A/0AOb+A4ejTL9Ft4CJpU3CJKYRJl6g3gTs= Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h12ug4p3d-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 09:49:48 -0700 Received: from twshared22934.08.ash9.facebook.com (2620:10d:c085:108::8) by mail.thefacebook.com (2620:10d:c085:21d::5) 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 09:49:47 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id 4D67125D4CF0; Thu, 30 Jun 2022 09:49:26 -0700 (PDT) From: Dylan Yudaken To: CC: , , , Dylan Yudaken Subject: [PATCH v3 liburing 3/7] add io_uring_prep_(recv|recvmsg)_multishot Date: Thu, 30 Jun 2022 09:49:14 -0700 Message-ID: <20220630164918.3958710-4-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630164918.3958710-1-dylany@fb.com> References: <20220630164918.3958710-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: tS6ouvwuzGP-zjUFtDVhN7mz3yYezlPv X-Proofpoint-ORIG-GUID: tS6ouvwuzGP-zjUFtDVhN7mz3yYezlPv 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_12,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..b11d90e 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->ioprio |= 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->ioprio |= 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 16:49:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Yudaken X-Patchwork-Id: 12902031 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 AAAECC43334 for ; Thu, 30 Jun 2022 16:50:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235913AbiF3QuC (ORCPT ); Thu, 30 Jun 2022 12:50:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52294 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235832AbiF3QuB (ORCPT ); Thu, 30 Jun 2022 12:50:01 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 155D82FFD3 for ; Thu, 30 Jun 2022 09:50:01 -0700 (PDT) Received: from pps.filterd (m0109333.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25UGiISm032063 for ; Thu, 30 Jun 2022 09:50:00 -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=qMlpcEEA5fLCbgRbBxMffR7ffeyE56p3hkLoBwgyZBYRmejFbJaWvjja7ExjZZRvW8Nw G6KCZC8LBrX2b2xFvEW2rd6vifrHwoUuyCR8Dcws2KvyGleGSQxEYD70nfKsrNJbvfsT jdGmxarmqhtoSM2KRfBg+VKn6p2ImloOh2E= Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h12ug4p4w-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 09:50:00 -0700 Received: from twshared17349.03.ash7.facebook.com (2620:10d:c085:108::8) by mail.thefacebook.com (2620:10d:c085:21d::5) 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 09:50:00 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id CCD3825D4CF9; Thu, 30 Jun 2022 09:49:26 -0700 (PDT) From: Dylan Yudaken To: CC: , , , Dylan Yudaken Subject: [PATCH v3 liburing 4/7] add IORING_RECV_MULTISHOT docs Date: Thu, 30 Jun 2022 09:49:15 -0700 Message-ID: <20220630164918.3958710-5-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630164918.3958710-1-dylany@fb.com> References: <20220630164918.3958710-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: vc8YAIbHGS89CKwyAflKSHB9181G-fS3 X-Proofpoint-ORIG-GUID: vc8YAIbHGS89CKwyAflKSHB9181G-fS3 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_12,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 16:49: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: 12902030 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 34BA1C433EF for ; Thu, 30 Jun 2022 16:50:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235606AbiF3QuB (ORCPT ); Thu, 30 Jun 2022 12:50:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52276 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235832AbiF3QuA (ORCPT ); Thu, 30 Jun 2022 12:50:00 -0400 Received: from mx0a-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 442E5338B1 for ; Thu, 30 Jun 2022 09:49:59 -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 25U9O6gB005950 for ; Thu, 30 Jun 2022 09:49: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=BgsJG9kFUEMe2IR+vcew8VN1c9zibc9zH6+/i3pXAsw=; b=jkeZrA3dH2m65GQsZxmOQDF0fpvDpH/TFP8JqbGdUuwCyV2fF0sENcBT2IcA+4NQzyd5 ZM0rrQOd8dBKJxPkPIuMyPItKHhdMxi5LOmY13S4jwFguG7VbqKf7ufVtxpBBOFmJvWW 9FXBh2ySNx+cPMqxryuQ1vYxBuAYCql2Avo= Received: from mail.thefacebook.com ([163.114.132.120]) by m0089730.ppops.net (PPS) with ESMTPS id 3h195a2w8m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 09:49:58 -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 09:49:57 -0700 Received: from twshared18317.08.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 09:49:56 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id AE84825D4D25; Thu, 30 Jun 2022 09:49:27 -0700 (PDT) From: Dylan Yudaken To: CC: , , , "Dylan Yudaken" Subject: [PATCH v3 liburing 5/7] add recv-multishot test Date: Thu, 30 Jun 2022 09:49:16 -0700 Message-ID: <20220630164918.3958710-6-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630164918.3958710-1-dylany@fb.com> References: <20220630164918.3958710-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: -n-ma4hnEwbH2HSnDpI7gMXNrmAzMfMU X-Proofpoint-ORIG-GUID: -n-ma4hnEwbH2HSnDpI7gMXNrmAzMfMU 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_12,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 | 343 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 344 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..e91f585 --- /dev/null +++ b/test/recv-multishot.c @@ -0,0 +1,343 @@ +// 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 T_EXIT_SKIP; + + 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 T_EXIT_FAIL; + } + } + } + + return T_EXIT_PASS; +} From patchwork Thu Jun 30 16:49: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: 12902033 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 EBB8FC433EF for ; Thu, 30 Jun 2022 16:50:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235314AbiF3QuK (ORCPT ); Thu, 30 Jun 2022 12:50:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235969AbiF3QuI (ORCPT ); Thu, 30 Jun 2022 12:50:08 -0400 Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BB00B35269 for ; Thu, 30 Jun 2022 09:50:07 -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 25U7Upi8009340 for ; Thu, 30 Jun 2022 09:50:07 -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=fFG+TgftRUXXJ4MiTs++5u6JBu5pyFJeV6pr4jbHDdNWbGQeJWAjkB/EMIfh1wjhbg8R FgsrfUtQacVNCf2VyvRl0p1U+/yLPjuSwLEX9hxquxETdnDHpYZfJNTWkhAiGtslurUR oKGR/YcLf1bkLGsFRmcaCM6nLcqUEGulGOY= Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h17geuveg-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 09:50:06 -0700 Received: from twshared14577.08.ash8.facebook.com (2620:10d:c085:108::4) by mail.thefacebook.com (2620:10d:c085:11d::5) 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 09:50:05 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id 54C3725D4D2A; Thu, 30 Jun 2022 09:49:28 -0700 (PDT) From: Dylan Yudaken To: CC: , , , Dylan Yudaken Subject: [PATCH v3 liburing 6/7] add poll overflow test Date: Thu, 30 Jun 2022 09:49:17 -0700 Message-ID: <20220630164918.3958710-7-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630164918.3958710-1-dylany@fb.com> References: <20220630164918.3958710-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-ORIG-GUID: 980g7koY2YRVLDBloso6z4FyTU3E2xDz X-Proofpoint-GUID: 980g7koY2YRVLDBloso6z4FyTU3E2xDz 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_12,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 16:49: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: 12902032 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 1D9D5CCA480 for ; Thu, 30 Jun 2022 16:50:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235832AbiF3QuD (ORCPT ); Thu, 30 Jun 2022 12:50:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52296 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235869AbiF3QuC (ORCPT ); Thu, 30 Jun 2022 12:50:02 -0400 Received: from mx0a-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 773B531374 for ; Thu, 30 Jun 2022 09:50:01 -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 25UEqUT0009483 for ; Thu, 30 Jun 2022 09:50:00 -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=GGDmYmzdYFHXtdJ/X2my8lRJDSU+ZIVtZNTGjoYlbZdm2Hq1tMjOAkhAQCQoYuxNp9nO KaSP1eXWkTo+FAVODPwbK1nfjJtHk5LwcW9m9s1P34KUdIbLuMV7N+NjdT1or//hUUEb yNb8N/6me7hFBcpngtyrzTwfN85ox9hNIS4= Received: from mail.thefacebook.com ([163.114.132.120]) by m0001303.ppops.net (PPS) with ESMTPS id 3h10tfn8ev-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 09:50:00 -0700 Received: from twshared18317.08.ash9.facebook.com (2620:10d:c085:108::8) by mail.thefacebook.com (2620:10d:c085:11d::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 09:49:58 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id C218125D4D2F; Thu, 30 Jun 2022 09:49:29 -0700 (PDT) From: Dylan Yudaken To: CC: , , , Dylan Yudaken Subject: [PATCH v3 liburing 7/7] add accept with overflow test Date: Thu, 30 Jun 2022 09:49:18 -0700 Message-ID: <20220630164918.3958710-8-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630164918.3958710-1-dylany@fb.com> References: <20220630164918.3958710-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: dM1uYfqVuv__QbBI29OGrM_EHs1HihP4 X-Proofpoint-ORIG-GUID: dM1uYfqVuv__QbBI29OGrM_EHs1HihP4 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_12,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; }