Skip to contentSkip to conversation

rust: kernel: update `file_with_nul` comment

PATCH In review Miguel Ojeda 5 participants 11 messages Apr 6 – Jul 10 Rust

lore
Share & tools
lore

Miguel Ojeda

author maintainer
#0 lore raw

PATCH v2 1/2 rust: kernel: update `file_with_nul` comment

feature(file_with_nul) [1] has been stabilized in Rust 1.92.0 [2].

Thus update the comment to keep track of it.

In addition, this will help to sort new conditionally enabled features (i.e. cfg_attr) around it appropiately.

---
 rust/kernel/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
rust/kernel/lib.rs +1 -1
index b48221a5b4ec..0fa9d820fe7c 100644
@@ -23,7 +23,7 @@
 // To be determined.
 #![feature(used_with_arg)]
 //
-// `feature(file_with_nul)` is expected to become stable. Before Rust 1.89.0, it did not exist, so
+// `feature(file_with_nul)` is stable since Rust 1.92.0. Before Rust 1.89.0, it did not exist, so
 // enable it conditionally.
 #![cfg_attr(CONFIG_RUSTC_HAS_FILE_WITH_NUL, feature(file_with_nul))]
 

base-commit: 232e79c72f572782434b43d0fc72581271cea7f3

Signature · 1 line
2.53.0
author maintainer
#1 lore raw

PATCH v2 2/2 rust: std_vendor: add `likely()`, `unlikely()` and `cold_path()`

feature(cold_path) is becoming stable [1] in the upcoming Rust 1.95.0 (expected 2026-04-16).

cold_path() can be used directly, but it also allows us to provide likely() and unlikely(), based on cold_path(), similar to the C side ones.

For instance, given:

    fn f1(a: i32) -> i32 {
        if a < 0 {
            return 123;
        }

        42
    }

    fn f2(a: i32) -> i32 {
        if likely(a < 0) {
            return 124;
        }

        42
    }

    fn f3(a: i32) -> i32 {
        if unlikely(a < 0) {
            return 125;
        }

        42
    }

LLVM emits the same code it would for similar C functions:

    f1:
            test   %edi,%edi
            mov    $0x7b,%ecx
            mov    $0x2a,%eax
            cmovs  %ecx,%eax
            ret

    f2:
            mov    $0x7c,%eax
            test   %edi,%edi
        /-- jns    <f2+0xa>
        |   ret
        \-> mov    $0x2a,%eax
            ret

    f3:
            test   %edi,%edi
        /-- js     <f3+0xa>
        |   mov    $0x2a,%eax
        |   ret
        \-> mov    $0x7d,%eax
            ret

The feature itself, feature(cold_path), was added in Rust 1.86.0 [2].

Previously, a PR in Rust 1.84.0 [3] fixed a number of issues with the likely() and unlikely() intrinsics (by implementing them on top of the new cold_path() intrinsic). So we could use that, in principle, for Rust 1.85.0. However, it is just a single version, and it is simpler to avoid intrinsics. Instead, approximate it with #[cold] [4].

Thus add support for cold_path() by applying several approaches:

- For Rust >= 1.86.0, use directly core's cold_path().

- For Rust 1.85, provide a #[cold] no-op, and vendor cores documentation.

And, for all versions, simply provide likely() and unlikely() based on cold_path(), by vendoring core's unstable ones (the one from intrinsics, not the hint wrapper, to save a layer).

In the future, if likely() and unlikely() become stable [5], we may want to use them directly as well.

Now, in the C side, the likely() and unlikely() macros come from compiler.h, which means it is pretty much available everywhere directly. Thus just add these to the prelude (instead of e.g. re-exporting them in the root or in a new hint module).

This will also mean less churn when we can remove the cold_path() version from std_vendor (and potentially the other two too).

I tested that Rust 1.93.0 generate the code above and, in a previous version of the patch, that Rust 1.83.0 and 1.78.0 do not, as expected.

---
v1: https://lore.kernel.org/rust-for-linux/[email protected]/
v2:
- Drop the intrinsics and use #[cold] for Rust 1.85.0.

- Sorted after feature(file_with_nul) since now we know which was the stable version when it happened (Rust 1.92.0).

- Rebased and reworded accordingly.

 init/Kconfig              |   3 +
 rust/kernel/lib.rs        |   4 ++
 rust/kernel/prelude.rs    |   5 ++
 rust/kernel/std_vendor.rs | 142 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 154 insertions(+)
init/Kconfig +3 -0
index d9b795f70a38..f4c3368bf585 100644
@@ -178,6 +178,9 @@ config LD_CAN_USE_KEEP_IN_OVERLAY
 	# https://github.com/llvm/llvm-project/pull/130661
 	def_bool LD_IS_BFD || LLD_VERSION >= 210000
 
+config RUSTC_HAS_COLD_PATH
+	def_bool RUSTC_VERSION >= 108600
+
 config RUSTC_HAS_SPAN_FILE
 	def_bool RUSTC_VERSION >= 108800
 
rust/kernel/lib.rs +4 -0
index 0fa9d820fe7c..0615f741fcd4 100644
@@ -26,6 +26,10 @@
 // `feature(file_with_nul)` is stable since Rust 1.92.0. Before Rust 1.89.0, it did not exist, so
 // enable it conditionally.
 #![cfg_attr(CONFIG_RUSTC_HAS_FILE_WITH_NUL, feature(file_with_nul))]
+//
+// `feature(cold_path)` is stable since Rust 1.95.0. Before Rust 1.86.0, it did not exist, so
+// enable it conditionally.
+#![cfg_attr(CONFIG_RUSTC_HAS_COLD_PATH, feature(cold_path))]
 
 // Ensure conditional compilation based on the kernel configuration works;
 // otherwise we may silently break things like initcall handling.
rust/kernel/prelude.rs +5 -0
index 44edf72a4a24..f5d6d9d9b629 100644
@@ -97,6 +97,11 @@
     pr_notice,
     pr_warn,
     static_assert,
+    std_vendor::{
+        cold_path,
+        likely,
+        unlikely, //
+    },
     str::CStrExt as _,
     try_init,
     try_pin_init,
rust/kernel/std_vendor.rs +142 -0

145 lines not on this page · raw message

--
2.53.0

reviewer Reviewed-by on v2 1/2
#7 lore raw
In reply to Miguel Ojeda
Quoted 10 lines · Miguel Ojeda

feature(file_with_nul) [1] has been stabilized in Rust 1.92.0 [2].

Thus update the comment to keep track of it.

In addition, this will help to sort new conditionally enabled features (i.e. cfg_attr) around it appropiately.

Quoted 3 lines
---
 rust/kernel/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
reviewer Reviewed-by on v2 2/2
#2 lore raw

Re: [PATCH v2 2/2] rust: std_vendor: add `likely()`, `unlikely()` and `cold_path()`

In reply to Miguel Ojeda
Quoted 50 lines · Miguel Ojeda

feature(cold_path) is becoming stable [1] in the upcoming Rust 1.95.0 (expected 2026-04-16).

cold_path() can be used directly, but it also allows us to provide likely() and unlikely(), based on cold_path(), similar to the C side ones.

For instance, given:

    fn f1(a: i32) -> i32 {
        if a < 0 {
            return 123;
        }

        42
    }

    fn f2(a: i32) -> i32 {
        if likely(a < 0) {
            return 124;
        }

        42
    }

    fn f3(a: i32) -> i32 {
        if unlikely(a < 0) {
            return 125;
        }

        42
    }

LLVM emits the same code it would for similar C functions:

    f1:
            test   %edi,%edi
            mov    $0x7b,%ecx
            mov    $0x2a,%eax
            cmovs  %ecx,%eax
            ret

    f2:
            mov    $0x7c,%eax
            test   %edi,%edi
        /-- jns    <f2+0xa>
        |   ret
        \-> mov    $0x2a,%eax
            ret
Quoted 7 lines
    f3:
            test   %edi,%edi
        /-- js     <f3+0xa>
        |   mov    $0x2a,%eax
        |   ret
        \-> mov    $0x7d,%eax
            ret

I haven't checked the assembly, but otherwise:

Quoted 55 lines

The feature itself, feature(cold_path), was added in Rust 1.86.0 [2].

Previously, a PR in Rust 1.84.0 [3] fixed a number of issues with the likely() and unlikely() intrinsics (by implementing them on top of the new cold_path() intrinsic). So we could use that, in principle, for Rust 1.85.0. However, it is just a single version, and it is simpler to avoid intrinsics. Instead, approximate it with #[cold] [4].

Thus add support for cold_path() by applying several approaches:

- For Rust >= 1.86.0, use directly core's cold_path().

- For Rust 1.85, provide a #[cold] no-op, and vendor cores documentation.

And, for all versions, simply provide likely() and unlikely() based on cold_path(), by vendoring core's unstable ones (the one from intrinsics, not the hint wrapper, to save a layer).

In the future, if likely() and unlikely() become stable [5], we may want to use them directly as well.

Now, in the C side, the likely() and unlikely() macros come from compiler.h, which means it is pretty much available everywhere directly. Thus just add these to the prelude (instead of e.g. re-exporting them in the root or in a new hint module).

This will also mean less churn when we can remove the cold_path() version from std_vendor (and potentially the other two too).

I tested that Rust 1.93.0 generate the code above and, in a previous version of the patch, that Rust 1.83.0 and 1.78.0 do not, as expected.

---
v1: https://lore.kernel.org/rust-for-linux/[email protected]/
v2:
- Drop the intrinsics and use #[cold] for Rust 1.85.0.

- Sorted after feature(file_with_nul) since now we know which was the stable version when it happened (Rust 1.92.0).

- Rebased and reworded accordingly.

 init/Kconfig              |   3 +
 rust/kernel/lib.rs        |   4 ++
 rust/kernel/prelude.rs    |   5 ++
 rust/kernel/std_vendor.rs | 142 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 154 insertions(+)
reviewer Acked-by on v2 1/2
#8 lore raw
In reply to Miguel Ojeda
Quoted 10 lines · Miguel Ojeda

feature(file_with_nul) [1] has been stabilized in Rust 1.92.0 [2].

Thus update the comment to keep track of it.

In addition, this will help to sort new conditionally enabled features (i.e. cfg_attr) around it appropiately.

Regards,
Boqun

Quoted 22 lines
---
 rust/kernel/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
rust/kernel/lib.rs +1 -1
index b48221a5b4ec..0fa9d820fe7c 100644
@@ -23,7 +23,7 @@
 // To be determined.
 #![feature(used_with_arg)]
 //
-// `feature(file_with_nul)` is expected to become stable. Before Rust 1.89.0, it did not exist, so
+// `feature(file_with_nul)` is stable since Rust 1.92.0. Before Rust 1.89.0, it did not exist, so
 // enable it conditionally.
 #![cfg_attr(CONFIG_RUSTC_HAS_FILE_WITH_NUL, feature(file_with_nul))]
 

base-commit: 232e79c72f572782434b43d0fc72581271cea7f3

Signature · 1 line
2.53.0
reviewer Reviewed-by on v2 1/2
#9 lore raw
In reply to Miguel Ojeda
Quoted 10 lines · Miguel Ojeda

feature(file_with_nul) [1] has been stabilized in Rust 1.92.0 [2].

Thus update the comment to keep track of it.

In addition, this will help to sort new conditionally enabled features (i.e. cfg_attr) around it appropiately.

reviewer Reviewed-by on v2 2/2
#3 lore raw

Re: [PATCH v2 2/2] rust: std_vendor: add `likely()`, `unlikely()` and `cold_path()`

In reply to Miguel Ojeda
Quoted 91 lines · Miguel Ojeda

feature(cold_path) is becoming stable [1] in the upcoming Rust 1.95.0 (expected 2026-04-16).

cold_path() can be used directly, but it also allows us to provide likely() and unlikely(), based on cold_path(), similar to the C side ones.

For instance, given:

    fn f1(a: i32) -> i32 {
        if a < 0 {
            return 123;
        }

        42
    }

    fn f2(a: i32) -> i32 {
        if likely(a < 0) {
            return 124;
        }

        42
    }

    fn f3(a: i32) -> i32 {
        if unlikely(a < 0) {
            return 125;
        }

        42
    }

LLVM emits the same code it would for similar C functions:

    f1:
            test   %edi,%edi
            mov    $0x7b,%ecx
            mov    $0x2a,%eax
            cmovs  %ecx,%eax
            ret

    f2:
            mov    $0x7c,%eax
            test   %edi,%edi
        /-- jns    <f2+0xa>
        |   ret
        \-> mov    $0x2a,%eax
            ret

    f3:
            test   %edi,%edi
        /-- js     <f3+0xa>
        |   mov    $0x2a,%eax
        |   ret
        \-> mov    $0x7d,%eax
            ret

The feature itself, feature(cold_path), was added in Rust 1.86.0 [2].

Previously, a PR in Rust 1.84.0 [3] fixed a number of issues with the likely() and unlikely() intrinsics (by implementing them on top of the new cold_path() intrinsic). So we could use that, in principle, for Rust 1.85.0. However, it is just a single version, and it is simpler to avoid intrinsics. Instead, approximate it with #[cold] [4].

Thus add support for cold_path() by applying several approaches:

- For Rust >= 1.86.0, use directly core's cold_path().

- For Rust 1.85, provide a #[cold] no-op, and vendor cores documentation.

And, for all versions, simply provide likely() and unlikely() based on cold_path(), by vendoring core's unstable ones (the one from intrinsics, not the hint wrapper, to save a layer).

In the future, if likely() and unlikely() become stable [5], we may want to use them directly as well.

Now, in the C side, the likely() and unlikely() macros come from compiler.h, which means it is pretty much available everywhere directly. Thus just add these to the prelude (instead of e.g. re-exporting them in the root or in a new hint module).

This will also mean less churn when we can remove the cold_path() version from std_vendor (and potentially the other two too).

I tested that Rust 1.93.0 generate the code above and, in a previous version of the patch, that Rust 1.83.0 and 1.78.0 do not, as expected.

Quoted 6 lines
#4 lore raw

Re: [PATCH v2 2/2] rust: std_vendor: add `likely()`, `unlikely()` and `cold_path()`

In reply to Miguel Ojeda

rust/kernel/std_vendor.rs macro_rules! dbg { · line 306

Quoted 3 lines · Miguel Ojeda
rust/kernel/std_vendor.rs +2 -0
+#[cfg(CONFIG_RUSTC_HAS_COLD_PATH)]
+pub use core::hint::cold_path;

This works inside the kernel crate, but Sashiko is correct: we will need to enable the feature to use it later.

And while it can be done, it is not as simple as usual, because it is conditional.

I was already on the fence of making a single function to share the signature anyway, so I think I will just do that in v3.

Cheers,
Miguel

#10 lore raw
In reply to Miguel Ojeda
Quoted 11 lines · Miguel Ojeda

feature(file_with_nul) [1] has been stabilized in Rust 1.92.0 [2].

Thus update the comment to keep track of it.

In addition, this will help to sort new conditionally enabled features (i.e. cfg_attr) around it appropiately.

Applied (just this one) to rust-next -- thanks everyone!

Cheers,
Miguel

reviewer
#5 lore raw

Re: [PATCH v2 2/2] rust: std_vendor: add `likely()`, `unlikely()` and `cold_path()`

In reply to Miguel Ojeda
Quoted 8 lines · Miguel Ojeda

rust/kernel/std_vendor.rs macro_rules! dbg { · line 306

Quoted 3 lines · Miguel Ojeda
rust/kernel/std_vendor.rs +2 -0
+#[cfg(CONFIG_RUSTC_HAS_COLD_PATH)]
+pub use core::hint::cold_path;

This works inside the kernel crate, but Sashiko is correct: we will need to enable the feature to use it later.

Quoted 5 lines

And while it can be done, it is not as simple as usual, because it is conditional.

I was already on the fence of making a single function to share the signature anyway, so I think I will just do that in v3.

It might worth adding a user for this too in v3. warn_flags!() would be a good example.

Best,
Gary

#6 lore raw

Re: [PATCH v2 2/2] rust: std_vendor: add `likely()`, `unlikely()` and `cold_path()`

Quoted 3 lines · Gary Guo

It might worth adding a user for this too in v3. warn_flags!() would be a good example.

+1, yeah.

We will need to go back to v1 or similar (simpler now with the new MSRV), because if I recall correctly, I noticed at some point that v3 wouldn't actually generate the same assembly, which is why I didn't apply it yet. I have to re-recheck and send a new one.

Cheers,
Miguel