From patchwork Fri Apr 14 22:55:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Wei X-Patchwork-Id: 13212003 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 D2DF1C77B72 for ; Fri, 14 Apr 2023 22:55:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229732AbjDNWzm (ORCPT ); Fri, 14 Apr 2023 18:55:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36296 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229689AbjDNWzl (ORCPT ); Fri, 14 Apr 2023 18:55:41 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 83EB46A5A for ; Fri, 14 Apr 2023 15:55:39 -0700 (PDT) Received: from pps.filterd (m0044012.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 33EMsmUE014098 for ; Fri, 14 Apr 2023 15:55:39 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meta.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=s2048-2021-q4; bh=z3Qc8FO01L5i6R5sSnUXjCilWfJvkzXufIavP/mVI54=; b=fvS+VH1iX/F1QCV1Hg3F9QJReW17aKtZI44XvMzlhHUMJu1IdM2JWV3KzwQ3qXYH97sV WNRPrtepNoWUMxeSpOP+G4Rqj+Y4bv93BT3cU+FK7zBaUMMuXhzSKByBke89MspP330x 1eQew6ADmKlS3/UZJC5G9IvAbe2CfVEr2opCJpmHGUeJTeuihZmjZZo/WBs8eBg8g1FE K4NEJh7Vo8Hr79SRwc+mY0ES45wSBYlCh/Kt4BqFvyXJPhLu3sqUn/8IjxMekVWmsiGQ Gj7MLUTQTfOu9pOapI280q257qpnRF8keDGrUgwQTg7wYnXxezoAfUpkw1V8YbUn49RU cA== Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3pxx7qnus0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Fri, 14 Apr 2023 15:55:39 -0700 Received: from twshared8568.05.ash9.facebook.com (2620:10d:c085:208::11) 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.2507.17; Fri, 14 Apr 2023 15:55:38 -0700 Received: by devbig023.atn6.facebook.com (Postfix, from userid 197530) id 8A56E8EDA822; Fri, 14 Apr 2023 15:55:30 -0700 (PDT) From: David Wei To: Jens Axboe , Pavel Begunkov CC: , David Wei Subject: [PATCH v3 1/2] liburing: add multishot timeout support Date: Fri, 14 Apr 2023 15:55:05 -0700 Message-ID: <20230414225506.4108955-2-davidhwei@meta.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230414225506.4108955-1-davidhwei@meta.com> References: <20230414225506.4108955-1-davidhwei@meta.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: 4acuHucErlc03anB6ckyaRzxxNvxX97v X-Proofpoint-ORIG-GUID: 4acuHucErlc03anB6ckyaRzxxNvxX97v X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.942,Hydra:6.0.573,FMLib:17.11.170.22 definitions=2023-04-14_14,2023-04-14_01,2023-02-09_01 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org Sync the new IORING_TIMEOUT_MULTISHOT flag with kernel. Add unit tests for multishot timeouts. Signed-off-by: David Wei --- src/include/liburing/io_uring.h | 1 + test/timeout.c | 263 ++++++++++++++++++++++++++++++++ 2 files changed, 264 insertions(+) diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h index ec068d4..3d3a63b 100644 --- a/src/include/liburing/io_uring.h +++ b/src/include/liburing/io_uring.h @@ -250,6 +250,7 @@ enum io_uring_op { #define IORING_TIMEOUT_REALTIME (1U << 3) #define IORING_LINK_TIMEOUT_UPDATE (1U << 4) #define IORING_TIMEOUT_ETIME_SUCCESS (1U << 5) +#define IORING_TIMEOUT_MULTISHOT (1U << 6) #define IORING_TIMEOUT_CLOCK_MASK (IORING_TIMEOUT_BOOTTIME | IORING_TIMEOUT_REALTIME) #define IORING_TIMEOUT_UPDATE_MASK (IORING_TIMEOUT_UPDATE | IORING_LINK_TIMEOUT_UPDATE) /* diff --git a/test/timeout.c b/test/timeout.c index 8c43832..6a9dd88 100644 --- a/test/timeout.c +++ b/test/timeout.c @@ -1327,6 +1327,235 @@ done: } +static int test_timeout_multishot(struct io_uring *ring) +{ + struct io_uring_cqe *cqe; + struct io_uring_sqe *sqe; + struct __kernel_timespec ts; + int ret; + + sqe = io_uring_get_sqe(ring); + if (!sqe) { + fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__); + goto err; + } + + msec_to_ts(&ts, TIMEOUT_MSEC); + io_uring_prep_timeout(sqe, &ts, 0, IORING_TIMEOUT_MULTISHOT); + io_uring_sqe_set_data(sqe, (void *) 1); + + ret = io_uring_submit(ring); + if (ret <= 0) { + fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret); + goto err; + } + + for (int i = 0; i < 2; i++) { + ret = io_uring_wait_cqe(ring, &cqe); + if (ret < 0) { + fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); + goto err; + } + + if (!(cqe->flags & IORING_CQE_F_MORE)) { + fprintf(stderr, "%s: flag not set in cqe\n", __FUNCTION__); + goto err; + } + + ret = cqe->res; + if (ret != -ETIME) { + fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret)); + goto err; + } + + io_uring_cqe_seen(ring, cqe); + } + + sqe = io_uring_get_sqe(ring); + if (!sqe) { + fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__); + goto err; + } + + io_uring_prep_timeout_remove(sqe, 1, 0); + io_uring_sqe_set_data(sqe, (void *) 2); + + ret = io_uring_submit(ring); + if (ret <= 0) { + fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret); + goto err; + } + + ret = io_uring_wait_cqe(ring, &cqe); + if (ret < 0) { + fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); + goto err; + } + + ret = cqe->res; + if (ret < 0) { + fprintf(stderr, "%s: remove failed: %s\n", __FUNCTION__, strerror(-ret)); + goto err; + } + + io_uring_cqe_seen(ring, cqe); + + ret = io_uring_wait_cqe(ring, &cqe); + if (ret < 0) { + fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); + goto err; + } + + ret = cqe->res; + if (ret != -ECANCELED) { + fprintf(stderr, "%s: timeout canceled: %s %llu\n", __FUNCTION__, strerror(-ret), cqe->user_data); + goto err; + } + + io_uring_cqe_seen(ring, cqe); + return 0; +err: + return 1; +} + + +static int test_timeout_multishot_nr(struct io_uring *ring) +{ + struct io_uring_cqe *cqe; + struct io_uring_sqe *sqe; + struct __kernel_timespec ts; + int ret; + + sqe = io_uring_get_sqe(ring); + if (!sqe) { + fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__); + goto err; + } + + msec_to_ts(&ts, TIMEOUT_MSEC); + io_uring_prep_timeout(sqe, &ts, 3, IORING_TIMEOUT_MULTISHOT); + io_uring_sqe_set_data(sqe, (void *) 1); + + ret = io_uring_submit(ring); + if (ret <= 0) { + fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret); + goto err; + } + + for (int i = 0; i < 3; i++) { + ret = io_uring_wait_cqe(ring, &cqe); + if (ret < 0) { + fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); + goto err; + } + + if (i < 2 && !(cqe->flags & IORING_CQE_F_MORE)) { + fprintf(stderr, "%s: flag not set in cqe\n", __FUNCTION__); + goto err; + } + if (i == 3 && (cqe->flags & IORING_CQE_F_MORE)) { + fprintf(stderr, "%s: flag set in cqe\n", __FUNCTION__); + goto err; + } + + ret = cqe->res; + if (ret != -ETIME) { + fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret)); + goto err; + } + + io_uring_cqe_seen(ring, cqe); + } + + msec_to_ts(&ts, 2 * TIMEOUT_MSEC); + ret = io_uring_wait_cqe_timeout(ring, &cqe, &ts); + if (ret != -ETIME) { + fprintf(stderr, "%s: wait completion timeout %s\n", __FUNCTION__, strerror(-ret)); + goto err; + } + + return 0; +err: + return 1; +} + + +static int test_timeout_multishot_overflow(struct io_uring *ring) +{ + struct io_uring_cqe *cqe; + struct io_uring_sqe *sqe; + struct __kernel_timespec ts; + int ret; + + sqe = io_uring_get_sqe(ring); + if (!sqe) { + fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__); + goto err; + } + + msec_to_ts(&ts, 10); + io_uring_prep_timeout(sqe, &ts, 0, IORING_TIMEOUT_MULTISHOT); + io_uring_sqe_set_data(sqe, (void *) 1); + + ret = io_uring_submit(ring); + if (ret <= 0) { + fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret); + goto err; + } + + ret = io_uring_wait_cqe(ring, &cqe); + if (ret < 0) { + fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); + goto err; + } + + ret = cqe->res; + if (ret != -ETIME) { + fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret)); + goto err; + } + + io_uring_cqe_seen(ring, cqe); + sleep(1); + + if (!((*ring->sq.kflags) & IORING_SQ_CQ_OVERFLOW)) { + goto err; + } + + /* multishot timer should be gone */ + sqe = io_uring_get_sqe(ring); + if (!sqe) { + fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__); + goto err; + } + + io_uring_prep_timeout_remove(sqe, 1, 0); + + ret = io_uring_submit(ring); + if (ret <= 0) { + fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret); + goto err; + } + + ret = io_uring_wait_cqe(ring, &cqe); + if (ret < 0) { + fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); + goto err; + } + + ret = cqe->res; + io_uring_cqe_seen(ring, cqe); + if (ret != -ETIME) { + fprintf(stderr, "%s: remove failed: %d %s\n", __FUNCTION__, ret, strerror(-ret)); + goto err; + } + + return 0; +err: + return 1; +} + + int main(int argc, char *argv[]) { struct io_uring ring, sqpoll_ring; @@ -1419,6 +1648,40 @@ int main(int argc, char *argv[]) return ret; } + ret = test_timeout_multishot(&ring); + if (ret) { + fprintf(stderr, "test_timeout_multishot failed\n"); + return ret; + } + + ret = test_timeout_multishot_nr(&ring); + if (ret) { + fprintf(stderr, "test_timeout_multishot_nr failed\n"); + return ret; + } + + /* io_uring_wait_cqe_timeout() may have left a timeout, reinit ring */ + io_uring_queue_exit(&ring); + ret = io_uring_queue_init(8, &ring, 0); + if (ret) { + fprintf(stderr, "ring setup failed\n"); + return 1; + } + + ret = test_timeout_multishot_overflow(&ring); + if (ret) { + fprintf(stderr, "test_timeout_multishot_overflow failed\n"); + return ret; + } + + /* io_uring_wait_cqe_timeout() may have left a timeout, reinit ring */ + io_uring_queue_exit(&ring); + ret = io_uring_queue_init(8, &ring, 0); + if (ret) { + fprintf(stderr, "ring setup failed\n"); + return 1; + } + ret = test_single_timeout_wait(&ring, &p); if (ret) { fprintf(stderr, "test_single_timeout_wait failed\n"); From patchwork Fri Apr 14 22:55:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Wei X-Patchwork-Id: 13212004 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 1848EC77B71 for ; Fri, 14 Apr 2023 22:55:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229774AbjDNWzo (ORCPT ); Fri, 14 Apr 2023 18:55:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36306 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229689AbjDNWzn (ORCPT ); Fri, 14 Apr 2023 18:55:43 -0400 Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 198D772BE for ; Fri, 14 Apr 2023 15:55:42 -0700 (PDT) Received: from pps.filterd (m0109331.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 33EMtIqZ010771 for ; Fri, 14 Apr 2023 15:55:41 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meta.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=s2048-2021-q4; bh=PWgpLMwEoeKsjWAD+ht5qN5ZNQcpQMzIXg7FG6zhkWY=; b=Hod5OUekIHH/ab392PwT4E08t/4eAm1n7R0qfhEkPTHIyyY852rbG6qTt2V8x4w4XF8+ QcI9ZjeMlEgSuBMYZEmIRdmFG2/UIq4R2AoO6TeDkr8WrHT71cDeJTBSpZs5l2Kkc86y N3CPo15s3Tk53dhDrfnLl/rIExenxWVhpuMn8WwKCIa5EfD7rqvppFOTRqzNnhzqoDtM WLPgoDHOMdZPRSpS7oMJwgNzRkMyT2Ra7JoLnfxt8eHdkUgcx1bwsQWm9ChIzY8t1e+o oUCjfUPxcSaKzTbvNhl0PaqfvLPLto+aoKCJ6CGMCb/jYTooWWDdafI1q9A0UruD/dkR /w== Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3pxx65wyt7-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Fri, 14 Apr 2023 15:55:41 -0700 Received: from twshared35445.38.frc1.facebook.com (2620:10d:c085:208::11) 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.2507.17; Fri, 14 Apr 2023 15:55:38 -0700 Received: by devbig023.atn6.facebook.com (Postfix, from userid 197530) id 65F128EDA890; Fri, 14 Apr 2023 15:55:33 -0700 (PDT) From: David Wei To: Jens Axboe , Pavel Begunkov CC: , David Wei Subject: [PATCH v3 2/2] liburing: update man page for multishot timeouts Date: Fri, 14 Apr 2023 15:55:06 -0700 Message-ID: <20230414225506.4108955-3-davidhwei@meta.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230414225506.4108955-1-davidhwei@meta.com> References: <20230414225506.4108955-1-davidhwei@meta.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-ORIG-GUID: NUbTDHJANE7AQyepHaqMawDAdDNrZHLm X-Proofpoint-GUID: NUbTDHJANE7AQyepHaqMawDAdDNrZHLm X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.942,Hydra:6.0.573,FMLib:17.11.170.22 definitions=2023-04-14_14,2023-04-14_01,2023-02-09_01 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org Signed-off-by: David Wei --- man/io_uring_prep_timeout.3 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/man/io_uring_prep_timeout.3 b/man/io_uring_prep_timeout.3 index bfb8791..f4036e6 100644 --- a/man/io_uring_prep_timeout.3 +++ b/man/io_uring_prep_timeout.3 @@ -51,6 +51,13 @@ Normally a timeout that triggers would return in a CQE .I res value. +.TP +.B IORING_TIMEOUT_MULTISHOT +The request will return multiple timeout completions. The completion flag +IORING_CQE_F_MORE is set if more timeouts are expected. The value specified in +.I count +is the number of repeats. A value of 0 means the timeout is indefinite and can +only be stopped by a removal request. .PP The timeout completion event will trigger if either the specified timeout has occurred, or the specified number of events to wait for have been posted