Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'rust-sched.2025.06.24' of git://git.kernel.org/pub/scm/linux/kernel/git/boqun/linux into sched/core

Rust task & schedule changes for v6.17:

- Make Task, CondVar and PollCondVar methods inline to avoid unnecessary
function calls

- Add might_sleep() support for Rust code: Rust's "#[track_caller]"
mechanism is used so that Rust's might_sleep() doesn't need to be
defined as a macro

Signed-off-by: Peter Zijlstra <peterz@infradead.org>

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCAAdFiEEj5IosQTPz8XU1wRHSXnow7UH+rgFAmhbLOgACgkQSXnow7UH
# +riscwf/e/+KmJTox5/JOqs6yxxQdCHMaGnMK62E5AII7NsiUI8+XB9z6efzCMmy
# kS2W7aCmBZX67Y1B/xRL/ArHMBAJBi/CrCedZJcmzfB9aMa4Lj4mgiPkbUXkxE6Q
# F5CDQK21ftu+0Q7Hhlq92ec17ZWodOvNxCFBBmjtQqUvBzj0dY45jcG7brs+N+1Z
# t9UO3YokzukNqpIXTpG0HFP+XNafWWCgn9iIQ44lRxIaAoPI44uJjh1OXLTrZ1M9
# EMWYIrsY3b71Im78l6pzr+UOzJdJLI+QCBiz7ySLYz3kZ5dEfFdJOsumbc0G8A69
# VSGDFPEbJxZYuMxrH0E44XmxH4rJdA==
# =gD/Y
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 25 Jun 2025 12:55:36 AM CEST
# gpg: using RSA key 8F9228B104CFCFC5D4D704474979E8C3B507FAB8
# gpg: Can't check signature: No public key

+94
+3
init/Kconfig
··· 142 142 config RUSTC_HAS_UNNECESSARY_TRANSMUTES 143 143 def_bool RUSTC_VERSION >= 108800 144 144 145 + config RUSTC_HAS_FILE_WITH_NUL 146 + def_bool RUSTC_VERSION >= 108900 147 + 145 148 config PAHOLE_VERSION 146 149 int 147 150 default $(shell,$(srctree)/scripts/pahole-version.sh $(PAHOLE))
+6
rust/helpers/task.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 + #include <linux/kernel.h> 3 4 #include <linux/sched/task.h> 5 + 6 + void rust_helper_might_resched(void) 7 + { 8 + might_resched(); 9 + } 4 10 5 11 struct task_struct *rust_helper_get_current(void) 6 12 {
+48
rust/kernel/lib.rs
··· 40 40 #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(coerce_unsized))] 41 41 #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(dispatch_from_dyn))] 42 42 #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(unsize))] 43 + // 44 + // `feature(file_with_nul)` is expected to become stable. Before Rust 1.89.0, it did not exist, so 45 + // enable it conditionally. 46 + #![cfg_attr(CONFIG_RUSTC_HAS_FILE_WITH_NUL, feature(file_with_nul))] 43 47 44 48 // Ensure conditional compilation based on the kernel configuration works; 45 49 // otherwise we may silently break things like initcall handling. ··· 277 273 ($($asm:expr),* ; $($rest:tt)*) => { 278 274 ::core::arch::asm!( $($asm)*, $($rest)* ) 279 275 }; 276 + } 277 + 278 + /// Gets the C string file name of a [`Location`]. 279 + /// 280 + /// If `file_with_nul()` is not available, returns a string that warns about it. 281 + /// 282 + /// [`Location`]: core::panic::Location 283 + /// 284 + /// # Examples 285 + /// 286 + /// ``` 287 + /// # use kernel::file_from_location; 288 + /// 289 + /// #[track_caller] 290 + /// fn foo() { 291 + /// let caller = core::panic::Location::caller(); 292 + /// 293 + /// // Output: 294 + /// // - A path like "rust/kernel/example.rs" if file_with_nul() is available. 295 + /// // - "<Location::file_with_nul() not supported>" otherwise. 296 + /// let caller_file = file_from_location(caller); 297 + /// 298 + /// // Prints out the message with caller's file name. 299 + /// pr_info!("foo() called in file {caller_file:?}\n"); 300 + /// 301 + /// # if cfg!(CONFIG_RUSTC_HAS_FILE_WITH_NUL) { 302 + /// # assert_eq!(Ok(caller.file()), caller_file.to_str()); 303 + /// # } 304 + /// } 305 + /// 306 + /// # foo(); 307 + /// ``` 308 + #[inline] 309 + pub fn file_from_location<'a>(loc: &'a core::panic::Location<'a>) -> &'a core::ffi::CStr { 310 + #[cfg(CONFIG_RUSTC_HAS_FILE_WITH_NUL)] 311 + { 312 + loc.file_with_nul() 313 + } 314 + 315 + #[cfg(not(CONFIG_RUSTC_HAS_FILE_WITH_NUL))] 316 + { 317 + let _ = loc; 318 + c"<Location::file_with_nul() not supported>" 319 + } 280 320 }
+3
rust/kernel/sync/condvar.rs
··· 216 216 /// This method behaves like `notify_one`, except that it hints to the scheduler that the 217 217 /// current thread is about to go to sleep, so it should schedule the target thread on the same 218 218 /// CPU. 219 + #[inline] 219 220 pub fn notify_sync(&self) { 220 221 // SAFETY: `wait_queue_head` points to valid memory. 221 222 unsafe { bindings::__wake_up_sync(self.wait_queue_head.get(), TASK_NORMAL) }; ··· 226 225 /// 227 226 /// This is not 'sticky' in the sense that if no thread is waiting, the notification is lost 228 227 /// completely (as opposed to automatically waking up the next waiter). 228 + #[inline] 229 229 pub fn notify_one(&self) { 230 230 self.notify(1); 231 231 } ··· 235 233 /// 236 234 /// This is not 'sticky' in the sense that if no thread is waiting, the notification is lost 237 235 /// completely (as opposed to automatically waking up the next waiter). 236 + #[inline] 238 237 pub fn notify_all(&self) { 239 238 self.notify(0); 240 239 }
+1
rust/kernel/sync/poll.rs
··· 107 107 108 108 #[pinned_drop] 109 109 impl PinnedDrop for PollCondVar { 110 + #[inline] 110 111 fn drop(self: Pin<&mut Self>) { 111 112 // Clear anything registered using `register_wait`. 112 113 //
+33
rust/kernel/task.rs
··· 173 173 /// Callers must ensure that the returned object is only used to access a [`CurrentTask`] 174 174 /// within the task context that was active when this function was called. For more details, 175 175 /// see the invariants section for [`CurrentTask`]. 176 + #[inline] 176 177 pub unsafe fn current() -> impl Deref<Target = CurrentTask> { 177 178 struct TaskRef { 178 179 task: *const CurrentTask, ··· 223 222 } 224 223 225 224 /// Returns the UID of the given task. 225 + #[inline] 226 226 pub fn uid(&self) -> Kuid { 227 227 // SAFETY: It's always safe to call `task_uid` on a valid task. 228 228 Kuid::from_raw(unsafe { bindings::task_uid(self.as_ptr()) }) 229 229 } 230 230 231 231 /// Returns the effective UID of the given task. 232 + #[inline] 232 233 pub fn euid(&self) -> Kuid { 233 234 // SAFETY: It's always safe to call `task_euid` on a valid task. 234 235 Kuid::from_raw(unsafe { bindings::task_euid(self.as_ptr()) }) 235 236 } 236 237 237 238 /// Determines whether the given task has pending signals. 239 + #[inline] 238 240 pub fn signal_pending(&self) -> bool { 239 241 // SAFETY: It's always safe to call `signal_pending` on a valid task. 240 242 unsafe { bindings::signal_pending(self.as_ptr()) != 0 } 241 243 } 242 244 243 245 /// Returns task's pid namespace with elevated reference count 246 + #[inline] 244 247 pub fn get_pid_ns(&self) -> Option<ARef<PidNamespace>> { 245 248 // SAFETY: By the type invariant, we know that `self.0` is valid. 246 249 let ptr = unsafe { bindings::task_get_pid_ns(self.as_ptr()) }; ··· 260 255 261 256 /// Returns the given task's pid in the provided pid namespace. 262 257 #[doc(alias = "task_tgid_nr_ns")] 258 + #[inline] 263 259 pub fn tgid_nr_ns(&self, pidns: Option<&PidNamespace>) -> Pid { 264 260 let pidns = match pidns { 265 261 Some(pidns) => pidns.as_ptr(), ··· 274 268 } 275 269 276 270 /// Wakes up the task. 271 + #[inline] 277 272 pub fn wake_up(&self) { 278 273 // SAFETY: It's always safe to call `wake_up_process` on a valid task, even if the task 279 274 // running. ··· 348 341 349 342 // SAFETY: The type invariants guarantee that `Task` is always refcounted. 350 343 unsafe impl crate::types::AlwaysRefCounted for Task { 344 + #[inline] 351 345 fn inc_ref(&self) { 352 346 // SAFETY: The existence of a shared reference means that the refcount is nonzero. 353 347 unsafe { bindings::get_task_struct(self.as_ptr()) }; 354 348 } 355 349 350 + #[inline] 356 351 unsafe fn dec_ref(obj: ptr::NonNull<Self>) { 357 352 // SAFETY: The safety requirements guarantee that the refcount is nonzero. 358 353 unsafe { bindings::put_task_struct(obj.cast().as_ptr()) } ··· 400 391 } 401 392 402 393 impl Eq for Kuid {} 394 + 395 + /// Annotation for functions that can sleep. 396 + /// 397 + /// Equivalent to the C side [`might_sleep()`], this function serves as 398 + /// a debugging aid and a potential scheduling point. 399 + /// 400 + /// This function can only be used in a nonatomic context. 401 + /// 402 + /// [`might_sleep()`]: https://docs.kernel.org/driver-api/basics.html#c.might_sleep 403 + #[track_caller] 404 + #[inline] 405 + pub fn might_sleep() { 406 + #[cfg(CONFIG_DEBUG_ATOMIC_SLEEP)] 407 + { 408 + let loc = core::panic::Location::caller(); 409 + let file = kernel::file_from_location(loc); 410 + 411 + // SAFETY: `file.as_ptr()` is valid for reading and guaranteed to be nul-terminated. 412 + unsafe { crate::bindings::__might_sleep(file.as_ptr().cast(), loc.line() as i32) } 413 + } 414 + 415 + // SAFETY: Always safe to call. 416 + unsafe { crate::bindings::might_resched() } 417 + }