From patchwork Sun Jun 19 02:07:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Axboe X-Patchwork-Id: 12886525 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 236E1C43334 for ; Sun, 19 Jun 2022 02:07:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230417AbiFSCHW (ORCPT ); Sat, 18 Jun 2022 22:07:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51058 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230299AbiFSCHU (ORCPT ); Sat, 18 Jun 2022 22:07:20 -0400 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F37C1BE12 for ; Sat, 18 Jun 2022 19:07:19 -0700 (PDT) Received: by mail-pl1-x62c.google.com with SMTP id r1so6893722plo.10 for ; Sat, 18 Jun 2022 19:07:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qnYCdoubkpiLmSN6UHWGctyowhlzWD/sapXtgqX+VFE=; b=lJc6uK3jeelmmM32+nNdkmzTJV2Xd5/sH3yYHqM+OdfeeoNjzOyJ7m+uzES0jbRW64 J0b2J+W4pznHfMJmEe8M5Moy+Rn4avBV5bxhGdKX4nPqbdJp5neuYrJT8ZZlIwvnQ1RE qaFoVARme87pZCbsh/AN3crhcJHrtXEeb/SGfMO20q01eJvfWswTPmZfL1DZuZGSKnv1 mvKqv8kmPkdIsfu5pM+A/oxHT2AEbwTWI9e5E9mXgXIhT5m3K4Cg30ANHolOqat401kl P/OLvEzRrp0laq+yU2Ep1MIp3jGHlAAz//6hkb2wde1EeyfRYVKL+M9Rq37gMigGJG+l bFqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qnYCdoubkpiLmSN6UHWGctyowhlzWD/sapXtgqX+VFE=; b=VqeUnzrgBMmhqnWOF8eXWt2kLqiynaDbmG2NFgQz5XGo6CJYIC+tqcjJVL8TMBcBVy nYH+5gpmV3Y+fNgRPYkKmdYFOrOi3AejE9gsqn5g5+sc9PX0Se/kxLI+SzBCY1x8U456 NMyanW7JCU4zmoQtgOQz5tjoJjSuBHkyjqI/qWCxr44byWhJYh3EbUBauz6KoUScqohP 0ev0nOVhElIiVl/5nJiQys+aglmSzhkTC+z5B63cRiCfHZiu9dkNzlAsIhZndmAgYo8l MaJKE4pl1n+xeVdKxb3W0B2cfP4ktTZevmQ5ctyqZt58eBiQPdCxznHtnWQicq+SxaF2 ueqg== X-Gm-Message-State: AJIora9pj/pUlVXdF9eOfigdvBYPxVB3DJQyPpvz0ocki5n/dstCHI8v 7H0JkmG4JfpkfGMpOGZM1XAzv9QSuSpoGA== X-Google-Smtp-Source: AGRyM1vIYLZbNWw9werOyyeaXSe96iIjsZC7ZEb1SS7L20lSJLPNIJloZ0cJtDH2GSi31XNUVvO0Kw== X-Received: by 2002:a17:903:1d2:b0:168:e3b9:e62b with SMTP id e18-20020a17090301d200b00168e3b9e62bmr17098487plh.115.1655604439103; Sat, 18 Jun 2022 19:07:19 -0700 (PDT) Received: from localhost.localdomain ([198.8.77.157]) by smtp.gmail.com with ESMTPSA id p24-20020aa78618000000b0051c7038bd52sm6118598pfn.220.2022.06.18.19.07.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Jun 2022 19:07:18 -0700 (PDT) From: Jens Axboe To: io-uring@vger.kernel.org Cc: asml.silence@gmail.com, carter.li@eoitek.com, Jens Axboe Subject: [PATCH 1/3] io_uring: have cancelation API accept io_uring_task directly Date: Sat, 18 Jun 2022 20:07:13 -0600 Message-Id: <20220619020715.1327556-2-axboe@kernel.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220619020715.1327556-1-axboe@kernel.dk> References: <20220619020715.1327556-1-axboe@kernel.dk> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org We just use the io_kiocb passed in to find the io_uring_task, and we already pass in the ctx via cd->ctx anyway. Signed-off-by: Jens Axboe --- io_uring/cancel.c | 17 +++++++++-------- io_uring/cancel.h | 2 +- io_uring/timeout.c | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/io_uring/cancel.c b/io_uring/cancel.c index d1e7f5a955ab..500ee5f5fd23 100644 --- a/io_uring/cancel.c +++ b/io_uring/cancel.c @@ -77,15 +77,15 @@ static int io_async_cancel_one(struct io_uring_task *tctx, return ret; } -int io_try_cancel(struct io_kiocb *req, struct io_cancel_data *cd, +int io_try_cancel(struct io_uring_task *tctx, struct io_cancel_data *cd, unsigned issue_flags) { - struct io_ring_ctx *ctx = req->ctx; + struct io_ring_ctx *ctx = cd->ctx; int ret; - WARN_ON_ONCE(!io_wq_current_is_worker() && req->task != current); + WARN_ON_ONCE(!io_wq_current_is_worker() && tctx != current->io_uring); - ret = io_async_cancel_one(req->task->io_uring, cd); + ret = io_async_cancel_one(tctx, cd); /* * Fall-through even for -EALREADY, as we may have poll armed * that need unarming. @@ -104,7 +104,6 @@ int io_try_cancel(struct io_kiocb *req, struct io_cancel_data *cd, return ret; } - int io_async_cancel_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { struct io_cancel *cancel = io_kiocb_to_cmd(req); @@ -127,7 +126,8 @@ int io_async_cancel_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) return 0; } -static int __io_async_cancel(struct io_cancel_data *cd, struct io_kiocb *req, +static int __io_async_cancel(struct io_cancel_data *cd, + struct io_uring_task *tctx, unsigned int issue_flags) { bool all = cd->flags & (IORING_ASYNC_CANCEL_ALL|IORING_ASYNC_CANCEL_ANY); @@ -136,7 +136,7 @@ static int __io_async_cancel(struct io_cancel_data *cd, struct io_kiocb *req, int ret, nr = 0; do { - ret = io_try_cancel(req, cd, issue_flags); + ret = io_try_cancel(tctx, cd, issue_flags); if (ret == -ENOENT) break; if (!all) @@ -170,6 +170,7 @@ int io_async_cancel(struct io_kiocb *req, unsigned int issue_flags) .flags = cancel->flags, .seq = atomic_inc_return(&req->ctx->cancel_seq), }; + struct io_uring_task *tctx = req->task->io_uring; int ret; if (cd.flags & IORING_ASYNC_CANCEL_FD) { @@ -185,7 +186,7 @@ int io_async_cancel(struct io_kiocb *req, unsigned int issue_flags) cd.file = req->file; } - ret = __io_async_cancel(&cd, req, issue_flags); + ret = __io_async_cancel(&cd, tctx, issue_flags); done: if (ret < 0) req_set_fail(req); diff --git a/io_uring/cancel.h b/io_uring/cancel.h index 2338012a5b06..1bc7e917ce94 100644 --- a/io_uring/cancel.h +++ b/io_uring/cancel.h @@ -16,6 +16,6 @@ struct io_cancel_data { int io_async_cancel_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe); int io_async_cancel(struct io_kiocb *req, unsigned int issue_flags); -int io_try_cancel(struct io_kiocb *req, struct io_cancel_data *cd, +int io_try_cancel(struct io_uring_task *tctx, struct io_cancel_data *cd, unsigned int issue_flags); void init_hash_table(struct io_hash_table *table, unsigned size); diff --git a/io_uring/timeout.c b/io_uring/timeout.c index 557c637af158..a01480a9d29f 100644 --- a/io_uring/timeout.c +++ b/io_uring/timeout.c @@ -272,7 +272,7 @@ static void io_req_task_link_timeout(struct io_kiocb *req, bool *locked) .data = prev->cqe.user_data, }; - ret = io_try_cancel(req, &cd, issue_flags); + ret = io_try_cancel(req->task->io_uring, &cd, issue_flags); } io_req_set_res(req, ret ?: -ETIME, 0); io_req_complete_post(req); From patchwork Sun Jun 19 02:07:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Axboe X-Patchwork-Id: 12886526 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 72195CCA47C for ; Sun, 19 Jun 2022 02:07:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230299AbiFSCH2 (ORCPT ); Sat, 18 Jun 2022 22:07:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51064 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229697AbiFSCHV (ORCPT ); Sat, 18 Jun 2022 22:07:21 -0400 Received: from mail-pg1-x52e.google.com (mail-pg1-x52e.google.com [IPv6:2607:f8b0:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A7006357 for ; Sat, 18 Jun 2022 19:07:21 -0700 (PDT) Received: by mail-pg1-x52e.google.com with SMTP id e63so5767792pgc.5 for ; Sat, 18 Jun 2022 19:07:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yv80EaGMevOd0EuZa7EL3jvvNdNnZ4kzHEkhSFcBaU8=; b=5qVv5YkGGVF3DMT5SdkY7+ZDHmplg1YTMCeSV/jWWUj/xYhpNe5XoSRUJrrMPjjfr5 jUUfPuU3r2obt2cXxW34Ikttarvwlx1RigZn53hgkLPaaqutIt5zSKSq1G6lP+kLQhrD 5mMCOEoXDSFmQEYPfL49EFse7RrA0CK7oYwMtIOtpOpfc2n4rdTPuVfZhDzrh64r3Hgc JTgEqNARwuHZ0J/kg/XlnUGqO2LBGGNXnEBR78K2fPwtI4sli42t2yJMbAkx6EzIddgP 3fYVbG+qqpZQiA2YZ5q8fiqzWtl1xMy2czR0IdI1c8+MZQFSHE6Do6x6uLyXOpFibC+O lgoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yv80EaGMevOd0EuZa7EL3jvvNdNnZ4kzHEkhSFcBaU8=; b=uj1T7IFqT02mWuMCJYp5n3t9kzhEQhTIXIaC+O2wP5Gt1kxY3eWPPYr0nPkeNtDFK6 6J+gfimN3DxEHY4tZAxICuySCvrXIFdH99wKGo66YfnMR5DNlZsT+F/TqjljtLIf9Clr OyuW/XKp/MpBybWGvuzXXXXIq9lIAUsfEvh9fdLpf/scXpQRRZjx+MH/dQtykMtcLEBO jACQ5YRHt46Cr8a5DgAn8yV5GIIjsDf/jecc67BIosCt1NKjOd50rwrMuW0Gy8INSqq5 sonQz/feh+4M2iePXel6bLDmOai09PcEvyTYQgeRt25/86x53GT1HuNVvDscW5RJdFkf olkg== X-Gm-Message-State: AJIora990F+mV7HA285ii9ppEvVt8VPe5IzUIf9Zy4m7nxIaXlVPD8Df EF3lhcfbvZVnP77baa/Cz8xQtrAA4M6sow== X-Google-Smtp-Source: AGRyM1vO6HI/CP776uSaTlLma2fYLIzsNCXmUF1ag7tqRu185Mh+XhDebzpzosmy+GG2zCH0GY/3Fw== X-Received: by 2002:a63:d949:0:b0:408:870f:70d1 with SMTP id e9-20020a63d949000000b00408870f70d1mr15682446pgj.620.1655604440214; Sat, 18 Jun 2022 19:07:20 -0700 (PDT) Received: from localhost.localdomain ([198.8.77.157]) by smtp.gmail.com with ESMTPSA id p24-20020aa78618000000b0051c7038bd52sm6118598pfn.220.2022.06.18.19.07.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Jun 2022 19:07:19 -0700 (PDT) From: Jens Axboe To: io-uring@vger.kernel.org Cc: asml.silence@gmail.com, carter.li@eoitek.com, Jens Axboe Subject: [PATCH 2/3] io_uring: add IORING_ASYNC_CANCEL_FD_FIXED cancel flag Date: Sat, 18 Jun 2022 20:07:14 -0600 Message-Id: <20220619020715.1327556-3-axboe@kernel.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220619020715.1327556-1-axboe@kernel.dk> References: <20220619020715.1327556-1-axboe@kernel.dk> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org In preparation for not having a request to pass in that carries this state, add a separate cancelation flag that allows the caller to ask for a fixed file for cancelation. Signed-off-by: Jens Axboe --- include/uapi/linux/io_uring.h | 2 ++ io_uring/cancel.c | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index 8715f0942ec2..d69dac9bb02c 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -244,10 +244,12 @@ enum io_uring_op { * IORING_ASYNC_CANCEL_FD Key off 'fd' for cancelation rather than the * request 'user_data' * IORING_ASYNC_CANCEL_ANY Match any request + * IORING_ASYNC_CANCEL_FD_FIXED 'fd' passed in is a fixed descriptor */ #define IORING_ASYNC_CANCEL_ALL (1U << 0) #define IORING_ASYNC_CANCEL_FD (1U << 1) #define IORING_ASYNC_CANCEL_ANY (1U << 2) +#define IORING_ASYNC_CANCEL_FD_FIXED (1U << 3) /* * send/sendmsg and recv/recvmsg flags (sqe->addr2) diff --git a/io_uring/cancel.c b/io_uring/cancel.c index 500ee5f5fd23..da486de07029 100644 --- a/io_uring/cancel.c +++ b/io_uring/cancel.c @@ -24,7 +24,7 @@ struct io_cancel { }; #define CANCEL_FLAGS (IORING_ASYNC_CANCEL_ALL | IORING_ASYNC_CANCEL_FD | \ - IORING_ASYNC_CANCEL_ANY) + IORING_ASYNC_CANCEL_ANY | IORING_ASYNC_CANCEL_FD_FIXED) static bool io_cancel_cb(struct io_wq_work *work, void *data) { @@ -174,11 +174,14 @@ int io_async_cancel(struct io_kiocb *req, unsigned int issue_flags) int ret; if (cd.flags & IORING_ASYNC_CANCEL_FD) { - if (req->flags & REQ_F_FIXED_FILE) + if (req->flags & REQ_F_FIXED_FILE || + cd.flags & IORING_ASYNC_CANCEL_FD_FIXED) { + req->flags |= REQ_F_FIXED_FILE; req->file = io_file_get_fixed(req, cancel->fd, issue_flags); - else + } else { req->file = io_file_get_normal(req, cancel->fd); + } if (!req->file) { ret = -EBADF; goto done; From patchwork Sun Jun 19 02:07:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Axboe X-Patchwork-Id: 12886527 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 82AD4CCA473 for ; Sun, 19 Jun 2022 02:07:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229697AbiFSCH2 (ORCPT ); Sat, 18 Jun 2022 22:07:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51076 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231405AbiFSCHX (ORCPT ); Sat, 18 Jun 2022 22:07:23 -0400 Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 28A72BE12 for ; Sat, 18 Jun 2022 19:07:22 -0700 (PDT) Received: by mail-pj1-x1033.google.com with SMTP id b12-20020a17090a6acc00b001ec2b181c98so6135621pjm.4 for ; Sat, 18 Jun 2022 19:07:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=i/gZKEItjgM5ODXShu2bv021xYTS6+ZaZ035kwYe5/M=; b=atB+TAFqKYVH7BLdHqxTVpVEg6DaQqomkNNuNKLjHRwQuMUTiqFpyfm6H4SGC0apIf Oa9cxy0JvnpXSsyv/j1gfXbD35ar+Bh5mqdf0+Tu4PakvxLimzXJUbFBhlVU1NX4QR2k q2OCnSbXllI8dtliZlP9yTU1VILYeSJjcqpe5gex1K0OpT7zLIp5T/yGtcdHTw92UMvD KQkJhwymEfCtY07jDUa3vkqGqCd7ePAgMpHYu/1m1CcLvowJA7QtlYIStSmGeffvRlyY HvtnIAXVgrnoE+/J63qs9UsfjP0cyjsde1vcP03xwshuU14rpgnUwLCNs/Rh9VzzsEOc CdVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=i/gZKEItjgM5ODXShu2bv021xYTS6+ZaZ035kwYe5/M=; b=uIDVEUyBgcIbwNx/INrzOmuhyGvPKGDuzItj6Aa0zH5ck9pMwk1fy8tFgY2vL72xia 3cfPw2ao1jZC/8ZI/AbdC4oheBovemBHK+jbnBVBCIP5q/kMVTd37Jx2S97XzaEt76bP Luu5kSas5WF1B90uJUYhXostJKB0/dJWCwb4pwuE8Hcs0uDr647LNF6XaEaZ+CdDRHvp 2dthO95Ayhe6kbdF1OhMLsf9gyjzou5ZGxLouDyAdb3o8PIIGqZ2R+95iv1eWm6G0OAB KQR3fL8Qd1aXKU77U/Y5Z6/YVVQU/DP8w+U5EIcEYQ167lWQNbC6Vhp7ZHdx44QVevCA s1Qg== X-Gm-Message-State: AJIora8xtRAHp3OjsiWEyc6i9KevTghKXpDSVNYAceicljMFsZe2a5ks l3FzGCu458dcgkxXLosAxtdVGLSVtxT4PQ== X-Google-Smtp-Source: AGRyM1sE0FjanCZEkGK183Iu+p3FH2gU6Oi43uuik4YZkDpMhqdtGtautfwbTbT38dahQZq34WrRWg== X-Received: by 2002:a17:90b:4c85:b0:1e5:42ef:a921 with SMTP id my5-20020a17090b4c8500b001e542efa921mr29859884pjb.75.1655604441282; Sat, 18 Jun 2022 19:07:21 -0700 (PDT) Received: from localhost.localdomain ([198.8.77.157]) by smtp.gmail.com with ESMTPSA id p24-20020aa78618000000b0051c7038bd52sm6118598pfn.220.2022.06.18.19.07.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Jun 2022 19:07:20 -0700 (PDT) From: Jens Axboe To: io-uring@vger.kernel.org Cc: asml.silence@gmail.com, carter.li@eoitek.com, Jens Axboe Subject: [PATCH 3/3] io_uring: add sync cancelation API through io_uring_register() Date: Sat, 18 Jun 2022 20:07:15 -0600 Message-Id: <20220619020715.1327556-4-axboe@kernel.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220619020715.1327556-1-axboe@kernel.dk> References: <20220619020715.1327556-1-axboe@kernel.dk> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org The io_uring cancelation API is async, like any other API that we expose there. For the case of finding a request to cancel, or not finding one, it is fully sync in that when submission returns, the CQE for both the cancelation request and the targeted request have been posted to the CQ ring. However, if the targeted work is being executed by io-wq, the API can only start the act of canceling it. This makes it difficult to use in some circumstances, as the caller then has to wait for the CQEs to come in and match on the same cancelation data there. Provide a IORING_REGISTER_SYNC_CANCEL command for io_uring_register() that does sync cancelations, always. For the io-wq case, it'll wait for the cancelation to come in before returning. The only expected returns from this API is: 0 Request found and canceled fine. > 0 Requests found and canceled. Only happens if asked to cancel multiple requests, and if the work wasn't in progress. -ENOENT Request not found. -ETIME A timeout on the operation was requested, but the timeout expired before we could cancel. and we won't get -EALREADY via this API. If the timeout value passed in is -1 (tv_sec and tv_nsec), then that means that no timeout is requested. Otherwise, the timespec passed in is the amount of time the sync cancel will wait for a successful cancelation. Link: https://github.com/axboe/liburing/discussions/608 Signed-off-by: Jens Axboe --- include/uapi/linux/io_uring.h | 15 +++++ io_uring/cancel.c | 107 ++++++++++++++++++++++++++++++++++ io_uring/cancel.h | 2 + io_uring/io_uring.c | 6 ++ 4 files changed, 130 insertions(+) diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index d69dac9bb02c..09e7c3b13d2d 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -10,6 +10,7 @@ #include #include +#include /* * IO submission data structure (Submission Queue Entry) @@ -425,6 +426,9 @@ enum { IORING_REGISTER_PBUF_RING = 22, IORING_UNREGISTER_PBUF_RING = 23, + /* sync cancelation API */ + IORING_REGISTER_SYNC_CANCEL = 24, + /* this goes last */ IORING_REGISTER_LAST }; @@ -560,4 +564,15 @@ struct io_uring_getevents_arg { __u64 ts; }; +/* + * Argument for IORING_REGISTER_SYNC_CANCEL + */ +struct io_uring_sync_cancel_reg { + __u64 addr; + __s32 fd; + __u32 flags; + struct __kernel_timespec timeout; + __u64 pad[4]; +}; + #endif diff --git a/io_uring/cancel.c b/io_uring/cancel.c index da486de07029..78b5a3088ab3 100644 --- a/io_uring/cancel.c +++ b/io_uring/cancel.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -206,3 +207,109 @@ void init_hash_table(struct io_hash_table *table, unsigned size) INIT_HLIST_HEAD(&table->hbs[i].list); } } + +static int __io_sync_cancel(struct io_uring_task *tctx, + struct io_cancel_data *cd, int fd) +{ + struct io_ring_ctx *ctx = cd->ctx; + + /* fixed must be grabbed every time since we drop the uring_lock */ + if ((cd->flags & IORING_ASYNC_CANCEL_FD) && + (cd->flags & IORING_ASYNC_CANCEL_FD_FIXED)) { + unsigned long file_ptr; + + if (unlikely(fd > ctx->nr_user_files)) + return -EBADF; + fd = array_index_nospec(fd, ctx->nr_user_files); + file_ptr = io_fixed_file_slot(&ctx->file_table, fd)->file_ptr; + cd->file = (struct file *) (file_ptr & FFS_MASK); + if (!cd->file) + return -EBADF; + } + + return __io_async_cancel(cd, tctx, 0); +} + +int io_sync_cancel(struct io_ring_ctx *ctx, void __user *arg) + __must_hold(&ctx->uring_lock) +{ + struct io_cancel_data cd = { + .ctx = ctx, + .seq = atomic_inc_return(&ctx->cancel_seq), + }; + ktime_t timeout = KTIME_MAX; + struct io_uring_sync_cancel_reg sc; + struct fd f = { }; + DEFINE_WAIT(wait); + int ret; + + if (copy_from_user(&sc, arg, sizeof(sc))) + return -EFAULT; + if (sc.flags & ~CANCEL_FLAGS) + return -EINVAL; + if (sc.pad[0] || sc.pad[1] || sc.pad[2] || sc.pad[3]) + return -EINVAL; + + cd.data = sc.addr; + cd.flags = sc.flags; + + /* we can grab a normal file descriptor upfront */ + if ((cd.flags & IORING_ASYNC_CANCEL_FD) && + !(cd.flags & IORING_ASYNC_CANCEL_FD_FIXED)) { + f = fdget(sc.fd); + if (!f.file) + return -EBADF; + cd.file = f.file; + } + + ret = __io_sync_cancel(current->io_uring, &cd, sc.fd); + + /* found something, done! */ + if (ret != -EALREADY) + goto out; + + if (sc.timeout.tv_sec != -1UL || sc.timeout.tv_nsec != -1UL) { + struct timespec64 ts = { + .tv_sec = sc.timeout.tv_sec, + .tv_nsec = sc.timeout.tv_nsec + }; + + timeout = ktime_add_ns(timespec64_to_ktime(ts), ktime_get_ns()); + } + + /* + * Keep looking until we get -ENOENT. we'll get woken everytime + * every time a request completes and will retry the cancelation. + */ + do { + cd.seq = atomic_inc_return(&ctx->cancel_seq), + + prepare_to_wait(&ctx->cq_wait, &wait, TASK_INTERRUPTIBLE); + + ret = __io_sync_cancel(current->io_uring, &cd, sc.fd); + + if (ret != -EALREADY) + break; + + mutex_unlock(&ctx->uring_lock); + ret = io_run_task_work_sig(); + if (ret < 0) { + mutex_lock(&ctx->uring_lock); + break; + } + ret = schedule_hrtimeout(&timeout, HRTIMER_MODE_ABS); + mutex_lock(&ctx->uring_lock); + if (!ret) { + ret = -ETIME; + break; + } + } while (1); + + finish_wait(&ctx->cq_wait, &wait); + + if (ret == -ENOENT || ret > 0) + ret = 0; +out: + fdput(f); + return ret; +} diff --git a/io_uring/cancel.h b/io_uring/cancel.h index 1bc7e917ce94..6a59ee484d0c 100644 --- a/io_uring/cancel.h +++ b/io_uring/cancel.h @@ -19,3 +19,5 @@ int io_async_cancel(struct io_kiocb *req, unsigned int issue_flags); int io_try_cancel(struct io_uring_task *tctx, struct io_cancel_data *cd, unsigned int issue_flags); void init_hash_table(struct io_hash_table *table, unsigned size); + +int io_sync_cancel(struct io_ring_ctx *ctx, void __user *arg); diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 430e65494989..8abb841e424d 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -3911,6 +3911,12 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode, break; ret = io_unregister_pbuf_ring(ctx, arg); break; + case IORING_REGISTER_SYNC_CANCEL: + ret = -EINVAL; + if (!arg || nr_args != 1) + break; + ret = io_sync_cancel(ctx, arg); + break; default: ret = -EINVAL; break;