Linux block layer
 help / color / mirror / Atom feed
* [PATCH 2/4] block: factor out a bio_await helper
From: Christoph Hellwig @ 2026-04-06  5:57 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Carlos Maiolino, Bart Van Assche, linux-block, linux-xfs
In-Reply-To: <20260406055728.472919-1-hch@lst.de>

Add a new helper to wait for a bio and anything chained off it to
complete synchronous after kicking it.  This factors common code out
of submit_bio_wait and bio_await_chain and will also be useful for
file system code and thus is exported.

Note that this will now set REQ_SYNC also for the bio_await case for
consistency.  Nothing should look at the flag in the end_io handler,
but if did, having the flag set makes more sense.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 block/bio.c         | 53 +++++++++++++++++++++++++++++++--------------
 include/linux/bio.h |  2 ++
 2 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 434e41182c05..c7e75d532666 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1468,17 +1468,20 @@ static void bio_wait_end_io(struct bio *bio)
 }
 
 /**
- * submit_bio_wait - submit a bio, and wait until it completes
- * @bio: The &struct bio which describes the I/O
+ * bio_await - call a function on a bio, and wait until it completes
+ * @bio:	the bio which describes the I/O
+ * @kick:	function called to "kick off" the bio
+ * @priv:	private data passed to @kick.
  *
- * Simple wrapper around submit_bio(). Returns 0 on success, or the error from
- * bio_endio() on failure.
+ * Wait for the bio as well as any bio chained off it after executing the
+ * passed in callback @kick.  The wait for the bio is set up before calling
+ * @kick to ensure that the completion is captured.  If @kick is %NULL,
+ * submit_bio() is used instead to submit the bio.
  *
- * WARNING: Unlike to how submit_bio() is usually used, this function does not
- * result in bio reference to be consumed. The caller must drop the reference
- * on his own.
+ * Note: this overrides the bi_private and bi_end_io fields in the bio.
  */
-int submit_bio_wait(struct bio *bio)
+void bio_await(struct bio *bio, void *priv,
+	       void (*kick)(struct bio *bio, void *priv))
 {
 	DECLARE_COMPLETION_ONSTACK_MAP(done,
 			bio->bi_bdev->bd_disk->lockdep_map);
@@ -1486,13 +1489,37 @@ int submit_bio_wait(struct bio *bio)
 	bio->bi_private = &done;
 	bio->bi_end_io = bio_wait_end_io;
 	bio->bi_opf |= REQ_SYNC;
-	submit_bio(bio);
+	if (kick)
+		kick(bio, priv);
+	else
+		submit_bio(bio);
 	blk_wait_io(&done);
+}
+EXPORT_SYMBOL_GPL(bio_await);
 
+/**
+ * submit_bio_wait - submit a bio, and wait until it completes
+ * @bio: The &struct bio which describes the I/O
+ *
+ * Simple wrapper around submit_bio(). Returns 0 on success, or the error from
+ * bio_endio() on failure.
+ *
+ * WARNING: Unlike to how submit_bio() is usually used, this function does not
+ * result in bio reference to be consumed. The caller must drop the reference
+ * on his own.
+ */
+int submit_bio_wait(struct bio *bio)
+{
+	bio_await(bio, NULL, NULL);
 	return blk_status_to_errno(bio->bi_status);
 }
 EXPORT_SYMBOL(submit_bio_wait);
 
+static void bio_endio_cb(struct bio *bio, void *priv)
+{
+	bio_endio(bio);
+}
+
 /**
  * bdev_rw_virt - synchronously read into / write from kernel mapping
  * @bdev:	block device to access
@@ -1528,13 +1555,7 @@ EXPORT_SYMBOL_GPL(bdev_rw_virt);
  */
 void bio_await_chain(struct bio *bio)
 {
-	DECLARE_COMPLETION_ONSTACK_MAP(done,
-			bio->bi_bdev->bd_disk->lockdep_map);
-
-	bio->bi_private = &done;
-	bio->bi_end_io = bio_wait_end_io;
-	bio_endio(bio);
-	blk_wait_io(&done);
+	bio_await(bio, NULL, bio_endio_cb);
 	bio_put(bio);
 }
 
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 984844d2870b..adcca9ad4eec 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -432,6 +432,8 @@ extern void bio_uninit(struct bio *);
 void bio_reset(struct bio *bio, struct block_device *bdev, blk_opf_t opf);
 void bio_reuse(struct bio *bio, blk_opf_t opf);
 void bio_chain(struct bio *, struct bio *);
+void bio_await(struct bio *bio, void *priv,
+	       void (*kick)(struct bio *bio, void *priv));
 
 int __must_check bio_add_page(struct bio *bio, struct page *page, unsigned len,
 			      unsigned off);
-- 
2.47.3


^ permalink raw reply related

* [PATCH 1/4] block: unify the synchronous bi_end_io callbacks
From: Christoph Hellwig @ 2026-04-06  5:57 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Carlos Maiolino, Bart Van Assche, linux-block, linux-xfs
In-Reply-To: <20260406055728.472919-1-hch@lst.de>

Put the bio in bio_await_chain after waiting for the completion, and
share the now identical callbacks between submit_bio_wait and
bio_await_chain.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
---
 block/bio.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index c8234d347fc5..434e41182c05 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1462,7 +1462,7 @@ void bio_iov_iter_unbounce(struct bio *bio, bool is_error, bool mark_dirty)
 		bio_iov_iter_unbounce_read(bio, is_error, mark_dirty);
 }
 
-static void submit_bio_wait_endio(struct bio *bio)
+static void bio_wait_end_io(struct bio *bio)
 {
 	complete(bio->bi_private);
 }
@@ -1484,7 +1484,7 @@ int submit_bio_wait(struct bio *bio)
 			bio->bi_bdev->bd_disk->lockdep_map);
 
 	bio->bi_private = &done;
-	bio->bi_end_io = submit_bio_wait_endio;
+	bio->bi_end_io = bio_wait_end_io;
 	bio->bi_opf |= REQ_SYNC;
 	submit_bio(bio);
 	blk_wait_io(&done);
@@ -1523,12 +1523,6 @@ int bdev_rw_virt(struct block_device *bdev, sector_t sector, void *data,
 }
 EXPORT_SYMBOL_GPL(bdev_rw_virt);
 
-static void bio_wait_end_io(struct bio *bio)
-{
-	complete(bio->bi_private);
-	bio_put(bio);
-}
-
 /*
  * bio_await_chain - ends @bio and waits for every chained bio to complete
  */
@@ -1541,6 +1535,7 @@ void bio_await_chain(struct bio *bio)
 	bio->bi_end_io = bio_wait_end_io;
 	bio_endio(bio);
 	blk_wait_io(&done);
+	bio_put(bio);
 }
 
 void __bio_advance(struct bio *bio, unsigned bytes)
-- 
2.47.3


^ permalink raw reply related

* refactor submit_bio_wait and bio await helpers v2
From: Christoph Hellwig @ 2026-04-06  5:57 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Carlos Maiolino, Bart Van Assche, linux-block, linux-xfs

Hi Jens,

this series factors common code between submit_bio_wait and
bio_await_chain into a common helper, and then uses that in XFS
as well instead of open coding such functionality.  It also
cleans up the submit or kill logic in the ioctl handlers to
share more code.

There is another places in btrfs that could be refactored to
use this, although it is non-trivial, and I plan to add more
users of this helper to XFS in the future.

Changes since v1:
 - preserve (and extend) setting REQ_SYNC

Diffstat:
 block/bio.c          |   81 ++++++++++++++++++++++++++++++++-------------------
 block/blk-lib.c      |   16 +---------
 block/blk.h          |    2 -
 block/ioctl.c        |   11 +-----
 fs/xfs/xfs_zone_gc.c |   19 +++--------
 include/linux/bio.h  |    2 +
 6 files changed, 63 insertions(+), 68 deletions(-)

^ permalink raw reply

* Re: [PATCH 3/4] block: add a bio_submit_or_kill helper
From: Christoph Hellwig @ 2026-04-06  5:51 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Christoph Hellwig, Jens Axboe, Carlos Maiolino, linux-block,
	linux-xfs
In-Reply-To: <dcb49ff0-fafd-42a1-addc-768912fba4f6@acm.org>

On Wed, Apr 01, 2026 at 08:42:15AM -0700, Bart Van Assche wrote:
> On 4/1/26 7:03 AM, Christoph Hellwig wrote:
>> Factor the common logic for the ioctl helpers to either submit a bio or
>> end if the process is being killed.  As this is now the only user of
>> bio_await_chain, open code that.
>
> There are two changes in this patch:
> - Inlining of bio_await_chain().
> - Introduction of bio_submit_or_kill().
>
> Please consider splitting this patch into two patches such that it
> becomes easier to review these changes.

No, not really.  We don't need a separate patch for killing a trivial
one-liner.


^ permalink raw reply

* Re: [PATCH 2/4] block: factor out a bio_await helper
From: Christoph Hellwig @ 2026-04-06  5:50 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Christoph Hellwig, Jens Axboe, Carlos Maiolino, linux-block,
	linux-xfs
In-Reply-To: <2065a50d-9029-44a6-9da0-4a2bb896bdb2@acm.org>

On Wed, Apr 01, 2026 at 08:35:10AM -0700, Bart Van Assche wrote:
>
> On 4/1/26 7:03 AM, Christoph Hellwig wrote:
>> +/**
>> + * bio_await - call a function on a bio, and wait until it completes
>> + * @bio:	the bio which describes the I/O
>> + * @kick:	function called to "kick off" the bio
>> + * @priv:	private data passed to @kick.
>> + *
>> + * Wait for the bio as well as any bio chained off it after executing the
>> + * passed in callback @kick.  The wait for the bio is set up before calling
>> + * @kick to ensure that the completion is captured.  If @kick is %NULL,
>> + * submit_bio() is used instead to submit the bio.
>> + *
>> + * Note: this overrides the bi_private and bi_end_io fields in the bio.
>> + */
>> +void bio_await(struct bio *bio, void *priv,
>> +	       void (*kick)(struct bio *bio, void *priv))
>
> Please consider swapping the @priv and @kick arguments because that's
> the argument order used elsewhere in the Linux kernel for callback
> function pointers and their private data pointer.

We have plenty of examples for both variants.  And the version here
generates objectively better code, because it keeps the arguments passed
on in the same registers.

> What happened to the bio->bi_opf |= REQ_SYNC statement? Shouldn't that 
> statement be preserved?

Yes.


^ permalink raw reply

* Re: [PATCH v2] block: Fix general protection fault in bio_integrity_map_user()
From: Christoph Hellwig @ 2026-04-06  5:39 UTC (permalink / raw)
  To: Sungwoo Kim
  Cc: Christoph Hellwig, Jens Axboe, Keith Busch, Chao Shi, Weidong Zhu,
	Dave Tian, linux-block, linux-kernel
In-Reply-To: <CAJNyHpK6ZPeRceCg5NWvvuRa23AMQYuwqhSQJcWJbNFiC6nrtA@mail.gmail.com>

On Fri, Apr 03, 2026 at 03:03:00AM +0900, Sungwoo Kim wrote:
> Thank you for letting me know about blktests. I'm learning this and
> finding a way to reproduce this bug.
> If blktests is not suitable for reproducing this - it might be too
> early to think about this though - I have another idea to reproduce
> this.
> I can modify the pin_user_pages_fast() source to make it always
> partial success, so there are always some unpinned pages, which is a
> precondition of this bug.
> I'd like to ask for comments on this if it doesn't make sense.

Using the failure injection framework to reproduce this sounds like a
good idea.


^ permalink raw reply

* [PATCH v2 0/2] ublk: fix infinite loop in ublk server teardown
From: Uday Shankar @ 2026-04-06  4:25 UTC (permalink / raw)
  To: Ming Lei, zhang, the-essence-of-life, Caleb Sander Mateos,
	Jens Axboe, Shuah Khan
  Cc: linux-block, linux-kernel, linux-kselftest, Uday Shankar

Fix an infinite loop in ublk server teardown which can arise when a ublk
server dies while recovering a device. Also add a test which
demonstrates the problem and verifies the fix.

Signed-off-by: Uday Shankar <ushankar@purestorage.com>
---
Changes in v2:
- Add support for batched fetch in pre_fetch_io (Ming Lei)
- Link to v1: https://lore.kernel.org/r/20260403-cancel-v1-0-86e5a6b3d3af@purestorage.com

---
Uday Shankar (2):
      ublk: reset per-IO canceled flag on each fetch
      selftests: ublk: test that teardown after incomplete recovery completes

 drivers/block/ublk_drv.c                        | 21 ++++++----
 tools/testing/selftests/ublk/Makefile           |  1 +
 tools/testing/selftests/ublk/fault_inject.c     | 52 +++++++++++++++++++++++--
 tools/testing/selftests/ublk/kublk.c            |  7 ++++
 tools/testing/selftests/ublk/kublk.h            |  3 ++
 tools/testing/selftests/ublk/test_generic_17.sh | 35 +++++++++++++++++
 6 files changed, 108 insertions(+), 11 deletions(-)
---
base-commit: cdd71b7feb3674d14c5edd9c133242ddf9a363f2
change-id: 20260403-cancel-bb6a1292534c

Best regards,
-- 
Uday Shankar <ushankar@purestorage.com>


^ permalink raw reply

* [PATCH v2 1/2] ublk: reset per-IO canceled flag on each fetch
From: Uday Shankar @ 2026-04-06  4:25 UTC (permalink / raw)
  To: Ming Lei, zhang, the-essence-of-life, Caleb Sander Mateos,
	Jens Axboe, Shuah Khan
  Cc: linux-block, linux-kernel, linux-kselftest, Uday Shankar
In-Reply-To: <20260405-cancel-v2-0-02d711e643c2@purestorage.com>

If a ublk server starts recovering devices but dies before issuing fetch
commands for all IOs, cancellation of the fetch commands that were
successfully issued may never complete. This is because the per-IO
canceled flag can remain set even after the fetch for that IO has been
submitted - the per-IO canceled flags for all IOs in a queue are reset
together only once all IOs for that queue have been fetched. So if a
nonempty proper subset of the IOs for a queue are fetched when the ublk
server dies, the IOs in that subset will never successfully be canceled,
as their canceled flags remain set, and this prevents ublk_cancel_cmd
from actually calling io_uring_cmd_done on the commands, despite the
fact that they are outstanding.

Fix this by resetting the per-IO cancel flags immediately when each IO
is fetched instead of waiting for all IOs for the queue (which may never
happen).

Signed-off-by: Uday Shankar <ushankar@purestorage.com>
Fixes: 728cbac5fe21 ("ublk: move device reset into ublk_ch_release()")
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: zhang, the-essence-of-life <zhangweize9@gmail.com>
---
 drivers/block/ublk_drv.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 3ba7da94d31499590a06a8b307ed151919a027cb..92dabeb820344107c9fadfae94396082b933d84e 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -2916,22 +2916,26 @@ static void ublk_stop_dev(struct ublk_device *ub)
 	ublk_cancel_dev(ub);
 }
 
+static void ublk_reset_io_flags(struct ublk_queue *ubq, struct ublk_io *io)
+{
+	/* UBLK_IO_FLAG_CANCELED can be cleared now */
+	spin_lock(&ubq->cancel_lock);
+	io->flags &= ~UBLK_IO_FLAG_CANCELED;
+	spin_unlock(&ubq->cancel_lock);
+}
+
 /* reset per-queue io flags */
 static void ublk_queue_reset_io_flags(struct ublk_queue *ubq)
 {
-	int j;
-
-	/* UBLK_IO_FLAG_CANCELED can be cleared now */
 	spin_lock(&ubq->cancel_lock);
-	for (j = 0; j < ubq->q_depth; j++)
-		ubq->ios[j].flags &= ~UBLK_IO_FLAG_CANCELED;
 	ubq->canceling = false;
 	spin_unlock(&ubq->cancel_lock);
 	ubq->fail_io = false;
 }
 
 /* device can only be started after all IOs are ready */
-static void ublk_mark_io_ready(struct ublk_device *ub, u16 q_id)
+static void ublk_mark_io_ready(struct ublk_device *ub, u16 q_id,
+	struct ublk_io *io)
 	__must_hold(&ub->mutex)
 {
 	struct ublk_queue *ubq = ublk_get_queue(ub, q_id);
@@ -2940,6 +2944,7 @@ static void ublk_mark_io_ready(struct ublk_device *ub, u16 q_id)
 		ub->unprivileged_daemons = true;
 
 	ubq->nr_io_ready++;
+	ublk_reset_io_flags(ubq, io);
 
 	/* Check if this specific queue is now fully ready */
 	if (ublk_queue_ready(ubq)) {
@@ -3202,7 +3207,7 @@ static int ublk_fetch(struct io_uring_cmd *cmd, struct ublk_device *ub,
 	if (!ret)
 		ret = ublk_config_io_buf(ub, io, cmd, buf_addr, NULL);
 	if (!ret)
-		ublk_mark_io_ready(ub, q_id);
+		ublk_mark_io_ready(ub, q_id, io);
 	mutex_unlock(&ub->mutex);
 	return ret;
 }
@@ -3610,7 +3615,7 @@ static int ublk_batch_prep_io(struct ublk_queue *ubq,
 	ublk_io_unlock(io);
 
 	if (!ret)
-		ublk_mark_io_ready(data->ub, ubq->q_id);
+		ublk_mark_io_ready(data->ub, ubq->q_id, io);
 
 	return ret;
 }

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 2/2] selftests: ublk: test that teardown after incomplete recovery completes
From: Uday Shankar @ 2026-04-06  4:25 UTC (permalink / raw)
  To: Ming Lei, zhang, the-essence-of-life, Caleb Sander Mateos,
	Jens Axboe, Shuah Khan
  Cc: linux-block, linux-kernel, linux-kselftest, Uday Shankar
In-Reply-To: <20260405-cancel-v2-0-02d711e643c2@purestorage.com>

Before the fix, teardown of a ublk server that was attempting to recover
a device, but died when it had submitted a nonempty proper subset of the
fetch commands to any queue would loop forever. Add a test to verify
that, after the fix, teardown completes. This is done by:

- Adding a new argument to the fault_inject target that causes it die
  after fetching a nonempty proper subset of the IOs to a queue
- Using that argument in a new test while trying to recover an
  already-created device
- Attempting to delete the ublk device at the end of the test; this
  hangs forever if teardown from the fault-injected ublk server never
  completed.

It was manually verified that the test passes with the fix and hangs
without it.

Signed-off-by: Uday Shankar <ushankar@purestorage.com>
---
 tools/testing/selftests/ublk/Makefile           |  1 +
 tools/testing/selftests/ublk/fault_inject.c     | 52 +++++++++++++++++++++++--
 tools/testing/selftests/ublk/kublk.c            |  7 ++++
 tools/testing/selftests/ublk/kublk.h            |  3 ++
 tools/testing/selftests/ublk/test_generic_17.sh | 35 +++++++++++++++++
 5 files changed, 95 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/ublk/Makefile b/tools/testing/selftests/ublk/Makefile
index 8ac2d4a682a1768fb1eb9d2dd2a5d01294a67a03..d338668c5a5fbd73f6d70165455a3551ab13e894 100644
--- a/tools/testing/selftests/ublk/Makefile
+++ b/tools/testing/selftests/ublk/Makefile
@@ -18,6 +18,7 @@ TEST_PROGS += test_generic_10.sh
 TEST_PROGS += test_generic_12.sh
 TEST_PROGS += test_generic_13.sh
 TEST_PROGS += test_generic_16.sh
+TEST_PROGS += test_generic_17.sh
 
 TEST_PROGS += test_batch_01.sh
 TEST_PROGS += test_batch_02.sh
diff --git a/tools/testing/selftests/ublk/fault_inject.c b/tools/testing/selftests/ublk/fault_inject.c
index 3b897f69c014cc73b4b469d816e80284dd21b577..150896e02ff8b3747fdc45eb2a6df7b52e134485 100644
--- a/tools/testing/selftests/ublk/fault_inject.c
+++ b/tools/testing/selftests/ublk/fault_inject.c
@@ -10,11 +10,17 @@
 
 #include "kublk.h"
 
+struct fi_opts {
+	long long delay_ns;
+	bool die_during_fetch;
+};
+
 static int ublk_fault_inject_tgt_init(const struct dev_ctx *ctx,
 				      struct ublk_dev *dev)
 {
 	const struct ublksrv_ctrl_dev_info *info = &dev->dev_info;
 	unsigned long dev_size = 250UL << 30;
+	struct fi_opts *opts = NULL;
 
 	if (ctx->auto_zc_fallback) {
 		ublk_err("%s: not support auto_zc_fallback\n", __func__);
@@ -35,17 +41,52 @@ static int ublk_fault_inject_tgt_init(const struct dev_ctx *ctx,
 	};
 	ublk_set_integrity_params(ctx, &dev->tgt.params);
 
-	dev->private_data = (void *)(unsigned long)(ctx->fault_inject.delay_us * 1000);
+	opts = calloc(1, sizeof(*opts));
+	if (!opts) {
+		ublk_err("%s: couldn't allocate memory for opts\n", __func__);
+		return -ENOMEM;
+	}
+
+	opts->delay_ns = ctx->fault_inject.delay_us * 1000;
+	opts->die_during_fetch = ctx->fault_inject.die_during_fetch;
+	dev->private_data = opts;
+
 	return 0;
 }
 
+static void ublk_fault_inject_pre_fetch_io(struct ublk_thread *t,
+					   struct ublk_queue *q, int tag,
+					   bool batch)
+{
+	struct fi_opts *opts = q->dev->private_data;
+
+	if (!opts->die_during_fetch)
+		return;
+
+	/*
+	 * Each queue fetches its IOs in increasing order of tags, so
+	 * dying just before we're about to fetch tag 1 (regardless of
+	 * what queue we're on) guarantees that we've fetched a nonempty
+	 * proper subset of the tags on that queue.
+	 */
+	if (tag == 1) {
+		/*
+		 * Ensure our commands are actually live in the kernel
+		 * before we die.
+		 */
+		io_uring_submit(&t->ring);
+		raise(SIGKILL);
+	}
+}
+
 static int ublk_fault_inject_queue_io(struct ublk_thread *t,
 				      struct ublk_queue *q, int tag)
 {
 	const struct ublksrv_io_desc *iod = ublk_get_iod(q, tag);
 	struct io_uring_sqe *sqe;
+	struct fi_opts *opts = q->dev->private_data;
 	struct __kernel_timespec ts = {
-		.tv_nsec = (long long)q->dev->private_data,
+		.tv_nsec = opts->delay_ns,
 	};
 
 	ublk_io_alloc_sqes(t, &sqe, 1);
@@ -77,29 +118,34 @@ static void ublk_fault_inject_cmd_line(struct dev_ctx *ctx, int argc, char *argv
 {
 	static const struct option longopts[] = {
 		{ "delay_us", 	1,	NULL,  0  },
+		{ "die_during_fetch", 1, NULL, 0  },
 		{ 0, 0, 0, 0 }
 	};
 	int option_idx, opt;
 
 	ctx->fault_inject.delay_us = 0;
+	ctx->fault_inject.die_during_fetch = false;
 	while ((opt = getopt_long(argc, argv, "",
 				  longopts, &option_idx)) != -1) {
 		switch (opt) {
 		case 0:
 			if (!strcmp(longopts[option_idx].name, "delay_us"))
 				ctx->fault_inject.delay_us = strtoll(optarg, NULL, 10);
+			if (!strcmp(longopts[option_idx].name, "die_during_fetch"))
+				ctx->fault_inject.die_during_fetch = strtoll(optarg, NULL, 10);
 		}
 	}
 }
 
 static void ublk_fault_inject_usage(const struct ublk_tgt_ops *ops)
 {
-	printf("\tfault_inject: [--delay_us us (default 0)]\n");
+	printf("\tfault_inject: [--delay_us us (default 0)] [--die_during_fetch 1]\n");
 }
 
 const struct ublk_tgt_ops fault_inject_tgt_ops = {
 	.name = "fault_inject",
 	.init_tgt = ublk_fault_inject_tgt_init,
+	.pre_fetch_io = ublk_fault_inject_pre_fetch_io,
 	.queue_io = ublk_fault_inject_queue_io,
 	.tgt_io_done = ublk_fault_inject_tgt_io_done,
 	.parse_cmd_line = ublk_fault_inject_cmd_line,
diff --git a/tools/testing/selftests/ublk/kublk.c b/tools/testing/selftests/ublk/kublk.c
index e1c3b3c55e565c8cad6b6fe9b9b764cd244818c0..e5b787ba21754719247bb17e1874313f52c35ed1 100644
--- a/tools/testing/selftests/ublk/kublk.c
+++ b/tools/testing/selftests/ublk/kublk.c
@@ -796,6 +796,8 @@ static void ublk_submit_fetch_commands(struct ublk_thread *t)
 			q = &t->dev->q[q_id];
 			io = &q->ios[tag];
 			io->buf_index = j++;
+			if (q->tgt_ops->pre_fetch_io)
+				q->tgt_ops->pre_fetch_io(t, q, tag, false);
 			ublk_queue_io_cmd(t, io);
 		}
 	} else {
@@ -807,6 +809,8 @@ static void ublk_submit_fetch_commands(struct ublk_thread *t)
 		for (i = 0; i < q->q_depth; i++) {
 			io = &q->ios[i];
 			io->buf_index = i;
+			if (q->tgt_ops->pre_fetch_io)
+				q->tgt_ops->pre_fetch_io(t, q, i, false);
 			ublk_queue_io_cmd(t, io);
 		}
 	}
@@ -983,6 +987,9 @@ static void ublk_batch_setup_queues(struct ublk_thread *t)
 		if (t->q_map[i] == 0)
 			continue;
 
+		if (q->tgt_ops->pre_fetch_io)
+			q->tgt_ops->pre_fetch_io(t, q, 0, true);
+
 		ret = ublk_batch_queue_prep_io_cmds(t, q);
 		ublk_assert(ret >= 0);
 	}
diff --git a/tools/testing/selftests/ublk/kublk.h b/tools/testing/selftests/ublk/kublk.h
index 02f0c55d006b4c791fea4456687d0d8757be7be2..6d1762aa30dfc8e72ff92aa86c8faba12169f644 100644
--- a/tools/testing/selftests/ublk/kublk.h
+++ b/tools/testing/selftests/ublk/kublk.h
@@ -60,6 +60,7 @@ struct stripe_ctx {
 struct fault_inject_ctx {
 	/* fault_inject */
 	unsigned long   delay_us;
+	bool die_during_fetch;
 };
 
 struct dev_ctx {
@@ -138,6 +139,8 @@ struct ublk_tgt_ops {
 	int (*init_tgt)(const struct dev_ctx *ctx, struct ublk_dev *);
 	void (*deinit_tgt)(struct ublk_dev *);
 
+	void (*pre_fetch_io)(struct ublk_thread *t, struct ublk_queue *q,
+			     int tag, bool batch);
 	int (*queue_io)(struct ublk_thread *, struct ublk_queue *, int tag);
 	void (*tgt_io_done)(struct ublk_thread *, struct ublk_queue *,
 			    const struct io_uring_cqe *);
diff --git a/tools/testing/selftests/ublk/test_generic_17.sh b/tools/testing/selftests/ublk/test_generic_17.sh
new file mode 100755
index 0000000000000000000000000000000000000000..2278b5fc9dba523bb1bf8411d22f4f95a28da905
--- /dev/null
+++ b/tools/testing/selftests/ublk/test_generic_17.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+. "$(cd "$(dirname "$0")" && pwd)"/test_common.sh
+
+ERR_CODE=0
+
+_prep_test "fault_inject" "teardown after incomplete recovery"
+
+# First start and stop a ublk server with device configured for recovery
+dev_id=$(_add_ublk_dev -t fault_inject -r 1)
+_check_add_dev $TID $?
+state=$(__ublk_kill_daemon "${dev_id}" "QUIESCED")
+if [ "$state" != "QUIESCED" ]; then
+        echo "device isn't quiesced($state) after $action"
+        ERR_CODE=255
+fi
+
+# Then recover the device, but use --die_during_fetch to have the ublk
+# server die while a queue has some (but not all) I/Os fetched
+${UBLK_PROG} recover -n "${dev_id}" --foreground -t fault_inject --die_during_fetch 1
+RECOVER_RES=$?
+# 137 is the result when dying of SIGKILL
+if (( RECOVER_RES != 137 )); then
+        echo "recover command exited with unexpected code ${RECOVER_RES}!"
+        ERR_CODE=255
+fi
+
+# Clean up the device. This can only succeed once teardown of the above
+# exited ublk server completes. So if teardown never completes, we will
+# time out here
+_ublk_del_dev "${dev_id}"
+
+_cleanup_test "fault_inject"
+_show_result $TID $ERR_CODE

-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH 1/2] ublk: reset per-IO canceled flag on each fetch
From: zhang @ 2026-04-06  3:37 UTC (permalink / raw)
  To: ming.lei
  Cc: axboe, csander, linux-block, linux-kernel, linux-kselftest, shuah,
	ushankar, zhangweize9
In-Reply-To: <adMlcc0EkqUNpMbu@fedora>

Hi Ming,

Thanks for your clarification. I see, as long as `->cancel_fn()` ensures forward progress, the potential repetition from userspace won't compromise the kernel stability. That makes perfect sense.

Also, thanks for pointing out the tag format. I will use my full name and email address for formal reviews in the future.

Best regards,
zhang, the-essence-of-life <zhangweize9@gmail.com>

^ permalink raw reply

* Re: [PATCH v10 13/13] docs: add io_queue flag to isolcpus
From: Ming Lei @ 2026-04-06  3:29 UTC (permalink / raw)
  To: Aaron Tomlin
  Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
	martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
	shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
	sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
	jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
	akpm, maz, ruanjinjie, bigeasy, yphbchou0911, wagi, frederic,
	longman, chenridong, hare, kch, steve, sean, chjohnst, neelx,
	mproche, linux-block, linux-kernel, virtualization, linux-nvme,
	linux-scsi, megaraidlinux.pdl, mpi3mr-linuxdrv.pdl,
	MPT-FusionLinux.pdl
In-Reply-To: <nxe24ixebb4lm2d5w4aubhtwr23df6mumqd663axj35oswdiyv@amtqhtsidyr4>

On Sun, Apr 05, 2026 at 09:15:36PM -0400, Aaron Tomlin wrote:
> On Fri, Apr 03, 2026 at 10:30:26AM +0800, Ming Lei wrote:
> > On Wed, Apr 01, 2026 at 06:23:12PM -0400, Aaron Tomlin wrote:
> > 
> > All these can be supported by `managed_irq` already, please document the thing
> > which `io_queue` solves, and `managed_irq` can't cover, so user can know
> > how to choose between the two command lines.
> > 
> > `Restrict the placement of queues to housekeeping CPUs only` looks totally
> > stale, please see patch 10, in which isolated CPUs are spread too.
> 
> Dear Ming,
> 
> Thank you for your careful review of the documentation and for raising
> these excellent points. I completely agree that the administrator guide
> must be as unambiguous as possible.
> 
> Regarding your first point on the distinction between managed_irq and
> io_queue, you are entirely correct that the documentation must explicitly
> guide the user in their choice. I shall revise the text to clarify that
> where managed_irq solely restricts the affinity of hardware interrupts at
> the interrupt controller level, io_queue governs the block layer
> multi-queue mapping algorithm itself. I will add a clear explanation that
> io_queue is required for users who utilise polling queues, which do not
> rely on interrupts, or specific drivers that do not use the managed
> interrupt infrastructure. Without io_queue, the block layer would still
> assign these polling duties to isolated CPUs, thereby breaking the
> isolation.

I don't think there is such breaking isolation thing. For iopoll, if
applications won't submit polled IO on isolated CPUs, everything is just
fine. If they do it, IO may be reaped from isolated CPUs, that is just their
choice, anything is wrong?

> 
> Every logical CPU, including the isolated ones, must logically map to a
> hardware context in order to submit input and output requests, saying they
> are completely restricted is indeed stale and technically inaccurate. The
> isolation mechanism actually ensures that the hardware contexts themselves
> are serviced by the housekeeping CPUs, while the isolated CPUs are simply
> mapped onto these housekeeping queues for submission purposes. I will
> rewrite this paragraph to accurately reflect this topology, ensuring it
> aligns perfectly with the behaviour introduced in patch 10.

I am not sure if the above words is helpful from administrator viewpoint about
the two kernel parameters.

IMO, only two differences from this viewpoint:

1) `io_queue` may reduce nr_hw_queues

2) when application submits IO from isolated CPUs, `io_queue` can complete
IO from housekeeping CPUs.

> 
> > > +
> > > +			  The io_queue configuration takes precedence
> > > +			  over managed_irq. When io_queue is used,
> > > +			  managed_irq placement constrains have no
> > > +			  effect.
> > > +
> > > +			  Note: Offlining housekeeping CPUS which serve
> > > +			  isolated CPUs will be rejected. Isolated CPUs
> > > +			  need to be offlined before offlining the
> > > +			  housekeeping CPUs.
> > > +
> > > +			  Note: When an isolated CPU issues an I/O request,
> > > +			  it is forwarded to a housekeeping CPU. This will
> > > +			  trigger a software interrupt on the completion
> > > +			  path.
> > 
> > `io_queue` doesn't touch io completion code path, which is more
> > implementation details, so not sure if the above Note is needed.
> 
> Possibly the original author intended to suggest that the software
> interrupt is sent to the isolated CPU?

I meant this point can't be found in the patches.


Thanks, 
Ming


^ permalink raw reply

* Re: [PATCH 1/2] ublk: reset per-IO canceled flag on each fetch
From: Ming Lei @ 2026-04-06  3:16 UTC (permalink / raw)
  To: zhang
  Cc: axboe, csander, linux-block, linux-kernel, linux-kselftest, shuah,
	ushankar
In-Reply-To: <46c04059-03a0-4488-a4a5-4bb93aa46a1e@gmail.com>

On Sun, Apr 05, 2026 at 09:02:30AM +0800, zhang wrote:
> Dear Ming Lei:
> 
> I just looked at your solution, which is to reset immediately after each IO is claimed. This solution can indeed effectively solve the blocking problem. However, if there is a task that is repeated and exactly the same, then the process may run repeatedly many times. Do you think we should add some logic to handle repeated tasks?
> 

->cancel_fn() can provide the forward progress, so it shouldn't be one
problem. If the userspace wants to repeat this action, let it do it, and
kernel won't hang with Uday's fix.


> Reviewed-by: zhang, the-essence-of-life.

Usually we show the whole email address.


Thanks,
Ming


^ permalink raw reply

* Re: [PATCH v10 13/13] docs: add io_queue flag to isolcpus
From: Aaron Tomlin @ 2026-04-06  1:15 UTC (permalink / raw)
  To: Ming Lei
  Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
	martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
	shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
	sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
	jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
	akpm, maz, ruanjinjie, bigeasy, yphbchou0911, wagi, frederic,
	longman, chenridong, hare, kch, steve, sean, chjohnst, neelx,
	mproche, linux-block, linux-kernel, virtualization, linux-nvme,
	linux-scsi, megaraidlinux.pdl, mpi3mr-linuxdrv.pdl,
	MPT-FusionLinux.pdl
In-Reply-To: <ac8l-w8ERG1YN2Wm@fedora>

[-- Attachment #1: Type: text/plain, Size: 3150 bytes --]

On Fri, Apr 03, 2026 at 10:30:26AM +0800, Ming Lei wrote:
> On Wed, Apr 01, 2026 at 06:23:12PM -0400, Aaron Tomlin wrote:
> 
> All these can be supported by `managed_irq` already, please document the thing
> which `io_queue` solves, and `managed_irq` can't cover, so user can know
> how to choose between the two command lines.
> 
> `Restrict the placement of queues to housekeeping CPUs only` looks totally
> stale, please see patch 10, in which isolated CPUs are spread too.

Dear Ming,

Thank you for your careful review of the documentation and for raising
these excellent points. I completely agree that the administrator guide
must be as unambiguous as possible.

Regarding your first point on the distinction between managed_irq and
io_queue, you are entirely correct that the documentation must explicitly
guide the user in their choice. I shall revise the text to clarify that
where managed_irq solely restricts the affinity of hardware interrupts at
the interrupt controller level, io_queue governs the block layer
multi-queue mapping algorithm itself. I will add a clear explanation that
io_queue is required for users who utilise polling queues, which do not
rely on interrupts, or specific drivers that do not use the managed
interrupt infrastructure. Without io_queue, the block layer would still
assign these polling duties to isolated CPUs, thereby breaking the
isolation.

Every logical CPU, including the isolated ones, must logically map to a
hardware context in order to submit input and output requests, saying they
are completely restricted is indeed stale and technically inaccurate. The
isolation mechanism actually ensures that the hardware contexts themselves
are serviced by the housekeeping CPUs, while the isolated CPUs are simply
mapped onto these housekeeping queues for submission purposes. I will
rewrite this paragraph to accurately reflect this topology, ensuring it
aligns perfectly with the behaviour introduced in patch 10.

> > +
> > +			  The io_queue configuration takes precedence
> > +			  over managed_irq. When io_queue is used,
> > +			  managed_irq placement constrains have no
> > +			  effect.
> > +
> > +			  Note: Offlining housekeeping CPUS which serve
> > +			  isolated CPUs will be rejected. Isolated CPUs
> > +			  need to be offlined before offlining the
> > +			  housekeeping CPUs.
> > +
> > +			  Note: When an isolated CPU issues an I/O request,
> > +			  it is forwarded to a housekeeping CPU. This will
> > +			  trigger a software interrupt on the completion
> > +			  path.
> 
> `io_queue` doesn't touch io completion code path, which is more
> implementation details, so not sure if the above Note is needed.

Possibly the original author intended to suggest that the software
interrupt is sent to the isolated CPU?

To achieve absolute zero disturbance, an isolated CPU must either entirely
abstain from submitting standard I/O, or it must exclusively utilise
polling queues, where the CPU actively checks for completions and entirely
bypasses the interrupt and softirq mechanisms.


Kind regards,
-- 
Aaron Tomlin

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v2 07/33] rust: allow globally `clippy::incompatible_msrv`
From: Gary Guo @ 2026-04-06  0:18 UTC (permalink / raw)
  To: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Trevor Gross, rust-for-linux, linux-kbuild, Lorenzo Stoakes,
	Vlastimil Babka, Liam R . Howlett, Uladzislau Rezki, linux-block,
	moderated for non-subscribers, Alexandre Ghiti, linux-riscv,
	nouveau, dri-devel, Rae Moar, linux-kselftest, kunit-dev,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm, linux-kernel,
	Shuah Khan, linux-doc
In-Reply-To: <20260405235309.418950-8-ojeda@kernel.org>

On Mon Apr 6, 2026 at 12:52 AM BST, Miguel Ojeda wrote:
> `clippy::incompatible_msrv` is not buying us much, and we discussed
> allowing it several times in the past.
> 
> For instance, there was recently another patch sent to `allow` it where
> needed [1]. While that particular case would not be needed after the
> minimum version bump to 1.85.0, it is simpler to just allow it to prevent
> future instances.
> 
> Thus do so, and remove the last instance of locally allowing it we have
> in the tree (except the one in the vendored `proc_macro2` crate).
> 
> Note that we still keep the `msrv` config option in `clippy.toml` since
> that affects other lints as well.
> 
> Link: https://lore.kernel.org/rust-for-linux/20260404212831.78971-4-jhubbard@nvidia.com/ [1]
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

Reviewed-by: Gary Guo <gary@garyguo.net>

> ---
>  Makefile               | 1 +
>  rust/macros/helpers.rs | 1 -
>  2 files changed, 1 insertion(+), 1 deletion(-)


^ permalink raw reply

* Re: [PATCH v2 01/33] rust: kbuild: remove `--remap-path-prefix` workarounds
From: Gary Guo @ 2026-04-06  0:18 UTC (permalink / raw)
  To: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Trevor Gross, rust-for-linux, linux-kbuild, Lorenzo Stoakes,
	Vlastimil Babka, Liam R . Howlett, Uladzislau Rezki, linux-block,
	moderated for non-subscribers, Alexandre Ghiti, linux-riscv,
	nouveau, dri-devel, Rae Moar, linux-kselftest, kunit-dev,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm, linux-kernel,
	Shuah Khan, linux-doc
In-Reply-To: <20260405235309.418950-2-ojeda@kernel.org>

On Mon Apr 6, 2026 at 12:52 AM BST, Miguel Ojeda wrote:
> Commit 8cf5b3f83614 ("Revert "kbuild, rust: use -fremap-path-prefix
> to make paths relative"") removed `--remap-path-prefix` from the build
> system, so the workarounds are not needed anymore.
> 
> Thus remove them.
> 
> Note that the flag has landed again in parallel in this cycle in
> commit dda135077ecc ("rust: build: remap path to avoid absolute path"),
> together with `--remap-path-scope=macro` [1]. However, they are gated on
> `rustc-option-yn, --remap-path-scope=macro`, which means they are both
> only passed starting with Rust 1.95.0 [2]:
> 
>   `--remap-path-scope` is only stable in Rust 1.95, so use `rustc-option`
>   to detect its presence. This feature has been available as
>   `-Zremap-path-scope` for all versions that we support; however due to
>   bugs in the Rust compiler, it does not work reliably until 1.94. I opted
>   to not enable it for 1.94 as it's just a single version that we missed.
> 
> In turn, that means the workarounds removed here should not be needed
> again (even with the flag added again above), since:
> 
>   - `rustdoc` now recognizes the `--remap-path-prefix` flag since Rust
>     1.81.0 [3] (even if it is still an unstable feature [4]).
> 
>   - The Internal Compiler Error [5] that the comment mentions was fixed in
>     Rust 1.87.0 [6]. We tested that was the case in a previous version
>     of this series by making the workaround conditional [7][8].
> 
> ...which are both older versions than Rust 1.95.0.
> 
> We will still need to skip `--remap-path-scope` for `rustdoc` though,
> since `rustdoc` does not support that one yet [4].
> 
> Link: https://github.com/rust-lang/rust/issues/111540 [1]
> Link: https://github.com/rust-lang/rust/pull/147611 [2]
> Link: https://github.com/rust-lang/rust/pull/107099 [3]
> Link: https://doc.rust-lang.org/nightly/rustdoc/unstable-features.html#--remap-path-prefix-remap-source-code-paths-in-output [4]
> Link: https://github.com/rust-lang/rust/issues/138520 [5]
> Link: https://github.com/rust-lang/rust/pull/138556 [6]
> Link: https://lore.kernel.org/rust-for-linux/20260401114540.30108-9-ojeda@kernel.org/ [7]
> Link: https://lore.kernel.org/rust-for-linux/20260401114540.30108-10-ojeda@kernel.org/ [8]
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

Acked-by: Gary Guo <gary@garyguo.net>

> ---
>  rust/Makefile | 8 ++------
>  1 file changed, 2 insertions(+), 6 deletions(-)


^ permalink raw reply

* Re: [PATCH 23/33] docs: rust: quick-start: update Ubuntu versioned packages
From: Miguel Ojeda @ 2026-04-06  0:14 UTC (permalink / raw)
  To: Gary Guo, Fiona Behrens
  Cc: Tamir Duberstein, Miguel Ojeda, Nathan Chancellor, Nicolas Schier,
	Danilo Krummrich, Andreas Hindborg, Catalin Marinas, Will Deacon,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Courbot,
	David Airlie, Simona Vetter, Brendan Higgins, David Gow,
	Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
	Christian Brauner, Carlos Llamas, Alice Ryhl, Jonathan Corbet,
	Boqun Feng, Björn Roy Baron, Benno Lossin, Trevor Gross,
	rust-for-linux, linux-kbuild, Lorenzo Stoakes, Vlastimil Babka,
	Liam R . Howlett, Uladzislau Rezki, linux-block, linux-arm-kernel,
	Alexandre Ghiti, linux-riscv, nouveau, dri-devel, Rae Moar,
	linux-kselftest, kunit-dev, Nick Desaulniers, Bill Wendling,
	Justin Stitt, llvm, linux-kernel, Shuah Khan, linux-doc
In-Reply-To: <DHLMTLCY6U4N.3VOMQXRIT1RFY@garyguo.net>

On Mon, Apr 6, 2026 at 2:06 AM Gary Guo <gary@garyguo.net> wrote:
>
> It's still required.

Thanks for confirming!

> Perhaps having a repo in rust-for-linux GitHub org (or somewhere else in
> kernel.org SCM) where we can point people to?

...and for all these details :)

I agree that it doesn't fit perfectly within the kernel, but an update
every kernel cycle or so should be fine, I think, if you think that is
enough.

Otherwise, regarding the repository, that sounds great to me -- we
already had an old https://github.com/Rust-for-Linux/nix and
https://github.com/Rust-for-Linux/nixpkgs. Not sure if Fiona (Cc'd)
wants them, but perhaps you could reuse them (otherwise we should
archive them).

Cheers,
Miguel

^ permalink raw reply

* Re: [PATCH 32/33] rust: kbuild: support global per-version flags
From: Gary Guo @ 2026-04-06  0:09 UTC (permalink / raw)
  To: Miguel Ojeda, Gary Guo, Nathan Chancellor, Nicolas Schier
  Cc: Miguel Ojeda, Danilo Krummrich, Andreas Hindborg, Catalin Marinas,
	Will Deacon, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Courbot, David Airlie, Simona Vetter, Brendan Higgins,
	David Gow, Greg Kroah-Hartman, Arve Hjønnevåg,
	Todd Kjos, Christian Brauner, Carlos Llamas, Alice Ryhl,
	Jonathan Corbet, Boqun Feng, Björn Roy Baron, Benno Lossin,
	Trevor Gross, rust-for-linux, linux-kbuild, Lorenzo Stoakes,
	Vlastimil Babka, Liam R . Howlett, Uladzislau Rezki, linux-block,
	moderated for non-subscribers, Alexandre Ghiti, linux-riscv,
	nouveau, dri-devel, Rae Moar, linux-kselftest, kunit-dev,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm, linux-kernel,
	Shuah Khan, linux-doc
In-Reply-To: <CANiq72mTaA2tjhkLKf0-2hrrrt9rxWPgy6SfNSbponbGOegQvA@mail.gmail.com>

On Mon Apr 6, 2026 at 12:15 AM BST, Miguel Ojeda wrote:
> On Thu, Apr 2, 2026 at 12:28 AM Gary Guo <gary@garyguo.net> wrote:
>>
>> I think I would prefer moving these down.
>>
>> The current approach append the flags to all variables, which will cause the
>> following equivalence to stop holding after the flag update.
>>
>> KBUILD_HOSTRUSTFLAGS := $(rust_common_flags) -O -Cstrip=debuginfo \
>>                         -Zallow-features= $(HOSTRUSTFLAGS)
>>
>> (Per version flags doesn't go before -O anymore, it comes after HOSTRUSTFLAGS).
>
> [ For context for others, Sashiko reported the same and we also talked
> about it in a Rust for Linux call. ]
>
> I have been thinking about this, and about potential other ways to
> achieve the same thing. I think the best at the moment is to move just
> the `$(HOSTRUSTFLAGS)` below, but not the rest.
>
> The reason is that it is closer to what we do with other user (kernel)
> flags (e.g. arch flags come after the general ones). But I am
> wondering if we should/could set all the user variables later in the
> `Makefile` in general `HOST*FLAGS` later in the `Makefile`.
>
> In fact, there is already a limitation with the host flags: `-Werror`,
> i.e. that one gets appended later, and so users cannot override it.

I cared a bit more about the code clarity (where appending to all variables
feel like a hack, while moving the code block is natural).

Best,
Gary

> [...]
>
> Anyway, for now I moved the expansion of `HOSTRUSTFLAGS` in v2. If
> Kbuild (Nathan, Nicolas) think it is a good idea to do one of the
> bigger changes (e.g. for more `HOST*` flags, appending it even later),
> then we can do it afterwards.
>
> Cheers,
> Miguel


^ permalink raw reply

* Re: [PATCH 23/33] docs: rust: quick-start: update Ubuntu versioned packages
From: Gary Guo @ 2026-04-06  0:06 UTC (permalink / raw)
  To: Miguel Ojeda, Tamir Duberstein
  Cc: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Trevor Gross, rust-for-linux,
	linux-kbuild, Lorenzo Stoakes, Vlastimil Babka, Liam R . Howlett,
	Uladzislau Rezki, linux-block, linux-arm-kernel, Alexandre Ghiti,
	linux-riscv, nouveau, dri-devel, Rae Moar, linux-kselftest,
	kunit-dev, Nick Desaulniers, Bill Wendling, Justin Stitt, llvm,
	linux-kernel, Shuah Khan, linux-doc
In-Reply-To: <CANiq72nqenC30r7QQAmdKxS8ehGU2SoSGr+LCnoTAGLegH-KnA@mail.gmail.com>

On Sun Apr 5, 2026 at 8:35 PM BST, Miguel Ojeda wrote:
> On Thu, Apr 2, 2026 at 1:01 AM Tamir Duberstein <tamird@kernel.org> wrote:
>>
>> RUST_LIB_SRC is also mentioned in the nix section, do you know if it is
>> still needed there?
>
> Yeah, that would be nice to know.

It's still required. It's used here:
https://github.com/NixOS/nixpkgs/blob/acf7ae578589bb8bdd6f9273141d7053fed84bed/pkgs/os-specific/linux/kernel/generic.nix#L186

>
> I tried on my own, and it does seem still required (at least with
> those packages mentioned in the example). But perhaps a Nix user knows
> of a better way to do it, anyway.
>
> So I kept it.
>
> By the way, I think it would be nice to have a "standard",
> well-maintained `shell.nix` (or a flake or whatever is best nowadays)
> in the kernel tree somewhere, i.e. one that is known to work, that
> covers most tooling used in the kernel, etc.
>
> Cheers,
> Miguel

I have my dev shell here in case it helps:
https://github.com/nbdd0121/nix-collection/blob/trunk/dev/linux.nix

It makes use of oxalica's rust-overlay. It can be used with shell.nix by a
fetchTarball, but for obvious reasons you want that to be pinned and not be
fetching latest version everytime.

Flake is good for pinning, but using flake is a two-edged sword -- it both gives
you superb reproducibility so years down the line you can still build an old
environment (assuming the source tarballs used are still available or NixOS
cache server still has a copy).

But it also means that it can be outdated. So people (myself included) usually
combine pinning + regular updating by having flake.lock routinely updated.
I'm not sure that really fits well inside kernel.

If we don't use anything outside nixpkgs though, we can use "channel" feature of
imperative nix which says `import <nixpkgs>` will import user's local nixpkgs
version. A shell.nix using only that should work, but it will only be able to
use latest rustc/clippy/cargo/bindgen in nixpkgs and won't be able to include
things like klint.

Perhaps having a repo in rust-for-linux GitHub org (or somewhere else in
kernel.org SCM) where we can point people to?

Best,
Gary

^ permalink raw reply

* [PATCH v2 33/33] rust: kbuild: allow `clippy::precedence` for Rust < 1.86.0
From: Miguel Ojeda @ 2026-04-05 23:53 UTC (permalink / raw)
  To: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Trevor Gross, rust-for-linux, linux-kbuild, Lorenzo Stoakes,
	Vlastimil Babka, Liam R . Howlett, Uladzislau Rezki, linux-block,
	moderated for non-subscribers, Alexandre Ghiti, linux-riscv,
	nouveau, dri-devel, Rae Moar, linux-kselftest, kunit-dev,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm, linux-kernel,
	Shuah Khan, linux-doc, Tamir Duberstein
In-Reply-To: <20260405235309.418950-1-ojeda@kernel.org>

The Clippy `precedence` lint was extended in Rust 1.85.0 to include
bitmasking and shift operations [1]. However, because it generated
many hits, in Rust 1.86.0 it was split into a new `precedence_bits`
lint which is not enabled by default [2].

In other words, only Rust 1.85 has a different behavior. For instance,
it reports:

    warning: operator precedence can trip the unwary
      --> drivers/gpu/nova-core/fb/hal/ga100.rs:16:5
       |
    16 | /     u64::from(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR::read(bar).adr_39_08()) << FLUSH_SYSMEM_ADDR_SHIFT
    17 | |         | u64::from(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI::read(bar).adr_63_40())
    18 | |             << FLUSH_SYSMEM_ADDR_SHIFT_HI
       | |_________________________________________^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#precedence
       = note: `-W clippy::precedence` implied by `-W clippy::all`
       = help: to override `-W clippy::all` add `#[allow(clippy::precedence)]`
    help: consider parenthesizing your expression
       |
    16 ~     (u64::from(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR::read(bar).adr_39_08()) << FLUSH_SYSMEM_ADDR_SHIFT) | (u64::from(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI::read(bar).adr_63_40())
    17 +             << FLUSH_SYSMEM_ADDR_SHIFT_HI)
       |

While so far we try our best to keep all versions Clippy-clean, the
minimum (which is now Rust 1.85.0 after the bump) and the latest stable
are the most important ones; and this may be considered a "false positive"
with respect to the behavior in other versions.

Thus allow this lint for this version using the per-version flags
mechanism introduced in the previous commit.

Link: https://github.com/rust-lang/rust-clippy/issues/14097 [1]
Link: https://github.com/rust-lang/rust-clippy/pull/14115 [2]
Link: https://lore.kernel.org/rust-for-linux/DFVDKMMA7KPC.2DN0951H3H55Y@kernel.org/
Reviewed-by: Tamir Duberstein <tamird@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index a305ae4be522..b8c38aa49cf4 100644
--- a/Makefile
+++ b/Makefile
@@ -838,7 +838,8 @@ export WARN_ON_UNUSED_TRACEPOINTS
 
 # Per-version Rust flags. These are like `rust_common_flags`, but may
 # depend on the Rust compiler version (e.g. using `rustc-min-version`).
-rust_common_flags_per_version :=
+rust_common_flags_per_version := \
+    $(if $(call rustc-min-version,108600),,-Aclippy::precedence)
 
 rust_common_flags += $(rust_common_flags_per_version)
 KBUILD_HOSTRUSTFLAGS += $(rust_common_flags_per_version) $(HOSTRUSTFLAGS)
-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 32/33] rust: kbuild: support global per-version flags
From: Miguel Ojeda @ 2026-04-05 23:53 UTC (permalink / raw)
  To: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Trevor Gross, rust-for-linux, linux-kbuild, Lorenzo Stoakes,
	Vlastimil Babka, Liam R . Howlett, Uladzislau Rezki, linux-block,
	moderated for non-subscribers, Alexandre Ghiti, linux-riscv,
	nouveau, dri-devel, Rae Moar, linux-kselftest, kunit-dev,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm, linux-kernel,
	Shuah Khan, linux-doc
In-Reply-To: <20260405235309.418950-1-ojeda@kernel.org>

Sometimes it is useful to gate global Rust flags per compiler version.
For instance, we may want to disable a lint that has false positives in
a single version [1].

We already had helpers like `rustc-min-version` for that, which we use
elsewhere, but we cannot currently use them for `rust_common_flags`,
which contains the global flags for all Rust code (kernel and host),
because `rustc-min-version` depends on `CONFIG_RUSTC_VERSION`, which
does not exist when `rust_common_flags` is defined.

Thus, to support that, introduce `rust_common_flags_per_version`,
defined after the `include/config/auto.conf` inclusion (where
`CONFIG_RUSTC_VERSION` becomes available), and append it to
`rust_common_flags`, `KBUILD_HOSTRUSTFLAGS` and `KBUILD_RUSTFLAGS`.

In addition, move the expansion of `HOSTRUSTFLAGS` to the same place,
so that users can also override per-version flags [2].

Link: https://lore.kernel.org/rust-for-linux/CANiq72mWdFU11GcCZRchzhy0Gi1QZShvZtyRkHV2O+WA2uTdVQ@mail.gmail.com/ [1]
Link: https://lore.kernel.org/rust-for-linux/CANiq72mTaA2tjhkLKf0-2hrrrt9rxWPgy6SfNSbponbGOegQvA@mail.gmail.com/ [2]
Link: https://patch.msgid.link/20260307170929.153892-1-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 Makefile | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 78f5ee173eda..a305ae4be522 100644
--- a/Makefile
+++ b/Makefile
@@ -506,7 +506,7 @@ KBUILD_HOSTCFLAGS   := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \
 KBUILD_HOSTCXXFLAGS := -Wall -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS) \
 		       -I $(srctree)/scripts/include
 KBUILD_HOSTRUSTFLAGS := $(rust_common_flags) -O -Cstrip=debuginfo \
-			-Zallow-features= $(HOSTRUSTFLAGS)
+			-Zallow-features=
 KBUILD_HOSTLDFLAGS  := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS)
 KBUILD_HOSTLDLIBS   := $(HOST_LFS_LIBS) $(HOSTLDLIBS)
 KBUILD_PROCMACROLDFLAGS := $(or $(PROCMACROLDFLAGS),$(KBUILD_HOSTLDFLAGS))
@@ -836,6 +836,14 @@ endif # CONFIG_TRACEPOINTS
 
 export WARN_ON_UNUSED_TRACEPOINTS
 
+# Per-version Rust flags. These are like `rust_common_flags`, but may
+# depend on the Rust compiler version (e.g. using `rustc-min-version`).
+rust_common_flags_per_version :=
+
+rust_common_flags += $(rust_common_flags_per_version)
+KBUILD_HOSTRUSTFLAGS += $(rust_common_flags_per_version) $(HOSTRUSTFLAGS)
+KBUILD_RUSTFLAGS += $(rust_common_flags_per_version)
+
 include $(srctree)/arch/$(SRCARCH)/Makefile
 
 ifdef need-config
-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 31/33] rust: declare cfi_encoding for lru_status
From: Miguel Ojeda @ 2026-04-05 23:53 UTC (permalink / raw)
  To: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Trevor Gross, rust-for-linux, linux-kbuild, Lorenzo Stoakes,
	Vlastimil Babka, Liam R . Howlett, Uladzislau Rezki, linux-block,
	moderated for non-subscribers, Alexandre Ghiti, linux-riscv,
	nouveau, dri-devel, Rae Moar, linux-kselftest, kunit-dev,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm, linux-kernel,
	Shuah Khan, linux-doc
In-Reply-To: <20260405235309.418950-1-ojeda@kernel.org>

From: Alice Ryhl <aliceryhl@google.com>

By default bindgen will convert 'enum lru_status' into a typedef for an
integer. For the most part, an integer of the same size as the enum
results in the correct ABI, but in the specific case of CFI, that is not
the case. The CFI encoding is supposed to be the same as a struct called
'lru_status' rather than the name of the underlying native integer type.

To fix this, tell bindgen to generate a newtype and set the CFI type
explicitly. Note that we need to set the CFI attribute explicitly as
bindgen is using repr(transparent), which is otherwise identical to the
inner type for ABI purposes.

This allows us to remove the page range helper C function in Binder
without risking a CFI failure when list_lru_walk calls the provided
function pointer.

The --with-attribute-custom-enum argument requires bindgen v0.71 or
greater.

[ In particular, the feature was added in 0.71.0 [1][2].

  In addition, `feature(cfi_encoding)` has been available since
  Rust 1.71.0 [3].

  Link: https://github.com/rust-lang/rust-bindgen/issues/2520 [1]
  Link: https://github.com/rust-lang/rust-bindgen/pull/2866 [2]
  Link: https://github.com/rust-lang/rust/pull/105452 [3]

    - Miguel ]

My testing procedure was to add this to the android17-6.18 branch and
verify that rust_shrink_free_page is successfully called without crash,
and verify that it does in fact crash when the cfi_encoding is set to
other values. Note that I couldn't test this on android16-6.12 as that
branch uses a bindgen version that is too old.

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260223-cfi-lru-status-v2-1-89c6448a63a4@google.com
Reviewed-by: Gary Guo <gary@garyguo.net>
[ Rebased on top of the minimum Rust version bump series which provide
  the required `bindgen` version. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 drivers/android/binder/Makefile            |  3 +--
 drivers/android/binder/page_range.rs       |  6 +++---
 drivers/android/binder/page_range_helper.c | 24 ----------------------
 drivers/android/binder/page_range_helper.h | 15 --------------
 rust/bindgen_parameters                    |  4 ++++
 rust/bindings/bindings_helper.h            |  1 -
 rust/bindings/lib.rs                       |  1 +
 rust/uapi/lib.rs                           |  1 +
 8 files changed, 10 insertions(+), 45 deletions(-)
 delete mode 100644 drivers/android/binder/page_range_helper.c
 delete mode 100644 drivers/android/binder/page_range_helper.h

diff --git a/drivers/android/binder/Makefile b/drivers/android/binder/Makefile
index 09eabb527fa0..7e0cd9782a8b 100644
--- a/drivers/android/binder/Makefile
+++ b/drivers/android/binder/Makefile
@@ -5,5 +5,4 @@ obj-$(CONFIG_ANDROID_BINDER_IPC_RUST) += rust_binder.o
 rust_binder-y := \
 	rust_binder_main.o	\
 	rust_binderfs.o		\
-	rust_binder_events.o	\
-	page_range_helper.o
+	rust_binder_events.o
diff --git a/drivers/android/binder/page_range.rs b/drivers/android/binder/page_range.rs
index fdd97112ef5c..8e9f5c4819d0 100644
--- a/drivers/android/binder/page_range.rs
+++ b/drivers/android/binder/page_range.rs
@@ -642,15 +642,15 @@ fn drop(self: Pin<&mut Self>) {
     unsafe {
         bindings::list_lru_walk(
             list_lru,
-            Some(bindings::rust_shrink_free_page_wrap),
+            Some(rust_shrink_free_page),
             ptr::null_mut(),
             nr_to_scan,
         )
     }
 }
 
-const LRU_SKIP: bindings::lru_status = bindings::lru_status_LRU_SKIP;
-const LRU_REMOVED_ENTRY: bindings::lru_status = bindings::lru_status_LRU_REMOVED_RETRY;
+const LRU_SKIP: bindings::lru_status = bindings::lru_status::LRU_SKIP;
+const LRU_REMOVED_ENTRY: bindings::lru_status = bindings::lru_status::LRU_REMOVED_RETRY;
 
 /// # Safety
 /// Called by the shrinker.
diff --git a/drivers/android/binder/page_range_helper.c b/drivers/android/binder/page_range_helper.c
deleted file mode 100644
index 496887723ee0..000000000000
--- a/drivers/android/binder/page_range_helper.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/* C helper for page_range.rs to work around a CFI violation.
- *
- * Bindgen currently pretends that `enum lru_status` is the same as an integer.
- * This assumption is fine ABI-wise, but once you add CFI to the mix, it
- * triggers a CFI violation because `enum lru_status` gets a different CFI tag.
- *
- * This file contains a workaround until bindgen can be fixed.
- *
- * Copyright (C) 2025 Google LLC.
- */
-#include "page_range_helper.h"
-
-unsigned int rust_shrink_free_page(struct list_head *item,
-				   struct list_lru_one *list,
-				   void *cb_arg);
-
-enum lru_status
-rust_shrink_free_page_wrap(struct list_head *item, struct list_lru_one *list,
-			   void *cb_arg)
-{
-	return rust_shrink_free_page(item, list, cb_arg);
-}
diff --git a/drivers/android/binder/page_range_helper.h b/drivers/android/binder/page_range_helper.h
deleted file mode 100644
index 18dd2dd117b2..000000000000
--- a/drivers/android/binder/page_range_helper.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2025 Google, Inc.
- */
-
-#ifndef _LINUX_PAGE_RANGE_HELPER_H
-#define _LINUX_PAGE_RANGE_HELPER_H
-
-#include <linux/list_lru.h>
-
-enum lru_status
-rust_shrink_free_page_wrap(struct list_head *item, struct list_lru_one *list,
-			   void *cb_arg);
-
-#endif /* _LINUX_PAGE_RANGE_HELPER_H */
diff --git a/rust/bindgen_parameters b/rust/bindgen_parameters
index 112ec197ef0a..6f02d9720ad2 100644
--- a/rust/bindgen_parameters
+++ b/rust/bindgen_parameters
@@ -19,6 +19,10 @@
 # warning. We don't need to peek into it anyway.
 --opaque-type spinlock
 
+# enums that appear in indirect function calls should specify a cfi type
+--newtype-enum lru_status
+--with-attribute-custom-enum=lru_status='#[cfi_encoding="10lru_status"]'
+
 # `seccomp`'s comment gets understood as a doctest
 --no-doc-comments
 
diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index 083cc44aa952..faf3ee634ced 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -149,5 +149,4 @@ const vm_flags_t RUST_CONST_HELPER_VM_NOHUGEPAGE = VM_NOHUGEPAGE;
 #if IS_ENABLED(CONFIG_ANDROID_BINDER_IPC_RUST)
 #include "../../drivers/android/binder/rust_binder.h"
 #include "../../drivers/android/binder/rust_binder_events.h"
-#include "../../drivers/android/binder/page_range_helper.h"
 #endif
diff --git a/rust/bindings/lib.rs b/rust/bindings/lib.rs
index e18c160dad17..854e7c471434 100644
--- a/rust/bindings/lib.rs
+++ b/rust/bindings/lib.rs
@@ -19,6 +19,7 @@
     unreachable_pub,
     unsafe_op_in_unsafe_fn
 )]
+#![feature(cfi_encoding)]
 
 #[allow(dead_code)]
 #[allow(clippy::cast_lossless)]
diff --git a/rust/uapi/lib.rs b/rust/uapi/lib.rs
index 821e286e0daa..b8a515de31ca 100644
--- a/rust/uapi/lib.rs
+++ b/rust/uapi/lib.rs
@@ -24,6 +24,7 @@
     unsafe_op_in_unsafe_fn
 )]
 #![cfg_attr(CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES, allow(unnecessary_transmutes))]
+#![feature(cfi_encoding)]
 
 // Manual definition of blocklisted types.
 type __kernel_size_t = usize;
-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 30/33] docs: rust: general-information: use real example
From: Miguel Ojeda @ 2026-04-05 23:53 UTC (permalink / raw)
  To: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Trevor Gross, rust-for-linux, linux-kbuild, Lorenzo Stoakes,
	Vlastimil Babka, Liam R . Howlett, Uladzislau Rezki, linux-block,
	moderated for non-subscribers, Alexandre Ghiti, linux-riscv,
	nouveau, dri-devel, Rae Moar, linux-kselftest, kunit-dev,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm, linux-kernel,
	Shuah Khan, linux-doc, Tamir Duberstein
In-Reply-To: <20260405235309.418950-1-ojeda@kernel.org>

Currently the example in the documentation shows a version-based name
for the Kconfig example:

    RUSTC_VERSION_MIN_107900

The reason behind it was to possibly avoid repetition in case several
features used the same minimum.

However, we ended up preferring to give them a descriptive name for each
feature added even if that could lead to some repetition. In practice,
the repetition has not happened so far, and even if it does at some point,
it is not a big deal.

Thus replace the example in the documentation with one of our current
examples (after removing previous ones from the bump), to show how they
actually look like, and in case someone `grep`s for it.

In addition, it has the advantage that it shows the `RUSTC_HAS_*`
pattern we follow in `init/Kconfig`, similar to the C side.

Reviewed-by: Tamir Duberstein <tamird@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 Documentation/rust/general-information.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/rust/general-information.rst b/Documentation/rust/general-information.rst
index 91535b2306ed..09234bed272c 100644
--- a/Documentation/rust/general-information.rst
+++ b/Documentation/rust/general-information.rst
@@ -157,5 +157,5 @@ numerical comparisons, one may define a new Kconfig symbol:
 
 .. code-block:: kconfig
 
-	config RUSTC_VERSION_MIN_107900
-		def_bool RUSTC_VERSION >= 107900
+	config RUSTC_HAS_SPAN_FILE
+		def_bool RUSTC_VERSION >= 108800
-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 29/33] docs: rust: general-information: simplify Kconfig example
From: Miguel Ojeda @ 2026-04-05 23:53 UTC (permalink / raw)
  To: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Trevor Gross, rust-for-linux, linux-kbuild, Lorenzo Stoakes,
	Vlastimil Babka, Liam R . Howlett, Uladzislau Rezki, linux-block,
	moderated for non-subscribers, Alexandre Ghiti, linux-riscv,
	nouveau, dri-devel, Rae Moar, linux-kselftest, kunit-dev,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm, linux-kernel,
	Shuah Khan, linux-doc, Tamir Duberstein
In-Reply-To: <20260405235309.418950-1-ojeda@kernel.org>

There is no need to use `def_bool y if <expr>` -- one can simply write
`def_bool <expr>`.

In fact, the simpler form is how we actually use them in practice in
`init/Kconfig`.

Thus simplify the example.

Reviewed-by: Tamir Duberstein <tamird@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 Documentation/rust/general-information.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/rust/general-information.rst b/Documentation/rust/general-information.rst
index 6146b49b6a98..91535b2306ed 100644
--- a/Documentation/rust/general-information.rst
+++ b/Documentation/rust/general-information.rst
@@ -158,4 +158,4 @@ numerical comparisons, one may define a new Kconfig symbol:
 .. code-block:: kconfig
 
 	config RUSTC_VERSION_MIN_107900
-		def_bool y if RUSTC_VERSION >= 107900
+		def_bool RUSTC_VERSION >= 107900
-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 28/33] docs: rust: quick-start: remove GDB/Binutils mention
From: Miguel Ojeda @ 2026-04-05 23:53 UTC (permalink / raw)
  To: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Trevor Gross, rust-for-linux, linux-kbuild, Lorenzo Stoakes,
	Vlastimil Babka, Liam R . Howlett, Uladzislau Rezki, linux-block,
	moderated for non-subscribers, Alexandre Ghiti, linux-riscv,
	nouveau, dri-devel, Rae Moar, linux-kselftest, kunit-dev,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm, linux-kernel,
	Shuah Khan, linux-doc, Tamir Duberstein
In-Reply-To: <20260405235309.418950-1-ojeda@kernel.org>

The versions provided nowadays by even a distribution like Debian Stable
(and Debian Old Stable) are newer than those mentioned [1].

Thus remove the workaround.

Note that the minimum binutils version in the kernel is still 2.30, so
one could argue part of the note is still relevant, but it is unlikely
a kernel developer using such an old binutils is enabling Rust on a
modern kernel, especially when using distribution toolchains, e.g. the
Rust minimum version is not satisfied by Debian Old Stable.

So we are at the point where keeping the docs short and relevant for
essentially everyone is probably the better trade-off.

Link: https://packages.debian.org/search?suite=all&searchon=names&keywords=binutils [1]
Link: https://lore.kernel.org/all/CANiq72mCpc9=2TN_zC4NeDMpFQtPXAFvyiP+gRApg2vzspPWmw@mail.gmail.com/
Reviewed-by: Tamir Duberstein <tamird@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 Documentation/rust/quick-start.rst | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/Documentation/rust/quick-start.rst b/Documentation/rust/quick-start.rst
index 5bbe059a8fa3..a6ec3fa94d33 100644
--- a/Documentation/rust/quick-start.rst
+++ b/Documentation/rust/quick-start.rst
@@ -352,12 +352,3 @@ Hacking
 To dive deeper, take a look at the source code of the samples
 at ``samples/rust/``, the Rust support code under ``rust/`` and
 the ``Rust hacking`` menu under ``Kernel hacking``.
-
-If GDB/Binutils is used and Rust symbols are not getting demangled, the reason
-is the toolchain does not support Rust's new v0 mangling scheme yet.
-There are a few ways out:
-
-- Install a newer release (GDB >= 10.2, Binutils >= 2.36).
-
-- Some versions of GDB (e.g. vanilla GDB 10.1) are able to use
-  the pre-demangled names embedded in the debug info (``CONFIG_DEBUG_INFO``).
-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 27/33] docs: rust: quick-start: remove Nix "unstable channel" note
From: Miguel Ojeda @ 2026-04-05 23:53 UTC (permalink / raw)
  To: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Trevor Gross, rust-for-linux, linux-kbuild, Lorenzo Stoakes,
	Vlastimil Babka, Liam R . Howlett, Uladzislau Rezki, linux-block,
	moderated for non-subscribers, Alexandre Ghiti, linux-riscv,
	nouveau, dri-devel, Rae Moar, linux-kselftest, kunit-dev,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm, linux-kernel,
	Shuah Khan, linux-doc, Tamir Duberstein
In-Reply-To: <20260405235309.418950-1-ojeda@kernel.org>

Nix does not need the "unstable channel" note, since its packages are
recent enough even in the stable channel [1][2].

Thus remove it to simplify the documentation.

Link: https://search.nixos.org/packages?channel=25.11&query=rust [1]
Link: https://search.nixos.org/packages?channel=25.11&query=bindgen [2]
Reviewed-by: Tamir Duberstein <tamird@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 Documentation/rust/quick-start.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/rust/quick-start.rst b/Documentation/rust/quick-start.rst
index 1518367324fe..5bbe059a8fa3 100644
--- a/Documentation/rust/quick-start.rst
+++ b/Documentation/rust/quick-start.rst
@@ -68,8 +68,8 @@ of the box, e.g.::
 Nix
 ***
 
-Nix (unstable channel) provides recent Rust releases and thus it should
-generally work out of the box, e.g.::
+Nix provides recent Rust releases and thus it should generally work out of the
+box, e.g.::
 
 	{ pkgs ? import <nixpkgs> {} }:
 	pkgs.mkShell {
-- 
2.53.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox