From patchwork Thu Nov 7 11:01:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 13866164 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A74CE1F1307 for ; Thu, 7 Nov 2024 11:02:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977330; cv=none; b=rjjRgSIfmraBebWfK25DQ8BtpYtS1i2AJjOfBkp6LJpfJvSPaDt/YYyHdYfjZsyy2EmSV1w+NQmE3cE/zYsSS8WUOLVZ/b26YCB5OHnMFTmtKfNV4zmjCTDZO5wd/HkLuD0rDHm97KKqqjKM3lVYjT2w4AX/ulUjtUqkAIg+bAc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977330; c=relaxed/simple; bh=KY21aSsoFkGld7gyEg4MUjE1GyRUFEzYi83bmiL8ReI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WsbjA8CzKVfOcrSr1nB3JyZqYEmI2BX4/++mJdxfaEybve1wS5y7qEU4iX7nva6rXZLv5zFz3MBoTx8eCG5hrn0Yatnhm47VyYWDFeEqPf/nFnvzw45nR1Em0OpbxT8IfOnr3kB5g+sngfVskTSu8Ic1OIuTife8QfFcxVt8qcw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=NDvwxpqF; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="NDvwxpqF" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730977327; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=E8xUGMnZYEgZHyzVejIyogI+0ROjG4G+oQC0qzqNcP0=; b=NDvwxpqF7At9qLeoSWv8nnAIz9q6lMeZxL7iJ0soj4c+V/auYK9Zr2F0p2xcDZ6bDIsZLq Kh5HJfjLezPJqC7nJvwLcjSzBSvF33PdkhisH2oUlPR8jBt9OmLZ/wokKtv9UmIsTnZ4w0 X3IZE4HB3V+p+XhCEXTIJt9OPj7FMCM= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-294-cnZAQ5mINmSqz0u0O5NA8A-1; Thu, 07 Nov 2024 06:02:04 -0500 X-MC-Unique: cnZAQ5mINmSqz0u0O5NA8A-1 X-Mimecast-MFC-AGG-ID: cnZAQ5mINmSqz0u0O5NA8A Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 19F4819560B1; Thu, 7 Nov 2024 11:02:03 +0000 (UTC) Received: from localhost (unknown [10.72.116.54]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id C0CB51955F3D; Thu, 7 Nov 2024 11:02:01 +0000 (UTC) From: Ming Lei To: Jens Axboe , io-uring@vger.kernel.org, Pavel Begunkov Cc: linux-block@vger.kernel.org, Uday Shankar , Akilesh Kailash , Ming Lei Subject: [PATCH V10 01/12] io_uring/rsrc: pass 'struct io_ring_ctx' reference to rsrc helpers Date: Thu, 7 Nov 2024 19:01:34 +0800 Message-ID: <20241107110149.890530-2-ming.lei@redhat.com> In-Reply-To: <20241107110149.890530-1-ming.lei@redhat.com> References: <20241107110149.890530-1-ming.lei@redhat.com> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 `io_rsrc_node` instance won't be shared among different io_uring ctxs, and its allocation 'ctx' is always same with the user's 'ctx', so it is safe to pass user 'ctx' reference to rsrc helpers. Even in io_clone_buffers(), `io_rsrc_node` instance is allocated actually for destination io_uring_ctx. Then io_rsrc_node_ctx() can be removed, and the 8 bytes `ctx` pointer will be removed from `io_rsrc_node` in the following patch. Signed-off-by: Ming Lei --- io_uring/filetable.c | 13 +++++++------ io_uring/filetable.h | 4 ++-- io_uring/rsrc.c | 24 +++++++++++------------- io_uring/rsrc.h | 22 +++++++++------------- io_uring/splice.c | 2 +- 5 files changed, 30 insertions(+), 35 deletions(-) diff --git a/io_uring/filetable.c b/io_uring/filetable.c index 45f005f5db42..a21660e3145a 100644 --- a/io_uring/filetable.c +++ b/io_uring/filetable.c @@ -36,20 +36,21 @@ static int io_file_bitmap_get(struct io_ring_ctx *ctx) return -ENFILE; } -bool io_alloc_file_tables(struct io_file_table *table, unsigned nr_files) +bool io_alloc_file_tables(struct io_ring_ctx *ctx, struct io_file_table *table, + unsigned nr_files) { if (io_rsrc_data_alloc(&table->data, nr_files)) return false; table->bitmap = bitmap_zalloc(nr_files, GFP_KERNEL_ACCOUNT); if (table->bitmap) return true; - io_rsrc_data_free(&table->data); + io_rsrc_data_free(ctx, &table->data); return false; } -void io_free_file_tables(struct io_file_table *table) +void io_free_file_tables(struct io_ring_ctx *ctx, struct io_file_table *table) { - io_rsrc_data_free(&table->data); + io_rsrc_data_free(ctx, &table->data); bitmap_free(table->bitmap); table->bitmap = NULL; } @@ -71,7 +72,7 @@ static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file, if (!node) return -ENOMEM; - if (!io_reset_rsrc_node(&ctx->file_table.data, slot_index)) + if (!io_reset_rsrc_node(ctx, &ctx->file_table.data, slot_index)) io_file_bitmap_set(&ctx->file_table, slot_index); ctx->file_table.data.nodes[slot_index] = node; @@ -130,7 +131,7 @@ int io_fixed_fd_remove(struct io_ring_ctx *ctx, unsigned int offset) node = io_rsrc_node_lookup(&ctx->file_table.data, offset); if (!node) return -EBADF; - io_reset_rsrc_node(&ctx->file_table.data, offset); + io_reset_rsrc_node(ctx, &ctx->file_table.data, offset); io_file_bitmap_clear(&ctx->file_table, offset); return 0; } diff --git a/io_uring/filetable.h b/io_uring/filetable.h index bfacadb8d089..7717ea9efd0e 100644 --- a/io_uring/filetable.h +++ b/io_uring/filetable.h @@ -6,8 +6,8 @@ #include #include "rsrc.h" -bool io_alloc_file_tables(struct io_file_table *table, unsigned nr_files); -void io_free_file_tables(struct io_file_table *table); +bool io_alloc_file_tables(struct io_ring_ctx *ctx, struct io_file_table *table, unsigned nr_files); +void io_free_file_tables(struct io_ring_ctx *ctx, struct io_file_table *table); int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags, struct file *file, unsigned int file_slot); diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index 2fb1791d7255..d7db36a2c66e 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -130,13 +130,13 @@ struct io_rsrc_node *io_rsrc_node_alloc(struct io_ring_ctx *ctx, int type) return node; } -__cold void io_rsrc_data_free(struct io_rsrc_data *data) +__cold void io_rsrc_data_free(struct io_ring_ctx *ctx, struct io_rsrc_data *data) { if (!data->nr) return; while (data->nr--) { if (data->nodes[data->nr]) - io_put_rsrc_node(data->nodes[data->nr]); + io_put_rsrc_node(ctx, data->nodes[data->nr]); } kvfree(data->nodes); data->nodes = NULL; @@ -184,7 +184,7 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx, continue; i = up->offset + done; - if (io_reset_rsrc_node(&ctx->file_table.data, i)) + if (io_reset_rsrc_node(ctx, &ctx->file_table.data, i)) io_file_bitmap_clear(&ctx->file_table, i); if (fd != -1) { @@ -266,7 +266,7 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx, node->tag = tag; } i = array_index_nospec(up->offset + done, ctx->buf_table.nr); - io_reset_rsrc_node(&ctx->buf_table, i); + io_reset_rsrc_node(ctx, &ctx->buf_table, i); ctx->buf_table.nodes[i] = node; if (ctx->compat) user_data += sizeof(struct compat_iovec); @@ -442,10 +442,8 @@ int io_files_update(struct io_kiocb *req, unsigned int issue_flags) return IOU_OK; } -void io_free_rsrc_node(struct io_rsrc_node *node) +void io_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node) { - struct io_ring_ctx *ctx = io_rsrc_node_ctx(node); - lockdep_assert_held(&ctx->uring_lock); if (node->tag) @@ -473,7 +471,7 @@ int io_sqe_files_unregister(struct io_ring_ctx *ctx) if (!ctx->file_table.data.nr) return -ENXIO; - io_free_file_tables(&ctx->file_table); + io_free_file_tables(ctx, &ctx->file_table); io_file_table_set_alloc_range(ctx, 0, 0); return 0; } @@ -494,7 +492,7 @@ int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, return -EMFILE; if (nr_args > rlimit(RLIMIT_NOFILE)) return -EMFILE; - if (!io_alloc_file_tables(&ctx->file_table, nr_args)) + if (!io_alloc_file_tables(ctx, &ctx->file_table, nr_args)) return -ENOMEM; for (i = 0; i < nr_args; i++) { @@ -551,7 +549,7 @@ int io_sqe_buffers_unregister(struct io_ring_ctx *ctx) { if (!ctx->buf_table.nr) return -ENXIO; - io_rsrc_data_free(&ctx->buf_table); + io_rsrc_data_free(ctx, &ctx->buf_table); return 0; } @@ -788,7 +786,7 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx, if (ret) { kvfree(imu); if (node) - io_put_rsrc_node(node); + io_put_rsrc_node(ctx, node); node = ERR_PTR(ret); } kvfree(pages); @@ -1018,7 +1016,7 @@ static int io_clone_buffers(struct io_ring_ctx *ctx, struct io_ring_ctx *src_ctx * old and new nodes at this point. */ if (arg->flags & IORING_REGISTER_DST_REPLACE) - io_rsrc_data_free(&ctx->buf_table); + io_rsrc_data_free(ctx, &ctx->buf_table); /* * ctx->buf_table should be empty now - either the contents are being @@ -1042,7 +1040,7 @@ static int io_clone_buffers(struct io_ring_ctx *ctx, struct io_ring_ctx *src_ctx kfree(data.nodes[i]); } out_unlock: - io_rsrc_data_free(&data); + io_rsrc_data_free(ctx, &data); mutex_unlock(&src_ctx->uring_lock); mutex_lock(&ctx->uring_lock); return ret; diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index bc3a863b14bb..c9057f7a06f5 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -45,8 +45,8 @@ struct io_imu_folio_data { }; struct io_rsrc_node *io_rsrc_node_alloc(struct io_ring_ctx *ctx, int type); -void io_free_rsrc_node(struct io_rsrc_node *node); -void io_rsrc_data_free(struct io_rsrc_data *data); +void io_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node); +void io_rsrc_data_free(struct io_ring_ctx *ctx, struct io_rsrc_data *data); int io_rsrc_data_alloc(struct io_rsrc_data *data, unsigned nr); int io_import_fixed(int ddir, struct iov_iter *iter, @@ -76,19 +76,20 @@ static inline struct io_rsrc_node *io_rsrc_node_lookup(struct io_rsrc_data *data return NULL; } -static inline void io_put_rsrc_node(struct io_rsrc_node *node) +static inline void io_put_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node) { if (node && !--node->refs) - io_free_rsrc_node(node); + io_free_rsrc_node(ctx, node); } -static inline bool io_reset_rsrc_node(struct io_rsrc_data *data, int index) +static inline bool io_reset_rsrc_node(struct io_ring_ctx *ctx, + struct io_rsrc_data *data, int index) { struct io_rsrc_node *node = data->nodes[index]; if (!node) return false; - io_put_rsrc_node(node); + io_put_rsrc_node(ctx, node); data->nodes[index] = NULL; return true; } @@ -96,20 +97,15 @@ static inline bool io_reset_rsrc_node(struct io_rsrc_data *data, int index) static inline void io_req_put_rsrc_nodes(struct io_kiocb *req) { if (req->file_node) { - io_put_rsrc_node(req->file_node); + io_put_rsrc_node(req->ctx, req->file_node); req->file_node = NULL; } if (req->flags & REQ_F_BUF_NODE) { - io_put_rsrc_node(req->buf_node); + io_put_rsrc_node(req->ctx, req->buf_node); req->buf_node = NULL; } } -static inline struct io_ring_ctx *io_rsrc_node_ctx(struct io_rsrc_node *node) -{ - return (struct io_ring_ctx *) (node->ctx_ptr & ~IORING_RSRC_TYPE_MASK); -} - static inline int io_rsrc_node_type(struct io_rsrc_node *node) { return node->ctx_ptr & IORING_RSRC_TYPE_MASK; diff --git a/io_uring/splice.c b/io_uring/splice.c index e8ed15f4ea1a..5b84f1630611 100644 --- a/io_uring/splice.c +++ b/io_uring/splice.c @@ -51,7 +51,7 @@ void io_splice_cleanup(struct io_kiocb *req) { struct io_splice *sp = io_kiocb_to_cmd(req, struct io_splice); - io_put_rsrc_node(sp->rsrc_node); + io_put_rsrc_node(req->ctx, sp->rsrc_node); } static struct file *io_splice_get_file(struct io_kiocb *req, From patchwork Thu Nov 7 11:01:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 13866165 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3C8041EF0A4 for ; Thu, 7 Nov 2024 11:02:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977336; cv=none; b=AlwNMJT3B8tyMBpubNLSWWFNJFtBIhIAt2B6gCOD/D/K1aXGxHIbeRpuDgUxJSs0G68tDoEhq2fvuHtpq2oLRWOxh6s4q83MeeYYDKLowDKBuhovMx7UXlnPajrAqt6N8rtTi/XXBlNJ0tGMr2P6XyAw5yn6WCtK3BtI5bsYR+k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977336; c=relaxed/simple; bh=ZFGfCyVjeZFrKdSqsUR0uFSnTKseX+QMM+62DjV+jHU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=S2wPhqYKDu/wphEV1XFaesMgfKNXsgRVvWr2yxVrIK1HpFiy4Gg5YraAJtlzHQ7Qv4EfQXMEFyXbqPo7oxAaXV+EafQoWNopvLim7YFuhdZWEBgrsMybZffKqU8Tur6Rer3bEmemRCUehkPrTJypP+TGyEzOmdUxqDo2Q1hKS9w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=UKhEJCfP; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="UKhEJCfP" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730977334; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GnbXVXfSuPoRT3IWiwcDDUSOQBe/hc8zNrNe+93is/4=; b=UKhEJCfPsN1RdXhlxsFuCOfLSdp8nsIIkbJUvXwAC6z7zfCvEkM2n+YwcR7trogCzdO8+2 4QD3pKHtMxQoo8DKFxLpK/JhRyQs7p6LPfpiIU1SkMYJYLwhzoEgnvkplYRBH/0T8WZ4nH kPfyoMie3AoKBDX78fTltB6uyf4TV9w= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-500-26Fc9L7lO1OR2iT-G6DWFA-1; Thu, 07 Nov 2024 06:02:09 -0500 X-MC-Unique: 26Fc9L7lO1OR2iT-G6DWFA-1 X-Mimecast-MFC-AGG-ID: 26Fc9L7lO1OR2iT-G6DWFA Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id CB6DA1955D4D; Thu, 7 Nov 2024 11:02:07 +0000 (UTC) Received: from localhost (unknown [10.72.116.54]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8BF6E196BC05; Thu, 7 Nov 2024 11:02:05 +0000 (UTC) From: Ming Lei To: Jens Axboe , io-uring@vger.kernel.org, Pavel Begunkov Cc: linux-block@vger.kernel.org, Uday Shankar , Akilesh Kailash , Ming Lei Subject: [PATCH V10 02/12] io_uring/rsrc: remove '->ctx_ptr' of 'struct io_rsrc_node' Date: Thu, 7 Nov 2024 19:01:35 +0800 Message-ID: <20241107110149.890530-3-ming.lei@redhat.com> In-Reply-To: <20241107110149.890530-1-ming.lei@redhat.com> References: <20241107110149.890530-1-ming.lei@redhat.com> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Remove '->ctx_ptr' of 'struct io_rsrc_node', and add 'type' field, meantime remove io_rsrc_node_type(). Signed-off-by: Ming Lei --- io_uring/rsrc.c | 4 ++-- io_uring/rsrc.h | 9 +-------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index d7db36a2c66e..adaae8630932 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -124,7 +124,7 @@ struct io_rsrc_node *io_rsrc_node_alloc(struct io_ring_ctx *ctx, int type) node = kzalloc(sizeof(*node), GFP_KERNEL); if (node) { - node->ctx_ptr = (unsigned long) ctx | type; + node->type = type; node->refs = 1; } return node; @@ -449,7 +449,7 @@ void io_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node) if (node->tag) io_post_aux_cqe(ctx, node->tag, 0, 0); - switch (io_rsrc_node_type(node)) { + switch (node->type) { case IORING_RSRC_FILE: if (io_slot_file(node)) fput(io_slot_file(node)); diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index c9057f7a06f5..c8a64a9ed5b9 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -11,12 +11,10 @@ enum { IORING_RSRC_FILE = 0, IORING_RSRC_BUFFER = 1, - - IORING_RSRC_TYPE_MASK = 0x3UL, }; struct io_rsrc_node { - unsigned long ctx_ptr; + unsigned char type; int refs; u64 tag; @@ -106,11 +104,6 @@ static inline void io_req_put_rsrc_nodes(struct io_kiocb *req) } } -static inline int io_rsrc_node_type(struct io_rsrc_node *node) -{ - return node->ctx_ptr & IORING_RSRC_TYPE_MASK; -} - static inline void io_req_assign_rsrc_node(struct io_rsrc_node **dst_node, struct io_rsrc_node *node) { From patchwork Thu Nov 7 11:01:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 13866166 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2B7801EF957 for ; Thu, 7 Nov 2024 11:02:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977337; cv=none; b=Lc6pWS/SfUBrbkEtqfj50RvTa4c9IH6HTDOxOQh7yHreOw6sTTfMYXg2T+mRZ/3j3hFrs1ez0yAyLcf0djRWYq2+5Wgy4uO4lvM/h7V2p01wjSTCduffOtyS4yieqSCJIcU29OL3qd/NG+mlviyeZ0U+zIeikS9EAGNu+4yXftc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977337; c=relaxed/simple; bh=/nBuYkm4ZIQSzZbsrM5SCU14YE72rgNY/zfy7ccWjSE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ml1MQwyyskxXtAqrPGdooiWDF07MkNbR1Q1ZWV9FXyKi3oTCUoWxPiNurNQJUEud3Eca5aYb9nYwwPU6F9O0qdKeHUPnh5nVKoZJFhz7XkDvubb0MIwimp4tbLep6IPID/L5fguHt97pYmiv3d08DdhN/zjWAZ2kyso5ffIJ7/E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=aTJdKcop; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="aTJdKcop" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730977335; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PBrVpfuh5t1ju1o2rH+qwizzz9nWJDofQ3E+XgyAU+M=; b=aTJdKcopSQtp7fmj1gNimpgnZz4ti0BWgo9KCmpOm6gyV0PCr4eYR0mOnFpwTHh4OLyvOS ZpCy3mB9hK4RefBhtkoignK4p2XmXnjd3eMdYWFmh+F2K4kZClyNjEMHZPznnmb2i8tbeN GP+bV3xqgVYE9QtIqJ3ve19rGkyvmQU= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-58-Zi9wzdZhOGmAGtHh48VJrw-1; Thu, 07 Nov 2024 06:02:14 -0500 X-MC-Unique: Zi9wzdZhOGmAGtHh48VJrw-1 X-Mimecast-MFC-AGG-ID: Zi9wzdZhOGmAGtHh48VJrw Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 98A511954B0A; Thu, 7 Nov 2024 11:02:12 +0000 (UTC) Received: from localhost (unknown [10.72.116.54]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 6429B1953883; Thu, 7 Nov 2024 11:02:10 +0000 (UTC) From: Ming Lei To: Jens Axboe , io-uring@vger.kernel.org, Pavel Begunkov Cc: linux-block@vger.kernel.org, Uday Shankar , Akilesh Kailash , Ming Lei Subject: [PATCH V10 03/12] io_uring/rsrc: add & apply io_req_assign_buf_node() Date: Thu, 7 Nov 2024 19:01:36 +0800 Message-ID: <20241107110149.890530-4-ming.lei@redhat.com> In-Reply-To: <20241107110149.890530-1-ming.lei@redhat.com> References: <20241107110149.890530-1-ming.lei@redhat.com> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 The following pattern becomes more and more: + io_req_assign_rsrc_node(&req->buf_node, node); + req->flags |= REQ_F_BUF_NODE; so make it a helper, which is less fragile to use than above code, for example, the BUF_NODE flag is even missed in current io_uring_cmd_prep(). Signed-off-by: Ming Lei --- io_uring/net.c | 3 +-- io_uring/nop.c | 3 +-- io_uring/rsrc.h | 7 +++++++ io_uring/rw.c | 3 +-- io_uring/uring_cmd.c | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/io_uring/net.c b/io_uring/net.c index 2ccc2b409431..df1f7dc6f1c8 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -1348,8 +1348,7 @@ static int io_send_zc_import(struct io_kiocb *req, unsigned int issue_flags) io_ring_submit_lock(ctx, issue_flags); node = io_rsrc_node_lookup(&ctx->buf_table, sr->buf_index); if (node) { - io_req_assign_rsrc_node(&sr->notif->buf_node, node); - sr->notif->flags |= REQ_F_BUF_NODE; + io_req_assign_buf_node(sr->notif, node); ret = 0; } io_ring_submit_unlock(ctx, issue_flags); diff --git a/io_uring/nop.c b/io_uring/nop.c index bc22bcc739f3..6d470d4251ee 100644 --- a/io_uring/nop.c +++ b/io_uring/nop.c @@ -67,8 +67,7 @@ int io_nop(struct io_kiocb *req, unsigned int issue_flags) io_ring_submit_lock(ctx, issue_flags); node = io_rsrc_node_lookup(&ctx->buf_table, nop->buffer); if (node) { - io_req_assign_rsrc_node(&req->buf_node, node); - req->flags |= REQ_F_BUF_NODE; + io_req_assign_buf_node(req, node); ret = 0; } io_ring_submit_unlock(ctx, issue_flags); diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index c8a64a9ed5b9..7a4668deaa1a 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -111,6 +111,13 @@ static inline void io_req_assign_rsrc_node(struct io_rsrc_node **dst_node, *dst_node = node; } +static inline void io_req_assign_buf_node(struct io_kiocb *req, + struct io_rsrc_node *node) +{ + io_req_assign_rsrc_node(&req->buf_node, node); + req->flags |= REQ_F_BUF_NODE; +} + int io_files_update(struct io_kiocb *req, unsigned int issue_flags); int io_files_update_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe); diff --git a/io_uring/rw.c b/io_uring/rw.c index e368b9afde03..b62cdb5fc936 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -341,8 +341,7 @@ static int io_prep_rw_fixed(struct io_kiocb *req, const struct io_uring_sqe *sqe node = io_rsrc_node_lookup(&ctx->buf_table, req->buf_index); if (!node) return -EFAULT; - io_req_assign_rsrc_node(&req->buf_node, node); - req->flags |= REQ_F_BUF_NODE; + io_req_assign_buf_node(req, node); io = req->async_data; ret = io_import_fixed(ddir, &io->iter, node->buf, rw->addr, rw->len); diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c index 40b8b777ba12..b62965f58f30 100644 --- a/io_uring/uring_cmd.c +++ b/io_uring/uring_cmd.c @@ -219,7 +219,7 @@ int io_uring_cmd_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) * being called. This prevents destruction of the mapped buffer * we'll need at actual import time. */ - io_req_assign_rsrc_node(&req->buf_node, node); + io_req_assign_buf_node(req, node); } ioucmd->cmd_op = READ_ONCE(sqe->cmd_op); From patchwork Thu Nov 7 11:01:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 13866167 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 111E31F4268 for ; Thu, 7 Nov 2024 11:02:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977343; cv=none; b=tpQUN+G+9YyptmSiNUYiibdhlauxoOQnseIMbwgIk6oewnEzKTqsHfkUAlnpwFcnoPknYAeG6jFjRS4AytA6GrAUDD5JY6cEdoa7C1VOXXBSJ+OFFFfbefZSNm/LDaSaKY27yEwjurPTlTc5k5f1JU/HTHEE2Gcmsj+B2j7/WQo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977343; c=relaxed/simple; bh=NsZ1msBsSYLL/eepZldaM7VPRfAR3s7KkSdOQlyHAYc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=U8dpIBU5aP/eUhRXT2+YCGazHNRT4HEuk6BLiN6O3kRK3Z8wEhDMB7j9uamR4KmLTZbiVxcQEzwlFGzuXnwve4pd/trrLkYZQw7epf0xpEeWLtEm2/phflgG2efvpzcF3X2N3K1RVshfyqZ1RxNbRouHEZDS9o9bvUcEH1XstzY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=huShxqC+; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="huShxqC+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730977341; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rsB2O5a+Xy5ldSEadpiS1OiDWOLSJfk5jFl4Okpjsxs=; b=huShxqC+BY4tWbvPut5igBo6oKZawIgqmhRBkyMEv/agPHgJ1CYooEquq3KquCfr0eesrJ bLK3ZeNDQkH0h3cZUVV4emaCL352/ckEUnv8jLpjc7F/7xo6iME6FwxyGePBqyVeEjxod7 Jg81KQo6CDOIquYsXGfEvV7TlpdLRVM= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-553-Ec1vTrEiNq2DY45L4bO7jw-1; Thu, 07 Nov 2024 06:02:18 -0500 X-MC-Unique: Ec1vTrEiNq2DY45L4bO7jw-1 X-Mimecast-MFC-AGG-ID: Ec1vTrEiNq2DY45L4bO7jw Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A8A621955EE8; Thu, 7 Nov 2024 11:02:16 +0000 (UTC) Received: from localhost (unknown [10.72.116.54]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B3424196BC05; Thu, 7 Nov 2024 11:02:15 +0000 (UTC) From: Ming Lei To: Jens Axboe , io-uring@vger.kernel.org, Pavel Begunkov Cc: linux-block@vger.kernel.org, Uday Shankar , Akilesh Kailash , Ming Lei Subject: [PATCH V10 04/12] io_uring/rsrc: prepare for supporting external 'io_rsrc_node' Date: Thu, 7 Nov 2024 19:01:37 +0800 Message-ID: <20241107110149.890530-5-ming.lei@redhat.com> In-Reply-To: <20241107110149.890530-1-ming.lei@redhat.com> References: <20241107110149.890530-1-ming.lei@redhat.com> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Now 'io_rsrc_node' is just one buffer, and it may be provided from other subsystem, such as the coming group kernel buffer. So add flag IORING_RSRC_F_NEED_FREE for external 'io_rsrc_node'. Signed-off-by: Ming Lei --- io_uring/rsrc.c | 12 +++++++----- io_uring/rsrc.h | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index adaae8630932..db5d917081b1 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -123,10 +123,9 @@ struct io_rsrc_node *io_rsrc_node_alloc(struct io_ring_ctx *ctx, int type) struct io_rsrc_node *node; node = kzalloc(sizeof(*node), GFP_KERNEL); - if (node) { - node->type = type; - node->refs = 1; - } + if (node) + io_rsrc_node_init(node, type, IORING_RSRC_F_NEED_FREE); + return node; } @@ -444,6 +443,8 @@ int io_files_update(struct io_kiocb *req, unsigned int issue_flags) void io_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node) { + bool need_free = node->flags & IORING_RSRC_F_NEED_FREE; + lockdep_assert_held(&ctx->uring_lock); if (node->tag) @@ -463,7 +464,8 @@ void io_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node) break; } - kfree(node); + if (need_free) + kfree(node); } int io_sqe_files_unregister(struct io_ring_ctx *ctx) diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index 7a4668deaa1a..582a69adfdc9 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -10,11 +10,15 @@ enum { IORING_RSRC_FILE = 0, - IORING_RSRC_BUFFER = 1, + IORING_RSRC_BUFFER, + __IORING_RSRC_LAST_TYPE, + + IORING_RSRC_F_NEED_FREE = 1 << 0, }; struct io_rsrc_node { unsigned char type; + unsigned char flags; int refs; u64 tag; @@ -66,6 +70,15 @@ int io_register_rsrc_update(struct io_ring_ctx *ctx, void __user *arg, int io_register_rsrc(struct io_ring_ctx *ctx, void __user *arg, unsigned int size, unsigned int type); +static inline void io_rsrc_node_init(struct io_rsrc_node *node, int type, + unsigned char flags) +{ + WARN_ON_ONCE(type >= __IORING_RSRC_LAST_TYPE); + + node->type = type; + node->refs = 1; + node->flags = flags; +} static inline struct io_rsrc_node *io_rsrc_node_lookup(struct io_rsrc_data *data, int index) { From patchwork Thu Nov 7 11:01:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 13866168 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B1391DFE2F for ; Thu, 7 Nov 2024 11:02:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977350; cv=none; b=ltiozmVqEqoFMKkrdertTk5EVPCnbzocNxHb4Tq+F0H9W6k4DqyB640/vLo0EwwF86YbBBUG/nLLMmZDWi8IpTngT6J5usOmn7547IuZ8Mk6NnqoHBuz2hOwrvqIGUsJNFUMWLT2jJ4hYLIFuJvqJE19/Gu7sG6tJq0xdIjZiRk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977350; c=relaxed/simple; bh=WXyPckGAHkAnJ3xaf8ENEQVhhom5E7uOP7ig1RDadls=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kthnmV2VQECVKKVMNmiQfzF8fPCcgDVgKyxYPudG9pVSSE3Qyvt6yKMFklqKSk3NLGgCgXW8b8ZYVHlLbAWMj8y7Fg5TcfU0QNrMSIGzOVsBhpAOXAxh9wOnAt892N+HW/INs1OL1etcmSEoOS0SaQkMur673XfTlu6EkEYVhoY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=eCNl1H86; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="eCNl1H86" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730977346; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=d1h9L5DweKmrJ102XwCrOvCHCpyndeFnMm0NdLnQwyk=; b=eCNl1H86Oxd9/vEtX/ldyRmHZKXOBvrpAl0OlTDzPdDuV/mHF35Jlkh0Z/NwbCRwN2vK2P ONGDyTLvOZ1foyd1BPZPjpnjpagcLh5XN1hQFVALueDXF9ctnrvGu/NwoJAlDb0GWdSc35 6FEesVkghCH6/svyE6yZzL8PMWlccus= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-653-pyHs6U3fNxOsnqkLWOG_3A-1; Thu, 07 Nov 2024 06:02:22 -0500 X-MC-Unique: pyHs6U3fNxOsnqkLWOG_3A-1 X-Mimecast-MFC-AGG-ID: pyHs6U3fNxOsnqkLWOG_3A Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C8A82194510C; Thu, 7 Nov 2024 11:02:20 +0000 (UTC) Received: from localhost (unknown [10.72.116.54]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D462A196BC05; Thu, 7 Nov 2024 11:02:19 +0000 (UTC) From: Ming Lei To: Jens Axboe , io-uring@vger.kernel.org, Pavel Begunkov Cc: linux-block@vger.kernel.org, Uday Shankar , Akilesh Kailash , Ming Lei Subject: [PATCH V10 05/12] io_uring: rename io_mapped_ubuf as io_mapped_buf Date: Thu, 7 Nov 2024 19:01:38 +0800 Message-ID: <20241107110149.890530-6-ming.lei@redhat.com> In-Reply-To: <20241107110149.890530-1-ming.lei@redhat.com> References: <20241107110149.890530-1-ming.lei@redhat.com> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Rename io_mapped_ubuf so that the same structure can be used for describing kernel buffer. Signed-off-by: Ming Lei --- io_uring/fdinfo.c | 2 +- io_uring/rsrc.c | 10 +++++----- io_uring/rsrc.h | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/io_uring/fdinfo.c b/io_uring/fdinfo.c index b214e5a407b5..9ca95f877312 100644 --- a/io_uring/fdinfo.c +++ b/io_uring/fdinfo.c @@ -218,7 +218,7 @@ __cold void io_uring_show_fdinfo(struct seq_file *m, struct file *file) } seq_printf(m, "UserBufs:\t%u\n", ctx->buf_table.nr); for (i = 0; has_lock && i < ctx->buf_table.nr; i++) { - struct io_mapped_ubuf *buf = NULL; + struct io_mapped_buf *buf = NULL; if (ctx->buf_table.nodes[i]) buf = ctx->buf_table.nodes[i]->buf; diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index db5d917081b1..a4a553bbbbfa 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -106,7 +106,7 @@ static void io_buffer_unmap(struct io_ring_ctx *ctx, struct io_rsrc_node *node) unsigned int i; if (node->buf) { - struct io_mapped_ubuf *imu = node->buf; + struct io_mapped_buf *imu = node->buf; if (!refcount_dec_and_test(&imu->refs)) return; @@ -580,7 +580,7 @@ static bool headpage_already_acct(struct io_ring_ctx *ctx, struct page **pages, /* check previously registered pages */ for (i = 0; i < ctx->buf_table.nr; i++) { struct io_rsrc_node *node = ctx->buf_table.nodes[i]; - struct io_mapped_ubuf *imu; + struct io_mapped_buf *imu; if (!node) continue; @@ -597,7 +597,7 @@ static bool headpage_already_acct(struct io_ring_ctx *ctx, struct page **pages, } static int io_buffer_account_pin(struct io_ring_ctx *ctx, struct page **pages, - int nr_pages, struct io_mapped_ubuf *imu, + int nr_pages, struct io_mapped_buf *imu, struct page **last_hpage) { int i, ret; @@ -724,7 +724,7 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx, struct iovec *iov, struct page **last_hpage) { - struct io_mapped_ubuf *imu = NULL; + struct io_mapped_buf *imu = NULL; struct page **pages = NULL; struct io_rsrc_node *node; unsigned long off; @@ -866,7 +866,7 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg, } int io_import_fixed(int ddir, struct iov_iter *iter, - struct io_mapped_ubuf *imu, + struct io_mapped_buf *imu, u64 buf_addr, size_t len) { u64 buf_end; diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index 582a69adfdc9..0867dc304f4f 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -24,11 +24,11 @@ struct io_rsrc_node { u64 tag; union { unsigned long file_ptr; - struct io_mapped_ubuf *buf; + struct io_mapped_buf *buf; }; }; -struct io_mapped_ubuf { +struct io_mapped_buf { u64 ubuf; unsigned int len; unsigned int nr_bvecs; @@ -52,7 +52,7 @@ void io_rsrc_data_free(struct io_ring_ctx *ctx, struct io_rsrc_data *data); int io_rsrc_data_alloc(struct io_rsrc_data *data, unsigned nr); int io_import_fixed(int ddir, struct iov_iter *iter, - struct io_mapped_ubuf *imu, + struct io_mapped_buf *imu, u64 buf_addr, size_t len); int io_register_clone_buffers(struct io_ring_ctx *ctx, void __user *arg); From patchwork Thu Nov 7 11:01:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 13866169 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9AB991DFE2F for ; Thu, 7 Nov 2024 11:02:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977352; cv=none; b=BXu7EeGeLkg3yJK5Ie4Pdux74EJOow6Jh/A5clkbAiMHEPnq1AHqYLNrfhxpJlClYi+8rugWR1/AzhJUpHgbYEbJGccUOqbafnPJSLw4I8qkwueh6PKpY19CDDzGApnl00dNflbO4oaRbZsoqXftq4Ipe2z+R4H/u5FbVbV6+vY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977352; c=relaxed/simple; bh=4F/eQLyt7fZU/1nE3xYwdURyTRkBywW2ceBXmGIM698=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZbpMdJOu9K3J0g584JgtcGAgVE0qthBYMYb8gvY6pbB9v9LZTSVNR14yYl7UNRb44iQb9NTjR+ypYi8sBNjKLXi90vqPSevk+wjNTPR2C8kbNIglGy6Jdeu6Vk7kDEIhKgd7z3/d4vlZRVOZ2b3/aUTTtE+oGLF1zp1zcFIXBSc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Jcb1uQpD; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Jcb1uQpD" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730977349; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=i0iUgUH84D+XrrmkG/wx4I+A+vYyGBAwJCNYHpW9PhY=; b=Jcb1uQpDtKiezbbileb+HGsBl/wSVcKvwlnM/TlNEsl+OT94tx6khFhvB93FKAv58xwaSm LnPtBomRrJtlMFKDUG+TgZjVvpAuljb8Re5wUcIrgoXpuykPvPEOKhBAexBz1ylvfRxPxi VQsNRX4ZwLkSjM/CvbTOda5JIRui6dg= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-347-dqsWXi6DNDyuaoYjwVOwGA-1; Thu, 07 Nov 2024 06:02:26 -0500 X-MC-Unique: dqsWXi6DNDyuaoYjwVOwGA-1 X-Mimecast-MFC-AGG-ID: dqsWXi6DNDyuaoYjwVOwGA Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4839B195608B; Thu, 7 Nov 2024 11:02:25 +0000 (UTC) Received: from localhost (unknown [10.72.116.54]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E50EB195E480; Thu, 7 Nov 2024 11:02:23 +0000 (UTC) From: Ming Lei To: Jens Axboe , io-uring@vger.kernel.org, Pavel Begunkov Cc: linux-block@vger.kernel.org, Uday Shankar , Akilesh Kailash , Ming Lei Subject: [PATCH V10 06/12] io_uring: rename io_mapped_buf->ubuf as io_mapped_buf->addr Date: Thu, 7 Nov 2024 19:01:39 +0800 Message-ID: <20241107110149.890530-7-ming.lei@redhat.com> In-Reply-To: <20241107110149.890530-1-ming.lei@redhat.com> References: <20241107110149.890530-1-ming.lei@redhat.com> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 ->addr of `io_mapped_buf` stores the start address of userspace fixed buffer. `io_mapped_buf` will be extended for covering kernel buffer, so rename ->ubuf as ->addr. Signed-off-by: Ming Lei --- io_uring/fdinfo.c | 2 +- io_uring/rsrc.c | 6 +++--- io_uring/rsrc.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/io_uring/fdinfo.c b/io_uring/fdinfo.c index 9ca95f877312..1fd05e78ce15 100644 --- a/io_uring/fdinfo.c +++ b/io_uring/fdinfo.c @@ -223,7 +223,7 @@ __cold void io_uring_show_fdinfo(struct seq_file *m, struct file *file) if (ctx->buf_table.nodes[i]) buf = ctx->buf_table.nodes[i]->buf; if (buf) - seq_printf(m, "%5u: 0x%llx/%u\n", i, buf->ubuf, buf->len); + seq_printf(m, "%5u: 0x%llx/%u\n", i, buf->addr, buf->len); else seq_printf(m, "%5u: \n", i); } diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index a4a553bbbbfa..f57c4d295f09 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -765,7 +765,7 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx, size = iov->iov_len; /* store original address for later verification */ - imu->ubuf = (unsigned long) iov->iov_base; + imu->addr = (unsigned long) iov->iov_base; imu->len = iov->iov_len; imu->nr_bvecs = nr_pages; imu->folio_shift = PAGE_SHIFT; @@ -877,14 +877,14 @@ int io_import_fixed(int ddir, struct iov_iter *iter, if (unlikely(check_add_overflow(buf_addr, (u64)len, &buf_end))) return -EFAULT; /* not inside the mapped region */ - if (unlikely(buf_addr < imu->ubuf || buf_end > (imu->ubuf + imu->len))) + if (unlikely(buf_addr < imu->addr || buf_end > (imu->addr + imu->len))) return -EFAULT; /* * Might not be a start of buffer, set size appropriately * and advance us to the beginning. */ - offset = buf_addr - imu->ubuf; + offset = buf_addr - imu->addr; iov_iter_bvec(iter, ddir, imu->bvec, imu->nr_bvecs, offset + len); if (offset) { diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index 0867dc304f4f..c8a4db4721ca 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -29,7 +29,7 @@ struct io_rsrc_node { }; struct io_mapped_buf { - u64 ubuf; + u64 addr; unsigned int len; unsigned int nr_bvecs; unsigned int folio_shift; From patchwork Thu Nov 7 11:01:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 13866170 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AE36B13C682 for ; Thu, 7 Nov 2024 11:02:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977357; cv=none; b=r3CuZN6P3zPMMWmCnwA+lrcf1QzKSOGU7Y1ZHLE1UQ/wqkzUezwKZNlKphVThrmJk2+3d68dGKGDZAPkV69yi4QBSdigz850JB66JKr9i/zivh9U1UwPp5SoDfqEN5LemMNnkpKzf4+DexoJ6F5xxo0JH1klgwjIJapVww8KBO4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977357; c=relaxed/simple; bh=NQ+bwr1JB4p3kwCzYVnZV2mYuii1jbMOo79wlSQxK5g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PoytXZmnsR6PHbNdOJ/A6yd1nJdTE/ll//2xQkXCvdrplZxleZndbIA4Z+uNKxoMJ+g5Cdb7MdufH6LYZQI71/HagZ6IBbsK7rjSt8qwn3o5EGrFCRPCabR3YnLpq12PmrXhCgQGpZ6WK02SPNM+v9yjJLTSz5/9b4da29j8B/A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=aMO+2Qwy; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="aMO+2Qwy" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730977354; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=V0VSqFzf1J9PU1pJLz6JPLAs1jAHK7dRkghElujlsZ8=; b=aMO+2QwyqX1aKdvo6jCIqxYhyKJGeLuq/MlyAI4zC9yqM1mo5ELdHhERZIYfSn/qtkENJc 75R0/gqPW1Bilj+LcyUmScsPUBDLTd7dvbfYj1txgre5sIZ24av1t4t3FYu57JO7QQ8tBd uFRR4TI+FHN6rpU4DstRbdGA4x2DpfQ= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-624-3mZzLQx5Op2Hni-UDMWQGQ-1; Thu, 07 Nov 2024 06:02:31 -0500 X-MC-Unique: 3mZzLQx5Op2Hni-UDMWQGQ-1 X-Mimecast-MFC-AGG-ID: 3mZzLQx5Op2Hni-UDMWQGQ Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D4F3D1956095; Thu, 7 Nov 2024 11:02:29 +0000 (UTC) Received: from localhost (unknown [10.72.116.54]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5D0AE196BC05; Thu, 7 Nov 2024 11:02:27 +0000 (UTC) From: Ming Lei To: Jens Axboe , io-uring@vger.kernel.org, Pavel Begunkov Cc: linux-block@vger.kernel.org, Uday Shankar , Akilesh Kailash , Ming Lei Subject: [PATCH V10 07/12] io_uring: shrink io_mapped_buf Date: Thu, 7 Nov 2024 19:01:40 +0800 Message-ID: <20241107110149.890530-8-ming.lei@redhat.com> In-Reply-To: <20241107110149.890530-1-ming.lei@redhat.com> References: <20241107110149.890530-1-ming.lei@redhat.com> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 `struct io_mapped_buf` will be extended to cover kernel buffer which may be in fast IO path, and `struct io_mapped_buf` needs to be per-IO. So shrink sizeof(struct io_mapped_buf) by the following ways: - folio_shift is < 64, so 6bits are enough to hold it, the remained bits can be used for the coming kernel buffer - define `acct_pages` as 'unsigned int', which is big enough for accounting pages in the buffer Signed-off-by: Ming Lei --- io_uring/rsrc.c | 2 ++ io_uring/rsrc.h | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index f57c4d295f09..99ff2797e6ec 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -685,6 +685,8 @@ static bool io_try_coalesce_buffer(struct page ***pages, int *nr_pages, return false; data->folio_shift = folio_shift(folio); + WARN_ON_ONCE(data->folio_shift >= 64); + /* * Check if pages are contiguous inside a folio, and all folios have * the same page count except for the head and tail. diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index c8a4db4721ca..bf0824b4beb6 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -32,9 +32,9 @@ struct io_mapped_buf { u64 addr; unsigned int len; unsigned int nr_bvecs; - unsigned int folio_shift; refcount_t refs; - unsigned long acct_pages; + unsigned int acct_pages; + unsigned int folio_shift:6; struct bio_vec bvec[] __counted_by(nr_bvecs); }; @@ -43,7 +43,7 @@ struct io_imu_folio_data { unsigned int nr_pages_head; /* For non-head/tail folios, has to be fully included */ unsigned int nr_pages_mid; - unsigned int folio_shift; + unsigned char folio_shift; }; struct io_rsrc_node *io_rsrc_node_alloc(struct io_ring_ctx *ctx, int type); From patchwork Thu Nov 7 11:01:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 13866171 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 971831F4296 for ; Thu, 7 Nov 2024 11:02:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977359; cv=none; b=uxOACIAl/G1PjOw+RFPGdjRzDZNsfTbCNzUA5qMWpVkgkamkTHKq9qs1ER7xXREbOnb7awfjrDmqJhEMqmhLh3LJaROS6tBu6lAGdnXqNKnBhUDb5RJeIlwMUj5LK61jbvfN+H4uaT2h8gAIw3FOhbWMzwpqJduGNOsyuj4zfSU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977359; c=relaxed/simple; bh=tly5WzZ/x+5sr3uFZjmb1OElDgbLU/izgB/EE+LNdcw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TfjNs0e+mjBVgukfoHwe0HVpWvXKF00ur393VF7eRGvF0hTTDZ4McnlXp8PUCMh7VyyxoUeJek3IyViLCK7PVOgy99yoOvDd8UeyrOnJ+BHOsftQaTZgyRt0xgTL33LTZPyVjq4fo6Dsix0CKrHTcfurqo6ZpOm7i07YJaYVwPI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=BJKJiJ2e; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="BJKJiJ2e" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730977356; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eXhq6YRcO+Qv5hJmRM0rhu2PFbttro6G4So3Dp8+hAE=; b=BJKJiJ2esDjGR8CE+Q0wXQuo877a1XPiwcYmHJpg5yUcOgxHXrWJ7Hr7iozCJbwDmchvNa 3iAe6KAhvBHDYOlIHrfHVBPtWlYD+Dce0BZqgqpFtZHrVpkqerN0XI10xuS0Ysa3TPEgJM QbcpMjhoddcwmgzljOlVhdE/Q0WoIlU= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-22-CXAvhZHPN5O82g83F8N1aA-1; Thu, 07 Nov 2024 06:02:35 -0500 X-MC-Unique: CXAvhZHPN5O82g83F8N1aA-1 X-Mimecast-MFC-AGG-ID: CXAvhZHPN5O82g83F8N1aA Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 201D51955F45; Thu, 7 Nov 2024 11:02:34 +0000 (UTC) Received: from localhost (unknown [10.72.116.54]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E59F33003B78; Thu, 7 Nov 2024 11:02:32 +0000 (UTC) From: Ming Lei To: Jens Axboe , io-uring@vger.kernel.org, Pavel Begunkov Cc: linux-block@vger.kernel.org, Uday Shankar , Akilesh Kailash , Ming Lei Subject: [PATCH V10 08/12] io_uring: reuse io_mapped_buf for kernel buffer Date: Thu, 7 Nov 2024 19:01:41 +0800 Message-ID: <20241107110149.890530-9-ming.lei@redhat.com> In-Reply-To: <20241107110149.890530-1-ming.lei@redhat.com> References: <20241107110149.890530-1-ming.lei@redhat.com> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Prepare for supporting kernel buffer in case of io group, in which group leader leases kernel buffer to io_uring, and consumed by io_uring OPs. So reuse io_mapped_buf for group kernel buffer, and unfortunately io_import_fixed() can't be reused since userspace fixed buffer is virt-contiguous, but it isn't true for kernel buffer. Signed-off-by: Ming Lei --- include/linux/io_uring_types.h | 19 +++++++++++++++++++ io_uring/kbuf.c | 34 ++++++++++++++++++++++++++++++++++ io_uring/kbuf.h | 3 +++ io_uring/rsrc.c | 1 + io_uring/rsrc.h | 10 ---------- 5 files changed, 57 insertions(+), 10 deletions(-) diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h index d060ce5e6145..03abaeef4a67 100644 --- a/include/linux/io_uring_types.h +++ b/include/linux/io_uring_types.h @@ -2,6 +2,7 @@ #define IO_URING_TYPES_H #include +#include #include #include #include @@ -39,6 +40,24 @@ enum io_uring_cmd_flags { IO_URING_F_COMPAT = (1 << 12), }; +struct io_mapped_buf { + u64 addr; + unsigned int len; + unsigned int nr_bvecs; + refcount_t refs; + union { + /* for userspace buffer only */ + unsigned int acct_pages; + /* offset in the 1st bvec, for kbuf only */ + unsigned int offset; + }; + const struct bio_vec *pbvec; /* pbvec is only for kbuf */ + unsigned int folio_shift:6; + unsigned int dir:1; /* ITER_DEST or ITER_SOURCE */ + unsigned int kbuf:1; /* kernel buffer or not */ + struct bio_vec bvec[] __counted_by(nr_bvecs); +}; + struct io_wq_work_node { struct io_wq_work_node *next; }; diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c index d407576ddfb7..c4a776860cb4 100644 --- a/io_uring/kbuf.c +++ b/io_uring/kbuf.c @@ -838,3 +838,37 @@ int io_pbuf_mmap(struct file *file, struct vm_area_struct *vma) io_put_bl(ctx, bl); return ret; } + +/* + * kernel buffer is built over generic bvec, and can't be always + * virt-contiguous, which is different with userspace fixed buffer, + * so we can't reuse io_import_fixed() here + * + * Also kernel buffer lifetime is bound with request, and we needn't + * to use rsrc_node to track its lifetime + */ +int io_import_kbuf(int ddir, struct iov_iter *iter, + const struct io_mapped_buf *kbuf, + u64 buf_off, size_t len) +{ + unsigned long offset = kbuf->offset; + + WARN_ON_ONCE(!kbuf->kbuf); + + if (ddir != kbuf->dir) + return -EINVAL; + + if (unlikely(buf_off > kbuf->len)) + return -EFAULT; + + if (unlikely(len > kbuf->len - buf_off)) + return -EFAULT; + + offset += buf_off; + iov_iter_bvec(iter, ddir, kbuf->pbvec, kbuf->nr_bvecs, offset + len); + + if (offset) + iov_iter_advance(iter, offset); + + return 0; +} diff --git a/io_uring/kbuf.h b/io_uring/kbuf.h index 36aadfe5ac00..04ccd52dd0ad 100644 --- a/io_uring/kbuf.h +++ b/io_uring/kbuf.h @@ -88,6 +88,9 @@ void io_put_bl(struct io_ring_ctx *ctx, struct io_buffer_list *bl); struct io_buffer_list *io_pbuf_get_bl(struct io_ring_ctx *ctx, unsigned long bgid); int io_pbuf_mmap(struct file *file, struct vm_area_struct *vma); +int io_import_kbuf(int ddir, struct iov_iter *iter, + const struct io_mapped_buf *kbuf, + u64 buf_off, size_t len); static inline bool io_kbuf_recycle_ring(struct io_kiocb *req) { diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index 99ff2797e6ec..b0b60ae0456a 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -771,6 +771,7 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx, imu->len = iov->iov_len; imu->nr_bvecs = nr_pages; imu->folio_shift = PAGE_SHIFT; + imu->kbuf = 0; if (coalesced) imu->folio_shift = data.folio_shift; refcount_set(&imu->refs, 1); diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index bf0824b4beb6..3bc3a484fbba 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -28,16 +28,6 @@ struct io_rsrc_node { }; }; -struct io_mapped_buf { - u64 addr; - unsigned int len; - unsigned int nr_bvecs; - refcount_t refs; - unsigned int acct_pages; - unsigned int folio_shift:6; - struct bio_vec bvec[] __counted_by(nr_bvecs); -}; - struct io_imu_folio_data { /* Head folio can be partially included in the fixed buf */ unsigned int nr_pages_head; From patchwork Thu Nov 7 11:01:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 13866172 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA1111F4FB8 for ; Thu, 7 Nov 2024 11:02:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977365; cv=none; b=PCyyzGihaYsvSvqtKcSH5lL8jtLTvCH5lz0ptZ9ULMBjV2nxhLXXiaVWWUoPrf4b1/s8NEiZUfghWo26bi/RUCz21q2eNiAA2eyrxBfN6Qu9Jr5iDJvhdLWYwNDp55bEOE5IxGcKXJ9qOGTt0u4Q7FHoiKWW2eWVi/9EBvr+tZ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977365; c=relaxed/simple; bh=SlVDir5D6UeaNDe+jsuQbh685ORFlAHHlttDEDq1XPY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QiChwV7FHu6pI5kf2WzJStXHrqIY8BmeL76MAqt3CRSsUfOcbqdeWJe6/neMTAa4C+IesWAg8dL6cf6wrrdWO/1OsxsWqF106Ee9hY7uLumD5wVCnDI0tNSUMsG0qVVNEwiODHTX7DkicAwxIqBYeC7r1PmyT9DzAgB65nfzGh0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=beaos4aI; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="beaos4aI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730977362; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dkSqkK/E8i2PqF8EQ4nFg2slbPvUmDf+ZN1S2KY4Ymo=; b=beaos4aIRxoGAk8Ni/xH78YxZYMn3KAZBYuEmJ+XxcWd4ZzfCuYaVcQ8pHER5inyIN2Y1N sm4TsG5O4LXcuZk0i6o7I34RUl/lONitLZ9j/E3Y5hFPOUFi/FQpnunaMXKt0bQgqg7mp7 GPg/4Y3l+OhSxZhlkzW2Irsp7Y3g/ac= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-190-s0ETgjZnPu2Oqx6nllwKxg-1; Thu, 07 Nov 2024 06:02:39 -0500 X-MC-Unique: s0ETgjZnPu2Oqx6nllwKxg-1 X-Mimecast-MFC-AGG-ID: s0ETgjZnPu2Oqx6nllwKxg Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2A6371955F69; Thu, 7 Nov 2024 11:02:38 +0000 (UTC) Received: from localhost (unknown [10.72.116.54]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2D24A3003B78; Thu, 7 Nov 2024 11:02:36 +0000 (UTC) From: Ming Lei To: Jens Axboe , io-uring@vger.kernel.org, Pavel Begunkov Cc: linux-block@vger.kernel.org, Uday Shankar , Akilesh Kailash , Ming Lei Subject: [PATCH V10 09/12] io_uring: add callback to 'io_mapped_buffer' for giving back kernel buffer Date: Thu, 7 Nov 2024 19:01:42 +0800 Message-ID: <20241107110149.890530-10-ming.lei@redhat.com> In-Reply-To: <20241107110149.890530-1-ming.lei@redhat.com> References: <20241107110149.890530-1-ming.lei@redhat.com> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Add one callback to 'io_mapped_buffer' for giving back kernel buffer after the buffer is used. Meantime move 'io_rsrc_node' into public header, and it will become part of kernel buffer API. Signed-off-by: Ming Lei --- include/linux/io_uring_types.h | 20 +++++++++++++++++++- io_uring/rsrc.c | 14 +++++++++++++- io_uring/rsrc.h | 13 +------------ 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h index 03abaeef4a67..7de0d4c0ed6b 100644 --- a/include/linux/io_uring_types.h +++ b/include/linux/io_uring_types.h @@ -40,8 +40,26 @@ enum io_uring_cmd_flags { IO_URING_F_COMPAT = (1 << 12), }; +struct io_rsrc_node { + unsigned char type; + unsigned char flags; + int refs; + + u64 tag; + union { + unsigned long file_ptr; + struct io_mapped_buf *buf; + }; +}; + +typedef void (io_uring_kbuf_ack_t) (struct io_rsrc_node *); + struct io_mapped_buf { - u64 addr; + /* 'addr' is always 0 for kernel buffer */ + union { + u64 addr; + io_uring_kbuf_ack_t *kbuf_ack; + }; unsigned int len; unsigned int nr_bvecs; refcount_t refs; diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index b0b60ae0456a..327bc1a83e4b 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -441,6 +441,18 @@ int io_files_update(struct io_kiocb *req, unsigned int issue_flags) return IOU_OK; } +static void __io_free_buf_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node) +{ + struct io_mapped_buf *buf = node->buf; + + if (node->flags & IORING_RSRC_F_BUF_KERNEL) { + if (buf->kbuf_ack) + buf->kbuf_ack(node); + } else { + io_buffer_unmap(ctx, node); + } +} + void io_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node) { bool need_free = node->flags & IORING_RSRC_F_NEED_FREE; @@ -457,7 +469,7 @@ void io_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node) break; case IORING_RSRC_BUFFER: if (node->buf) - io_buffer_unmap(ctx, node); + __io_free_buf_node(ctx, node); break; default: WARN_ON_ONCE(1); diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index 3bc3a484fbba..f45a26c3b79d 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -14,18 +14,7 @@ enum { __IORING_RSRC_LAST_TYPE, IORING_RSRC_F_NEED_FREE = 1 << 0, -}; - -struct io_rsrc_node { - unsigned char type; - unsigned char flags; - int refs; - - u64 tag; - union { - unsigned long file_ptr; - struct io_mapped_buf *buf; - }; + IORING_RSRC_F_BUF_KERNEL = 1 << 1, }; struct io_imu_folio_data { From patchwork Thu Nov 7 11:01:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 13866173 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A7341F130C for ; Thu, 7 Nov 2024 11:02:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977369; cv=none; b=uM+JJz4wKsDiaPj40tmdZr8OLA4ZQ4abOZkyRqcc6yWATUJf7GVghNXfrcSHWfX4VCBimPlMtMMZEWMZRWtfzj/DR1ZhzFBC2oIqkiyFSy7rq0wsIpWnG8Q2PdvpcoGbAFj7GE9L28GBTKw3PawtTBAtdSP66yHzgIk05dT71Ns= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977369; c=relaxed/simple; bh=WLUXOs7MNWpkEgzEkLmfGnLAZ+OFhefO3mr3LpA6yjQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YrtziC8HOitgPY4dPLnfIzNJB6lPRtefS+kwi31dVKXknQ3m0kru0v4jJl1ezBj8bOdhkntFCo59iVO4+fkT9xVftRKR0slok6zlpsRgHvvonWhLRcO1jOwDTe2Pow8Fp1GJt2vBFCoWG8h/AGAiDYS9WpgYIaMTNiDnwDJvqUY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=dG1IyglK; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="dG1IyglK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730977366; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AVlqwA/Orn5NedMGzu2+4AFeFVHVMFMTnRQroUg9LgA=; b=dG1IyglKL203u5XP6XEAwR+JwspJXk6fFggQ9MryQB+yg+zPmqtQopU9bnfotQwelHaAf7 z8+E3IEmEi/bRcDI2vWPplnqOTIThRMlhgD2BjXmRz/9KM+NX+CGwLsM+7QCIukKUPlp/r YgRZAYtEghouyBRyZymmYGXcgt11Z0g= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-185-zPNixEhHMcGwczNAxmkaGw-1; Thu, 07 Nov 2024 06:02:43 -0500 X-MC-Unique: zPNixEhHMcGwczNAxmkaGw-1 X-Mimecast-MFC-AGG-ID: zPNixEhHMcGwczNAxmkaGw Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 50B74195419F; Thu, 7 Nov 2024 11:02:42 +0000 (UTC) Received: from localhost (unknown [10.72.116.54]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5C52D195E480; Thu, 7 Nov 2024 11:02:40 +0000 (UTC) From: Ming Lei To: Jens Axboe , io-uring@vger.kernel.org, Pavel Begunkov Cc: linux-block@vger.kernel.org, Uday Shankar , Akilesh Kailash , Ming Lei Subject: [PATCH V10 10/12] io_uring: support leased group buffer with REQ_F_GROUP_BUF Date: Thu, 7 Nov 2024 19:01:43 +0800 Message-ID: <20241107110149.890530-11-ming.lei@redhat.com> In-Reply-To: <20241107110149.890530-1-ming.lei@redhat.com> References: <20241107110149.890530-1-ming.lei@redhat.com> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 SQE group introduces one new mechanism to share resource among one group of requests, and all member requests can consume the resource leased by group leader efficiently in parallel. This patch uses the added SQE group to lease kernel buffer from group leader(driver) to members(io_uring) in sqe group: - this kernel buffer is owned by kernel device(driver), and has very short lifetime, such as, it is often aligned with block IO lifetime - group leader leases the kernel buffer from driver to member requests of io_uring subsystem - member requests uses the leased buffer to do FS or network IO, IOSQE_IO_DRAIN bit isn't used for group member IO, so it is mapped to GROUP_KBUF; the actual use becomes very similar with buffer select. - this kernel buffer is returned back after all member requests are completed io_uring builtin provide/register buffer isn't one good match for this use case: - complicated dependency on add/remove buffer this buffer has to be added/removed to one global table by add/remove OPs, and all consumer OPs have to sync with the add/remove OPs; either consumer OPs have to by issued one by one with IO_LINK; or two extra syscall are added for one time of buffer lease & consumption, this way slows down ublk io handling, and may lose zero copy value - application becomes more complicated - application may panic and the kernel buffer is left in io_uring, which complicates io_uring shutdown handling since returning back buffer needs to cowork with buffer owner - big change is needed in io_uring provide/register buffer - the requirement is just to lease the kernel buffer to io_uring subsystem for very short time, not necessary to move it into io_uring and make it global This way looks a bit similar with kernel's pipe/splice, but there are some important differences: - splice is for transferring data between two FDs via pipe, and fd_out can only read data from pipe, but data can't be written to; this feature can lease buffer from group leader(driver subsystem) to members(io_uring subsystem), so member request can write data to this buffer if the buffer direction is allowed to write to. - splice implements data transfer by moving pages between subsystem and pipe, that means page ownership is transferred, and this way is one of the most complicated thing of splice; this patch supports scenarios in which the buffer can't be transferred, and buffer is only borrowed to member requests for consumption, and is returned back after member requests consume the leased buffer, so buffer lifetime is aligned with group leader lifetime, and buffer lifetime is simplified a lot. Especially the buffer is guaranteed to be returned back. - splice can't run in async way basically It can help to implement generic zero copy between device and related operations, such as ublk, fuse. Signed-off-by: Ming Lei --- include/linux/io_uring_types.h | 6 ++++ io_uring/io_uring.c | 24 ++++++++++++--- io_uring/io_uring.h | 5 ++++ io_uring/kbuf.c | 54 ++++++++++++++++++++++++++++++++-- io_uring/kbuf.h | 30 +++++++++++++++++-- io_uring/net.c | 27 ++++++++++++++++- io_uring/opdef.c | 4 +++ io_uring/opdef.h | 2 ++ io_uring/rsrc.h | 7 +++++ io_uring/rw.c | 37 +++++++++++++++++++---- 10 files changed, 180 insertions(+), 16 deletions(-) diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h index 7de0d4c0ed6b..b919ab62020c 100644 --- a/include/linux/io_uring_types.h +++ b/include/linux/io_uring_types.h @@ -518,6 +518,8 @@ enum { REQ_F_BUFFERS_COMMIT_BIT, REQ_F_BUF_NODE_BIT, REQ_F_GROUP_LEADER_BIT, + REQ_F_GROUP_BUF_BIT, + REQ_F_BUF_IMPORTED_BIT, /* not a real bit, just to check we're not overflowing the space */ __REQ_F_LAST_BIT, @@ -602,6 +604,10 @@ enum { REQ_F_BUF_NODE = IO_REQ_FLAG(REQ_F_BUF_NODE_BIT), /* sqe group lead */ REQ_F_GROUP_LEADER = IO_REQ_FLAG(REQ_F_GROUP_LEADER_BIT), + /* Use group leader's buffer */ + REQ_F_GROUP_BUF = IO_REQ_FLAG(REQ_F_GROUP_BUF_BIT), + /* used in case buffer has to be imported from ->issue() once */ + REQ_F_BUF_IMPORTED = IO_REQ_FLAG(REQ_F_BUF_IMPORTED_BIT), }; typedef void (*io_req_tw_func_t)(struct io_kiocb *req, struct io_tw_state *ts); diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 076171977d5e..c0d8b3c34d71 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -925,14 +925,21 @@ static void io_queue_group_members(struct io_kiocb *req) req->grp_link = NULL; while (member) { struct io_kiocb *next = member->grp_link; + bool grp_buf = member->flags & REQ_F_GROUP_BUF; member->grp_leader = req; if (unlikely(member->flags & REQ_F_FAIL)) io_req_task_queue_fail(member, member->cqe.res); + else if (unlikely(grp_buf && !(req->flags & REQ_F_BUF_NODE && + io_issue_defs[member->opcode].group_buf))) + io_req_task_queue_fail(member, -EINVAL); else if (unlikely(req->flags & REQ_F_FAIL)) io_req_task_queue_fail(member, -ECANCELED); - else + else { + if (grp_buf) + io_req_assign_buf_node(member, req->buf_node); io_req_task_queue(member); + } member = next; } } @@ -2196,9 +2203,18 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, if (sqe_flags & IOSQE_CQE_SKIP_SUCCESS) ctx->drain_disabled = true; if (sqe_flags & IOSQE_IO_DRAIN) { - if (ctx->drain_disabled) - return io_init_fail_req(req, -EOPNOTSUPP); - io_init_req_drain(req); + /* IO_DRAIN is mapped to GROUP_BUF for group members */ + if (ctx->submit_state.group.head) { + /* can't do buffer select */ + if (sqe_flags & IOSQE_BUFFER_SELECT) + return io_init_fail_req(req, -EINVAL); + req->flags &= ~REQ_F_IO_DRAIN; + req->flags |= REQ_F_GROUP_BUF; + } else { + if (ctx->drain_disabled) + return io_init_fail_req(req, -EOPNOTSUPP); + io_init_req_drain(req); + } } } if (unlikely(ctx->restricted || ctx->drain_active || ctx->drain_next)) { diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h index facd5c85ba8b..b14acb58b573 100644 --- a/io_uring/io_uring.h +++ b/io_uring/io_uring.h @@ -363,6 +363,11 @@ static inline bool req_is_group_leader(struct io_kiocb *req) return req->flags & REQ_F_GROUP_LEADER; } +static inline bool req_is_group_member(struct io_kiocb *req) +{ + return (req->flags & REQ_F_GROUP) && !req_is_group_leader(req); +} + /* * Don't complete immediately but use deferred completion infrastructure. * Protected by ->uring_lock and can only be used either with diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c index c4a776860cb4..6b2f74daf135 100644 --- a/io_uring/kbuf.c +++ b/io_uring/kbuf.c @@ -847,9 +847,9 @@ int io_pbuf_mmap(struct file *file, struct vm_area_struct *vma) * Also kernel buffer lifetime is bound with request, and we needn't * to use rsrc_node to track its lifetime */ -int io_import_kbuf(int ddir, struct iov_iter *iter, - const struct io_mapped_buf *kbuf, - u64 buf_off, size_t len) +static int io_import_kbuf(int ddir, struct iov_iter *iter, + const struct io_mapped_buf *kbuf, + u64 buf_off, size_t len) { unsigned long offset = kbuf->offset; @@ -872,3 +872,51 @@ int io_import_kbuf(int ddir, struct iov_iter *iter, return 0; } + +int io_import_group_buf(struct io_kiocb *req, int dir, struct iov_iter *iter, + unsigned long buf_off, unsigned int len) +{ + int ret; + + if (!req_is_group_member(req)) + return -EINVAL; + + if (!(req->flags & REQ_F_BUF_NODE)) + return -EINVAL; + + if (req->flags & REQ_F_BUF_IMPORTED) + return 0; + + ret = io_import_kbuf(dir, iter, req->buf_node->buf, buf_off, len); + if (!ret) + req->flags |= REQ_F_BUF_IMPORTED; + return ret; +} + +int io_lease_group_kbuf(struct io_kiocb *req, + struct io_rsrc_node *node) +{ + const struct io_mapped_buf *buf = node->buf; + + if (!(req->flags & REQ_F_GROUP_LEADER)) + return -EINVAL; + + if (req->flags & (REQ_F_BUFFER_SELECT | REQ_F_BUF_NODE)) + return -EINVAL; + + if (!buf || !buf->kbuf_ack || !buf->pbvec || !buf->kbuf) + return -EINVAL; + + /* + * Allow io_uring OPs to borrow this leased kbuf, which is returned + * back by calling `kbuf_ack` when the group leader is freed. + * + * Not like pipe/splice, this kernel buffer is always owned by the + * provider, and has to be returned back. + */ + io_rsrc_node_init(node, IORING_RSRC_BUFFER, IORING_RSRC_F_BUF_KERNEL); + req->buf_node = node; + + req->flags |= REQ_F_GROUP_BUF | REQ_F_BUF_NODE; + return 0; +} diff --git a/io_uring/kbuf.h b/io_uring/kbuf.h index 04ccd52dd0ad..2e47ac33aa60 100644 --- a/io_uring/kbuf.h +++ b/io_uring/kbuf.h @@ -3,6 +3,7 @@ #define IOU_KBUF_H #include +#include "rsrc.h" enum { /* ring mapped provided buffers */ @@ -88,9 +89,10 @@ void io_put_bl(struct io_ring_ctx *ctx, struct io_buffer_list *bl); struct io_buffer_list *io_pbuf_get_bl(struct io_ring_ctx *ctx, unsigned long bgid); int io_pbuf_mmap(struct file *file, struct vm_area_struct *vma); -int io_import_kbuf(int ddir, struct iov_iter *iter, - const struct io_mapped_buf *kbuf, - u64 buf_off, size_t len); + +int io_import_group_buf(struct io_kiocb *req, int dir, struct iov_iter *iter, + unsigned long buf_off, unsigned int len); +int io_lease_group_kbuf(struct io_kiocb *req, struct io_rsrc_node *node); static inline bool io_kbuf_recycle_ring(struct io_kiocb *req) { @@ -223,4 +225,26 @@ static inline unsigned int io_put_kbufs(struct io_kiocb *req, int len, { return __io_put_kbufs(req, len, nbufs, issue_flags); } + +static inline bool io_use_group_buf(struct io_kiocb *req) +{ + return req->flags & REQ_F_GROUP_BUF; +} + +static inline bool io_use_group_kbuf(struct io_kiocb *req) +{ + if (io_use_group_buf(req)) + return io_req_use_kernel_buf(req); + return false; +} + +/* zero remained bytes of kernel buffer for avoiding to leak data */ +static inline void io_req_zero_remained(struct io_kiocb *req, struct iov_iter *iter) +{ + size_t left = iov_iter_count(iter); + + if (iov_iter_rw(iter) == READ && left > 0) + iov_iter_zero(left, iter); +} + #endif diff --git a/io_uring/net.c b/io_uring/net.c index df1f7dc6f1c8..855bf101d54f 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -88,6 +88,13 @@ struct io_sr_msg { */ #define MULTISHOT_MAX_RETRY 32 +#define user_ptr_to_u64(x) ( \ +{ \ + typecheck(void __user *, (x)); \ + (u64)(unsigned long)(x); \ +} \ +) + int io_shutdown_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { struct io_shutdown *shutdown = io_kiocb_to_cmd(req, struct io_shutdown); @@ -384,7 +391,7 @@ static int io_send_setup(struct io_kiocb *req, const struct io_uring_sqe *sqe) kmsg->msg.msg_name = &kmsg->addr; kmsg->msg.msg_namelen = addr_len; } - if (!io_do_buffer_select(req)) { + if (!io_do_buffer_select(req) && !io_use_group_buf(req)) { ret = import_ubuf(ITER_SOURCE, sr->buf, sr->len, &kmsg->msg.msg_iter); if (unlikely(ret < 0)) @@ -599,6 +606,15 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags) if (issue_flags & IO_URING_F_NONBLOCK) flags |= MSG_DONTWAIT; + if (io_use_group_buf(req)) { + ret = io_import_group_buf(req, ITER_SOURCE, + &kmsg->msg.msg_iter, + user_ptr_to_u64(sr->buf), + sr->len); + if (unlikely(ret)) + return ret; + } + retry_bundle: if (io_do_buffer_select(req)) { struct buf_sel_arg arg = { @@ -889,6 +905,8 @@ static inline bool io_recv_finish(struct io_kiocb *req, int *ret, *ret = IOU_STOP_MULTISHOT; else *ret = IOU_OK; + if (io_use_group_kbuf(req)) + io_req_zero_remained(req, &kmsg->msg.msg_iter); io_req_msg_cleanup(req, issue_flags); return true; } @@ -1161,6 +1179,13 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags) goto out_free; } sr->buf = NULL; + } else if (io_use_group_buf(req)) { + ret = io_import_group_buf(req, ITER_DEST, + &kmsg->msg.msg_iter, + user_ptr_to_u64(sr->buf), + sr->len); + if (unlikely(ret)) + goto out_free; } kmsg->msg.msg_flags = 0; diff --git a/io_uring/opdef.c b/io_uring/opdef.c index 3de75eca1c92..4426e8e7a2f1 100644 --- a/io_uring/opdef.c +++ b/io_uring/opdef.c @@ -246,6 +246,7 @@ const struct io_issue_def io_issue_defs[] = { .ioprio = 1, .iopoll = 1, .iopoll_queue = 1, + .group_buf = 1, .async_size = sizeof(struct io_async_rw), .prep = io_prep_read, .issue = io_read, @@ -260,6 +261,7 @@ const struct io_issue_def io_issue_defs[] = { .ioprio = 1, .iopoll = 1, .iopoll_queue = 1, + .group_buf = 1, .async_size = sizeof(struct io_async_rw), .prep = io_prep_write, .issue = io_write, @@ -282,6 +284,7 @@ const struct io_issue_def io_issue_defs[] = { .audit_skip = 1, .ioprio = 1, .buffer_select = 1, + .group_buf = 1, #if defined(CONFIG_NET) .async_size = sizeof(struct io_async_msghdr), .prep = io_sendmsg_prep, @@ -297,6 +300,7 @@ const struct io_issue_def io_issue_defs[] = { .buffer_select = 1, .audit_skip = 1, .ioprio = 1, + .group_buf = 1, #if defined(CONFIG_NET) .async_size = sizeof(struct io_async_msghdr), .prep = io_recvmsg_prep, diff --git a/io_uring/opdef.h b/io_uring/opdef.h index 14456436ff74..44597d45d7c6 100644 --- a/io_uring/opdef.h +++ b/io_uring/opdef.h @@ -27,6 +27,8 @@ struct io_issue_def { unsigned iopoll_queue : 1; /* vectored opcode, set if 1) vectored, and 2) handler needs to know */ unsigned vectored : 1; + /* support group buffer */ + unsigned group_buf : 1; /* size of async data needed, if any */ unsigned short async_size; diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index f45a26c3b79d..9d001d72b65d 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -110,6 +110,13 @@ static inline void io_req_assign_buf_node(struct io_kiocb *req, req->flags |= REQ_F_BUF_NODE; } +static inline bool io_req_use_kernel_buf(struct io_kiocb *req) +{ + if (req->flags & REQ_F_BUF_NODE) + return req->buf_node->flags & IORING_RSRC_F_BUF_KERNEL; + return false; +} + int io_files_update(struct io_kiocb *req, unsigned int issue_flags); int io_files_update_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe); diff --git a/io_uring/rw.c b/io_uring/rw.c index b62cdb5fc936..f0a4e4524188 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -487,6 +487,11 @@ static bool __io_complete_rw_common(struct io_kiocb *req, long res) } req_set_fail(req); req->cqe.res = res; + if (io_use_group_kbuf(req)) { + struct io_async_rw *io = req->async_data; + + io_req_zero_remained(req, &io->iter); + } } return false; } @@ -628,11 +633,15 @@ static inline loff_t *io_kiocb_ppos(struct kiocb *kiocb) */ static ssize_t loop_rw_iter(int ddir, struct io_rw *rw, struct iov_iter *iter) { + struct io_kiocb *req = cmd_to_io_kiocb(rw); struct kiocb *kiocb = &rw->kiocb; struct file *file = kiocb->ki_filp; ssize_t ret = 0; loff_t *ppos; + if (io_use_group_kbuf(req)) + return -EOPNOTSUPP; + /* * Don't support polled IO through this interface, and we can't * support non-blocking either. For the latter, this just causes @@ -831,20 +840,32 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode, int rw_type) return 0; } +static int rw_import_group_buf(struct io_kiocb *req, int dir, + struct io_rw *rw, struct io_async_rw *io) +{ + int ret = io_import_group_buf(req, dir, &io->iter, rw->addr, rw->len); + + if (!ret) + iov_iter_save_state(&io->iter, &io->iter_state); + return ret; +} + static int __io_read(struct io_kiocb *req, unsigned int issue_flags) { bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK; struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw); struct io_async_rw *io = req->async_data; struct kiocb *kiocb = &rw->kiocb; - ssize_t ret; + ssize_t ret = 0; loff_t *ppos; - if (io_do_buffer_select(req)) { + if (io_do_buffer_select(req)) ret = io_import_iovec(ITER_DEST, req, io, issue_flags); - if (unlikely(ret < 0)) - return ret; - } + else if (io_use_group_buf(req)) + ret = rw_import_group_buf(req, ITER_DEST, rw, io); + if (unlikely(ret < 0)) + return ret; + ret = io_rw_init_file(req, FMODE_READ, READ); if (unlikely(ret)) return ret; @@ -1027,6 +1048,12 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags) ssize_t ret, ret2; loff_t *ppos; + if (io_use_group_buf(req)) { + ret = rw_import_group_buf(req, ITER_SOURCE, rw, io); + if (unlikely(ret < 0)) + return ret; + } + ret = io_rw_init_file(req, FMODE_WRITE, WRITE); if (unlikely(ret)) return ret; From patchwork Thu Nov 7 11:01:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 13866174 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F11D91F4260 for ; Thu, 7 Nov 2024 11:02:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977373; cv=none; b=tHQtcRqoflTFg2BSo5o3GMMk+DYrz17Rm70UYNfZo9+Gk2/GssdCp9fO9rcOmon4DOmEqnSBxURKFBF42grW21mlZ3DMgqtBaiTy1wMbRimVVOViysJ4WSm3PIJT6NxsswoQ7umRc5zxPT3RrDUrAT22YCjZpxq/H5anaGNwyM8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977373; c=relaxed/simple; bh=NZJz+MfkbY392ub/DHGzxgS6cymJL7zcbYfAl3y7Pgk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Y8i84coRj8nThL/Fj3rkMZt82EemFZQlRT8CcQGyRdNd4g6kEN38NQz7kYKWMvkFPN40xjMQeZRaXOxKCYN5QMp+IOwdWdhKNhThkLLmiMX7+BzpA8xK4mqLP0KH183076pKeKhAzx3J2ImPzLmKQR7LxdD2qghIyrgYW+Zptj0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Ips2zOeL; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Ips2zOeL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730977371; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=C1/P1RCfeEfoec5Dd70p3CI65Q7oJutsf47QDyw0okI=; b=Ips2zOeLO1TVZs2Uz5DvDYJl9FlIl8iROi8e8smwVFPkfBnYxm9nyyTFkTf2ianhwLax1E PbrYq+s1AucASrWglWSPO7TmUlkBQYZCKvkoZQXDwQo8vMtKmaD3tEJk/U9k/QaOOopSyg BPoWl/XIwTWiMxSK7ulK8cY3GrSRO3Q= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-400-fa_4EcmFMISrUjoD2tI3gA-1; Thu, 07 Nov 2024 06:02:48 -0500 X-MC-Unique: fa_4EcmFMISrUjoD2tI3gA-1 X-Mimecast-MFC-AGG-ID: fa_4EcmFMISrUjoD2tI3gA Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A7AB21955D58; Thu, 7 Nov 2024 11:02:46 +0000 (UTC) Received: from localhost (unknown [10.72.116.54]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7B826196BC05; Thu, 7 Nov 2024 11:02:45 +0000 (UTC) From: Ming Lei To: Jens Axboe , io-uring@vger.kernel.org, Pavel Begunkov Cc: linux-block@vger.kernel.org, Uday Shankar , Akilesh Kailash , Ming Lei Subject: [PATCH V10 11/12] io_uring/uring_cmd: support leasing device kernel buffer to io_uring Date: Thu, 7 Nov 2024 19:01:44 +0800 Message-ID: <20241107110149.890530-12-ming.lei@redhat.com> In-Reply-To: <20241107110149.890530-1-ming.lei@redhat.com> References: <20241107110149.890530-1-ming.lei@redhat.com> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Add API of io_uring_cmd_lease_kbuf() for driver to lease its kernel buffer to io_uring. The leased buffer can only be consumed by io_uring OPs in group wide, and the uring_cmd has to be one group leader. This way can support generic device zero copy over device buffer in userspace: - create one sqe group - lease one device buffer to io_uring by the group leader of uring_cmd - io_uring member OPs consume this kernel buffer by passing IOSQE_IO_DRAIN which isn't used for group member, and mapped to GROUP_BUF. - the kernel buffer is returned back after all member OPs are completed Signed-off-by: Ming Lei --- include/linux/io_uring/cmd.h | 7 +++++++ io_uring/uring_cmd.c | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/linux/io_uring/cmd.h b/include/linux/io_uring/cmd.h index 578a3fdf5c71..0997ea247188 100644 --- a/include/linux/io_uring/cmd.h +++ b/include/linux/io_uring/cmd.h @@ -60,6 +60,8 @@ void io_uring_cmd_mark_cancelable(struct io_uring_cmd *cmd, /* Execute the request from a blocking context */ void io_uring_cmd_issue_blocking(struct io_uring_cmd *ioucmd); +int io_uring_cmd_lease_kbuf(struct io_uring_cmd *ioucmd, + struct io_rsrc_node *node); #else static inline int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, struct iov_iter *iter, void *ioucmd) @@ -82,6 +84,11 @@ static inline void io_uring_cmd_mark_cancelable(struct io_uring_cmd *cmd, static inline void io_uring_cmd_issue_blocking(struct io_uring_cmd *ioucmd) { } +static inline int io_uring_cmd_lease_kbuf(struct io_uring_cmd *ioucmd, + struct io_rsrc_node *node); +{ + return -EOPNOTSUPP; +} #endif /* diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c index b62965f58f30..e7723759cb23 100644 --- a/io_uring/uring_cmd.c +++ b/io_uring/uring_cmd.c @@ -15,6 +15,7 @@ #include "alloc_cache.h" #include "rsrc.h" #include "uring_cmd.h" +#include "kbuf.h" static struct uring_cache *io_uring_async_get(struct io_kiocb *req) { @@ -175,6 +176,15 @@ void io_uring_cmd_done(struct io_uring_cmd *ioucmd, ssize_t ret, ssize_t res2, } EXPORT_SYMBOL_GPL(io_uring_cmd_done); +int io_uring_cmd_lease_kbuf(struct io_uring_cmd *ioucmd, + struct io_rsrc_node *node) +{ + struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); + + return io_lease_group_kbuf(req, node); +} +EXPORT_SYMBOL_GPL(io_uring_cmd_lease_kbuf); + static int io_uring_cmd_prep_setup(struct io_kiocb *req, const struct io_uring_sqe *sqe) { From patchwork Thu Nov 7 11:01:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 13866175 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E65E013C682 for ; Thu, 7 Nov 2024 11:02:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977377; cv=none; b=IzVk/8iKKjZzUKpoOzJWktJ9W5zV8tELxUbN2fSYkyW+wp1y8SrWImBERwiP8ooOB1Wg1Zp36QZLnCWF4NhEasVz4GjA8vPjQci8oBDxVWT/d88PfenhDDz1K+wWesEf6LLeDXryVIF0BgDzjT1vOXJ/8C9/56vGDm1MEFzpluw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730977377; c=relaxed/simple; bh=H7jFIdMVORMT+sdsRO+YN7e3BRjztjDL1TqpZ3/GqYs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AQxSJB5wVnKbAUQFffFs7/p/xHKDL4Dgp7pd2QTAhWthVCHZqiGi3TgZNBWk8byPupHVnIBw77V+74KsHbnirtK/tzTL7v6pAyM/F/dJXHuLEvouPjuJsPV0oPe9A9ITJAKjDcxMODLufjSJ/xWBsHSjE9xLcmggInPJFmUhRYk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=O8GkJAIv; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="O8GkJAIv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730977375; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pBCX2kuoWChvKhvKTksy4cTtgPbvuSqKubX4am/5b+8=; b=O8GkJAIvZL+Vy/nay+QTYJ0xfnpbFsTiYW/q0FTySQwbwwomp8rFZBQjL8mpgBVw/4i409 G/lmR1Hjhy+hmSBzjONzzZ2Swvg9j9naJ/oIMgUyq+OVS5xGJcF4Pit2YR+35Munp2IVmT iCqU7D0K6aB4y0biVbm/gBNmEol4Mlc= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-70-8RhsM3N5N4q0k3QVhBmKCw-1; Thu, 07 Nov 2024 06:02:52 -0500 X-MC-Unique: 8RhsM3N5N4q0k3QVhBmKCw-1 X-Mimecast-MFC-AGG-ID: 8RhsM3N5N4q0k3QVhBmKCw Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id AE1741956069; Thu, 7 Nov 2024 11:02:50 +0000 (UTC) Received: from localhost (unknown [10.72.116.54]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B7877195E480; Thu, 7 Nov 2024 11:02:49 +0000 (UTC) From: Ming Lei To: Jens Axboe , io-uring@vger.kernel.org, Pavel Begunkov Cc: linux-block@vger.kernel.org, Uday Shankar , Akilesh Kailash , Ming Lei Subject: [PATCH V10 12/12] ublk: support leasing io buffer to io_uring Date: Thu, 7 Nov 2024 19:01:45 +0800 Message-ID: <20241107110149.890530-13-ming.lei@redhat.com> In-Reply-To: <20241107110149.890530-1-ming.lei@redhat.com> References: <20241107110149.890530-1-ming.lei@redhat.com> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Suopport to lease block IO buffer for userpace to run io_uring operations(FS, network IO), then ublk zero copy can be supported. userspace code: git clone https://github.com/ublk-org/ublksrv.git -b uring_group And both loop and nbd zero copy(io_uring send and send zc) are covered. Performance improvement is quite obvious in big block size test, such as 'loop --buffered_io' perf is doubled in 64KB block test("loop/007 vs loop/009"). Signed-off-by: Ming Lei --- drivers/block/ublk_drv.c | 168 ++++++++++++++++++++++++++++++++-- include/uapi/linux/ublk_cmd.h | 11 ++- 2 files changed, 169 insertions(+), 10 deletions(-) diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 6ba2c1dd1d87..d90f4cac8154 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -51,6 +51,8 @@ /* private ioctl command mirror */ #define UBLK_CMD_DEL_DEV_ASYNC _IOC_NR(UBLK_U_CMD_DEL_DEV_ASYNC) +#define UBLK_IO_PROVIDE_IO_BUF _IOC_NR(UBLK_U_IO_PROVIDE_IO_BUF) + /* All UBLK_F_* have to be included into UBLK_F_ALL */ #define UBLK_F_ALL (UBLK_F_SUPPORT_ZERO_COPY \ | UBLK_F_URING_CMD_COMP_IN_TASK \ @@ -67,10 +69,18 @@ (UBLK_PARAM_TYPE_BASIC | UBLK_PARAM_TYPE_DISCARD | \ UBLK_PARAM_TYPE_DEVT | UBLK_PARAM_TYPE_ZONED) +struct uring_kbuf { + struct io_rsrc_node node; + struct io_mapped_buf buf; +}; + struct ublk_rq_data { struct llist_node node; struct kref ref; + + bool allocated_bvec; + struct uring_kbuf buf[0]; }; struct ublk_uring_cmd_pdu { @@ -189,11 +199,15 @@ struct ublk_params_header { __u32 types; }; +static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub, + struct ublk_queue *ubq, int tag, size_t offset); static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq); static inline unsigned int ublk_req_build_flags(struct request *req); static inline struct ublksrv_io_desc *ublk_get_iod(struct ublk_queue *ubq, int tag); +static void ublk_io_buf_giveback_cb(struct io_rsrc_node *node); + static inline bool ublk_dev_is_user_copy(const struct ublk_device *ub) { return ub->dev_info.flags & UBLK_F_USER_COPY; @@ -588,6 +602,11 @@ static inline bool ublk_need_req_ref(const struct ublk_queue *ubq) return ublk_support_user_copy(ubq); } +static inline bool ublk_support_zc(const struct ublk_queue *ubq) +{ + return ubq->flags & UBLK_F_SUPPORT_ZERO_COPY; +} + static inline void ublk_init_req_ref(const struct ublk_queue *ubq, struct request *req) { @@ -851,6 +870,74 @@ static size_t ublk_copy_user_pages(const struct request *req, return done; } +/* + * The built command buffer is immutable, so it is fine to feed it to + * concurrent io_uring provide buf commands + */ +static int ublk_init_zero_copy_buffer(struct request *req) +{ + struct ublk_rq_data *data = blk_mq_rq_to_pdu(req); + struct io_rsrc_node *node = &data->buf->node; + struct io_mapped_buf *imu = &data->buf->buf; + struct req_iterator rq_iter; + unsigned int nr_bvecs = 0; + struct bio_vec *bvec; + unsigned int offset; + struct bio_vec bv; + + if (!ublk_rq_has_data(req)) + goto exit; + + rq_for_each_bvec(bv, req, rq_iter) + nr_bvecs++; + + if (!nr_bvecs) + goto exit; + + if (req->bio != req->biotail) { + int idx = 0; + + bvec = kvmalloc_array(nr_bvecs, sizeof(struct bio_vec), + GFP_NOIO); + if (!bvec) + return -ENOMEM; + + offset = 0; + rq_for_each_bvec(bv, req, rq_iter) + bvec[idx++] = bv; + data->allocated_bvec = true; + } else { + struct bio *bio = req->bio; + + offset = bio->bi_iter.bi_bvec_done; + bvec = __bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter); + } + imu->kbuf = 1; + imu->pbvec = bvec; + imu->nr_bvecs = nr_bvecs; + imu->offset = offset; + imu->len = blk_rq_bytes(req); + imu->dir = req_op(req) == REQ_OP_READ ? ITER_DEST : ITER_SOURCE; + imu->kbuf_ack = ublk_io_buf_giveback_cb; + node->buf = imu; + + return 0; +exit: + imu->pbvec = NULL; + return 0; +} + +static void ublk_deinit_zero_copy_buffer(struct request *req) +{ + struct ublk_rq_data *data = blk_mq_rq_to_pdu(req); + struct io_mapped_buf *imu = &data->buf->buf; + + if (data->allocated_bvec) { + kvfree(imu->pbvec); + data->allocated_bvec = false; + } +} + static inline bool ublk_need_map_req(const struct request *req) { return ublk_rq_has_data(req) && req_op(req) == REQ_OP_WRITE; @@ -862,13 +949,25 @@ static inline bool ublk_need_unmap_req(const struct request *req) (req_op(req) == REQ_OP_READ || req_op(req) == REQ_OP_DRV_IN); } -static int ublk_map_io(const struct ublk_queue *ubq, const struct request *req, +static int ublk_map_io(const struct ublk_queue *ubq, struct request *req, struct ublk_io *io) { const unsigned int rq_bytes = blk_rq_bytes(req); - if (ublk_support_user_copy(ubq)) + if (ublk_support_user_copy(ubq)) { + if (ublk_support_zc(ubq)) { + int ret = ublk_init_zero_copy_buffer(req); + + /* + * The only failure is -ENOMEM for allocating providing + * buffer command, return zero so that we can requeue + * this req. + */ + if (unlikely(ret)) + return 0; + } return rq_bytes; + } /* * no zero copy, we delay copy WRITE request data into ublksrv @@ -886,13 +985,16 @@ static int ublk_map_io(const struct ublk_queue *ubq, const struct request *req, } static int ublk_unmap_io(const struct ublk_queue *ubq, - const struct request *req, + struct request *req, struct ublk_io *io) { const unsigned int rq_bytes = blk_rq_bytes(req); - if (ublk_support_user_copy(ubq)) + if (ublk_support_user_copy(ubq)) { + if (ublk_support_zc(ubq)) + ublk_deinit_zero_copy_buffer(req); return rq_bytes; + } if (ublk_need_unmap_req(req)) { struct iov_iter iter; @@ -1038,6 +1140,7 @@ static inline void __ublk_complete_rq(struct request *req) return; exit: + ublk_deinit_zero_copy_buffer(req); blk_mq_end_request(req, res); } @@ -1680,6 +1783,46 @@ static inline void ublk_prep_cancel(struct io_uring_cmd *cmd, io_uring_cmd_mark_cancelable(cmd, issue_flags); } +static void ublk_io_buf_giveback_cb(struct io_rsrc_node *node) +{ + struct uring_kbuf *buf = (struct uring_kbuf *)node; + struct ublk_rq_data *data = container_of(buf, struct ublk_rq_data, buf[0]); + struct request *req = blk_mq_rq_from_pdu(data); + struct ublk_queue *ubq = req->mq_hctx->driver_data; + + ublk_put_req_ref(ubq, req); +} + +static int ublk_provide_io_buf(struct io_uring_cmd *cmd, + struct ublk_queue *ubq, int tag) +{ + struct ublk_device *ub = cmd->file->private_data; + struct ublk_rq_data *data; + struct request *req; + + if (!ub) + return -EPERM; + + req = __ublk_check_and_get_req(ub, ubq, tag, 0); + if (!req) + return -EINVAL; + + pr_devel("%s: qid %d tag %u request bytes %u\n", + __func__, tag, ubq->q_id, blk_rq_bytes(req)); + + data = blk_mq_rq_to_pdu(req); + + /* + * io_uring guarantees that the callback will be called after + * the provided buffer is consumed, and it is automatic removal + * before this uring command is freed. + * + * This request won't be completed unless the callback is called, + * so ublk module won't be unloaded too. + */ + return io_uring_cmd_lease_kbuf(cmd, &data->buf->node); +} + static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags, const struct ublksrv_io_cmd *ub_cmd) @@ -1731,6 +1874,10 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, ret = -EINVAL; switch (_IOC_NR(cmd_op)) { + case UBLK_IO_PROVIDE_IO_BUF: + if (unlikely(!ublk_support_zc(ubq))) + goto out; + return ublk_provide_io_buf(cmd, ubq, tag); case UBLK_IO_FETCH_REQ: /* UBLK_IO_FETCH_REQ is only allowed before queue is setup */ if (ublk_queue_ready(ubq)) { @@ -2149,11 +2296,14 @@ static void ublk_align_max_io_size(struct ublk_device *ub) static int ublk_add_tag_set(struct ublk_device *ub) { + int zc = !!(ub->dev_info.flags & UBLK_F_SUPPORT_ZERO_COPY); + struct ublk_rq_data *data; + ub->tag_set.ops = &ublk_mq_ops; ub->tag_set.nr_hw_queues = ub->dev_info.nr_hw_queues; ub->tag_set.queue_depth = ub->dev_info.queue_depth; ub->tag_set.numa_node = NUMA_NO_NODE; - ub->tag_set.cmd_size = sizeof(struct ublk_rq_data); + ub->tag_set.cmd_size = struct_size(data, buf, zc); ub->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; ub->tag_set.driver_data = ub; return blk_mq_alloc_tag_set(&ub->tag_set); @@ -2458,8 +2608,12 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd) goto out_free_dev_number; } - /* We are not ready to support zero copy */ - ub->dev_info.flags &= ~UBLK_F_SUPPORT_ZERO_COPY; + /* zero copy depends on user copy */ + if ((ub->dev_info.flags & UBLK_F_SUPPORT_ZERO_COPY) && + !ublk_dev_is_user_copy(ub)) { + ret = -EINVAL; + goto out_free_dev_number; + } ub->dev_info.nr_hw_queues = min_t(unsigned int, ub->dev_info.nr_hw_queues, nr_cpu_ids); diff --git a/include/uapi/linux/ublk_cmd.h b/include/uapi/linux/ublk_cmd.h index 12873639ea96..04d73b349709 100644 --- a/include/uapi/linux/ublk_cmd.h +++ b/include/uapi/linux/ublk_cmd.h @@ -94,6 +94,8 @@ _IOWR('u', UBLK_IO_COMMIT_AND_FETCH_REQ, struct ublksrv_io_cmd) #define UBLK_U_IO_NEED_GET_DATA \ _IOWR('u', UBLK_IO_NEED_GET_DATA, struct ublksrv_io_cmd) +#define UBLK_U_IO_PROVIDE_IO_BUF \ + _IOWR('u', 0x23, struct ublksrv_io_cmd) /* only ABORT means that no re-fetch */ #define UBLK_IO_RES_OK 0 @@ -127,9 +129,12 @@ #define UBLKSRV_IO_BUF_TOTAL_SIZE (1ULL << UBLKSRV_IO_BUF_TOTAL_BITS) /* - * zero copy requires 4k block size, and can remap ublk driver's io - * request into ublksrv's vm space - */ + * io_uring provide kbuf command based zero copy + * + * Not available for UBLK_F_UNPRIVILEGED_DEV, because we rely on ublk + * server to fill up request buffer for READ IO, and ublk server can't + * be trusted in case of UBLK_F_UNPRIVILEGED_DEV. +*/ #define UBLK_F_SUPPORT_ZERO_COPY (1ULL << 0) /*