Merge tag 'sched-core-2025-07-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull scheduler updates from Ingo Molnar:
"Core scheduler changes:
- Better tracking of maximum lag of tasks in presence of different
slices duration, for better handling of lag in the fair scheduler
(Vincent Guittot)
- Clean up and standardize #if/#else/#endif markers throughout the
entire scheduler code base (Ingo Molnar)
- Make SMP unconditional: build the SMP scheduler's data structures
and logic on UP kernel too, even though they are not used, to
simplify the scheduler and remove around 200 #ifdef/[#else]/#endif
blocks from the scheduler (Ingo Molnar)
- Reorganize cgroup bandwidth control interface handling for better
interfacing with sched_ext (Tejun Heo)
Balancing:
- Bump sd->max_newidle_lb_cost when newidle balance fails (Chris
Mason)
- Remove sched_domain_topology_level::flags to simplify the code
(Prateek Nayak)
- Simplify and clean up build_sched_topology() (Li Chen)
- Optimize build_sched_topology() on large machines (Li Chen)
Real-time scheduling:
- Add initial version of proxy execution: a mechanism for
mutex-owning tasks to inherit the scheduling context of higher
priority waiters.
Currently limited to a single runqueue and conditional on
CONFIG_EXPERT, and other limitations (John Stultz, Peter Zijlstra,
Valentin Schneider)
- Deadline scheduler (Juri Lelli):
- Fix dl_servers initialization order (Juri Lelli)
- Fix DL scheduler's root domain reinitialization logic (Juri
Lelli)
- Fix accounting bugs after global limits change (Juri Lelli)
- Fix scalability regression by implementing less agressive
dl_server handling (Peter Zijlstra)
PSI:
- Improve scalability by optimizing psi_group_change() cpu_clock()
usage (Peter Zijlstra)
Rust changes:
- Make Task, CondVar and PollCondVar methods inline to avoid
unnecessary function calls (Kunwu Chan, Panagiotis Foliadis)
- 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 (Fujita Tomonori)
- Introduce file_from_location() (Boqun Feng)
Debugging & instrumentation:
- Make clangd usable with scheduler source code files again (Peter
Zijlstra)
- tools: Add root_domains_dump.py which dumps root domains info (Juri
Lelli)
- tools: Add dl_bw_dump.py for printing bandwidth accounting info
(Juri Lelli)
Misc cleanups & fixes:
- Remove play_idle() (Feng Lee)
- Fix check_preemption_disabled() (Sebastian Andrzej Siewior)
- Do not call __put_task_struct() on RT if pi_blocked_on is set (Luis
Claudio R. Goncalves)
- Correct the comment in place_entity() (wang wei)"
* tag 'sched-core-2025-07-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (84 commits)
sched/idle: Remove play_idle()
sched: Do not call __put_task_struct() on rt if pi_blocked_on is set
sched: Start blocked_on chain processing in find_proxy_task()
sched: Fix proxy/current (push,pull)ability
sched: Add an initial sketch of the find_proxy_task() function
sched: Fix runtime accounting w/ split exec & sched contexts
sched: Move update_curr_task logic into update_curr_se
locking/mutex: Add p->blocked_on wrappers for correctness checks
locking/mutex: Rework task_struct::blocked_on
sched: Add CONFIG_SCHED_PROXY_EXEC & boot argument to enable/disable
sched/topology: Remove sched_domain_topology_level::flags
x86/smpboot: avoid SMT domain attach/destroy if SMT is not enabled
x86/smpboot: moves x86_topology to static initialize and truncate
x86/smpboot: remove redundant CONFIG_SCHED_SMT
smpboot: introduce SDTL_INIT() helper to tidy sched topology setup
tools/sched: Add dl_bw_dump.py for printing bandwidth accounting info
tools/sched: Add root_domains_dump.py which dumps root domains info
sched/deadline: Fix accounting after global limits change
sched/deadline: Reset extra_bw to max_bw when clearing root domains
sched/deadline: Initialize dl_servers after SMP
...
This commit is contained in:
@@ -43,6 +43,10 @@
|
||||
#![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(coerce_unsized))]
|
||||
#![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(dispatch_from_dyn))]
|
||||
#![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(unsize))]
|
||||
//
|
||||
// `feature(file_with_nul)` is expected to become stable. 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))]
|
||||
|
||||
// Ensure conditional compilation based on the kernel configuration works;
|
||||
// otherwise we may silently break things like initcall handling.
|
||||
@@ -279,3 +283,47 @@ macro_rules! asm {
|
||||
::core::arch::asm!( $($asm)*, $($rest)* )
|
||||
};
|
||||
}
|
||||
|
||||
/// Gets the C string file name of a [`Location`].
|
||||
///
|
||||
/// If `file_with_nul()` is not available, returns a string that warns about it.
|
||||
///
|
||||
/// [`Location`]: core::panic::Location
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use kernel::file_from_location;
|
||||
///
|
||||
/// #[track_caller]
|
||||
/// fn foo() {
|
||||
/// let caller = core::panic::Location::caller();
|
||||
///
|
||||
/// // Output:
|
||||
/// // - A path like "rust/kernel/example.rs" if file_with_nul() is available.
|
||||
/// // - "<Location::file_with_nul() not supported>" otherwise.
|
||||
/// let caller_file = file_from_location(caller);
|
||||
///
|
||||
/// // Prints out the message with caller's file name.
|
||||
/// pr_info!("foo() called in file {caller_file:?}\n");
|
||||
///
|
||||
/// # if cfg!(CONFIG_RUSTC_HAS_FILE_WITH_NUL) {
|
||||
/// # assert_eq!(Ok(caller.file()), caller_file.to_str());
|
||||
/// # }
|
||||
/// }
|
||||
///
|
||||
/// # foo();
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn file_from_location<'a>(loc: &'a core::panic::Location<'a>) -> &'a core::ffi::CStr {
|
||||
#[cfg(CONFIG_RUSTC_HAS_FILE_WITH_NUL)]
|
||||
{
|
||||
loc.file_with_nul()
|
||||
}
|
||||
|
||||
#[cfg(not(CONFIG_RUSTC_HAS_FILE_WITH_NUL))]
|
||||
{
|
||||
let _ = loc;
|
||||
c"<Location::file_with_nul() not supported>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,6 +216,7 @@ impl CondVar {
|
||||
/// This method behaves like `notify_one`, except that it hints to the scheduler that the
|
||||
/// current thread is about to go to sleep, so it should schedule the target thread on the same
|
||||
/// CPU.
|
||||
#[inline]
|
||||
pub fn notify_sync(&self) {
|
||||
// SAFETY: `wait_queue_head` points to valid memory.
|
||||
unsafe { bindings::__wake_up_sync(self.wait_queue_head.get(), TASK_NORMAL) };
|
||||
@@ -225,6 +226,7 @@ impl CondVar {
|
||||
///
|
||||
/// This is not 'sticky' in the sense that if no thread is waiting, the notification is lost
|
||||
/// completely (as opposed to automatically waking up the next waiter).
|
||||
#[inline]
|
||||
pub fn notify_one(&self) {
|
||||
self.notify(1);
|
||||
}
|
||||
@@ -233,6 +235,7 @@ impl CondVar {
|
||||
///
|
||||
/// This is not 'sticky' in the sense that if no thread is waiting, the notification is lost
|
||||
/// completely (as opposed to automatically waking up the next waiter).
|
||||
#[inline]
|
||||
pub fn notify_all(&self) {
|
||||
self.notify(0);
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ impl Deref for PollCondVar {
|
||||
|
||||
#[pinned_drop]
|
||||
impl PinnedDrop for PollCondVar {
|
||||
#[inline]
|
||||
fn drop(self: Pin<&mut Self>) {
|
||||
// Clear anything registered using `register_wait`.
|
||||
//
|
||||
|
||||
@@ -173,6 +173,7 @@ impl Task {
|
||||
/// Callers must ensure that the returned object is only used to access a [`CurrentTask`]
|
||||
/// within the task context that was active when this function was called. For more details,
|
||||
/// see the invariants section for [`CurrentTask`].
|
||||
#[inline]
|
||||
pub unsafe fn current() -> impl Deref<Target = CurrentTask> {
|
||||
struct TaskRef {
|
||||
task: *const CurrentTask,
|
||||
@@ -222,24 +223,28 @@ impl Task {
|
||||
}
|
||||
|
||||
/// Returns the UID of the given task.
|
||||
#[inline]
|
||||
pub fn uid(&self) -> Kuid {
|
||||
// SAFETY: It's always safe to call `task_uid` on a valid task.
|
||||
Kuid::from_raw(unsafe { bindings::task_uid(self.as_ptr()) })
|
||||
}
|
||||
|
||||
/// Returns the effective UID of the given task.
|
||||
#[inline]
|
||||
pub fn euid(&self) -> Kuid {
|
||||
// SAFETY: It's always safe to call `task_euid` on a valid task.
|
||||
Kuid::from_raw(unsafe { bindings::task_euid(self.as_ptr()) })
|
||||
}
|
||||
|
||||
/// Determines whether the given task has pending signals.
|
||||
#[inline]
|
||||
pub fn signal_pending(&self) -> bool {
|
||||
// SAFETY: It's always safe to call `signal_pending` on a valid task.
|
||||
unsafe { bindings::signal_pending(self.as_ptr()) != 0 }
|
||||
}
|
||||
|
||||
/// Returns task's pid namespace with elevated reference count
|
||||
#[inline]
|
||||
pub fn get_pid_ns(&self) -> Option<ARef<PidNamespace>> {
|
||||
// SAFETY: By the type invariant, we know that `self.0` is valid.
|
||||
let ptr = unsafe { bindings::task_get_pid_ns(self.as_ptr()) };
|
||||
@@ -255,6 +260,7 @@ impl Task {
|
||||
|
||||
/// Returns the given task's pid in the provided pid namespace.
|
||||
#[doc(alias = "task_tgid_nr_ns")]
|
||||
#[inline]
|
||||
pub fn tgid_nr_ns(&self, pidns: Option<&PidNamespace>) -> Pid {
|
||||
let pidns = match pidns {
|
||||
Some(pidns) => pidns.as_ptr(),
|
||||
@@ -268,6 +274,7 @@ impl Task {
|
||||
}
|
||||
|
||||
/// Wakes up the task.
|
||||
#[inline]
|
||||
pub fn wake_up(&self) {
|
||||
// SAFETY: It's always safe to call `wake_up_process` on a valid task, even if the task
|
||||
// running.
|
||||
@@ -341,11 +348,13 @@ impl CurrentTask {
|
||||
|
||||
// SAFETY: The type invariants guarantee that `Task` is always refcounted.
|
||||
unsafe impl crate::types::AlwaysRefCounted for Task {
|
||||
#[inline]
|
||||
fn inc_ref(&self) {
|
||||
// SAFETY: The existence of a shared reference means that the refcount is nonzero.
|
||||
unsafe { bindings::get_task_struct(self.as_ptr()) };
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn dec_ref(obj: ptr::NonNull<Self>) {
|
||||
// SAFETY: The safety requirements guarantee that the refcount is nonzero.
|
||||
unsafe { bindings::put_task_struct(obj.cast().as_ptr()) }
|
||||
@@ -391,3 +400,27 @@ impl PartialEq for Kuid {
|
||||
}
|
||||
|
||||
impl Eq for Kuid {}
|
||||
|
||||
/// Annotation for functions that can sleep.
|
||||
///
|
||||
/// Equivalent to the C side [`might_sleep()`], this function serves as
|
||||
/// a debugging aid and a potential scheduling point.
|
||||
///
|
||||
/// This function can only be used in a nonatomic context.
|
||||
///
|
||||
/// [`might_sleep()`]: https://docs.kernel.org/driver-api/basics.html#c.might_sleep
|
||||
#[track_caller]
|
||||
#[inline]
|
||||
pub fn might_sleep() {
|
||||
#[cfg(CONFIG_DEBUG_ATOMIC_SLEEP)]
|
||||
{
|
||||
let loc = core::panic::Location::caller();
|
||||
let file = kernel::file_from_location(loc);
|
||||
|
||||
// SAFETY: `file.as_ptr()` is valid for reading and guaranteed to be nul-terminated.
|
||||
unsafe { crate::bindings::__might_sleep(file.as_ptr().cast(), loc.line() as i32) }
|
||||
}
|
||||
|
||||
// SAFETY: Always safe to call.
|
||||
unsafe { crate::bindings::might_resched() }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user