aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
AgeCommit message (Collapse)AuthorFilesLines
2026-07-16liveupdate: fix GET_NAME ioctl argument validationJackie Liu1-1/+1
LIVEUPDATE_SESSION_GET_NAME was developed in the liveupdate/next branch while the session type validation change was carried in liveupdate-fixes. When the conflict between the two branches was resolved, the GET_NAME operation descriptor picked up the structure and last member from RETRIEVE_FD. This makes both its known size and minimum size 16 bytes rather than 72. A zero-initialized request still succeeds because luo_session_get_name() writes the full name before luo_ucmd_respond() copies the full GET_NAME response to userspace. However, copy_struct_from_user() treats the output-only name field as unknown trailing data and rejects the request with -E2BIG if any byte in that field is nonzero. Use the GET_NAME structure and its name field in the descriptor. Link: https://lore.kernel.org/all/ahWlYXNjGUbkKoHy@sirena.org.uk/ Assisted-by: Codex:gpt-5.6-sol Reviewed-by: Pratyush Yadav (Google) <pratyush@kernel.org> Signed-off-by: Jackie Liu <liuyun01@kylinos.cn> Link: https://patch.msgid.link/20260716012607.22020-1-liu.yun@linux.dev Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
2026-07-15sched_ext: Add the scx_has_subs static key and gate sub-sched hot pathsTejun Heo5-4/+65
With CONFIG_EXT_SUB_SCHED=y but no sub-scheduler attached - the common case - hot paths still pay for sub-sched bookkeeping. Gate it behind __scx_has_subs, a static key counting live sub-schedulers, so that a root-only system stops paying. Most conversions are simple skip-if-no-sub tests. scx_idle_notify() is special - it's a hierarchy walk, so give it a fast path which notifies the root directly using the same tests as the walk. A pending SCX_RQ_SUB_IDLE_RENOTIFY can be ignored as no sub can be owed one and the caller clears the flag either way. Suggested-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-15sched_ext: Gate sub_dispatch_prev with CONFIG_EXT_SUB_SCHEDTejun Heo2-10/+12
rq->scx.sub_dispatch_prev is sub-sched-only but was left unconditional. Move it into the CONFIG_EXT_SUB_SCHED block next to ecaps_to_sync and gate its updates. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-15sched_ext: Move scx_dispatch_sched() to a new inlines.hTejun Heo5-110/+128
scx_dispatch_sched() is common dispatch machinery and looks out of place in sub.h, but it needs scx_cpu_arg() from cid.h and can't move into internal.h without creating a circular include. Add inlines.h on top of internal.h and cid.h, and move the function there. The function was sub.h's only cid.h user, so drop that include. Pure code move, no functional change. v2: Host the function in a new inlines.h instead of at internal.h's tail, which formed a circular include with cid.h. Drop sub.h's now-unused cid.h include. (sashiko AI) Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-15sched_ext: Remove queued ecaps syncs directly on sched teardownTejun Heo2-26/+43
scx_discard_ecaps_to_sync() waited for balance_one() to consume a dying sched's queued ecaps sync, polling with resched_cpu() + msleep(). The wait is unbounded - the ext dl_server forces picks through sustained fair or RT load only while ext tasks are queued, so an ext-idle cpu monopolized by a higher class can stall the teardown indefinitely. Remove the node directly instead: take all queued nodes, drop the dying sched's and resplice the rest. Consumption runs under the rq lock and batch nodes read as on-list throughout, so the producer-side dedup stays correct. A node that an in-flight scx_process_sync_ecaps() batch holds across a dispatch-induced rq unlock still needs a wait, but one bounded by that batch completing rather than by a future balance. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-15srcu: expose srcu_readers_active()Onur Özkan2-26/+1
This is needed by rust/helpers/srcu.c which now adds rust_helper_srcu_readers_active() as a wrapper around the SRCU helper for Rust callers. To achive this: 1- Move the srcu_readers_active() implementation from "kernel/rcu/srcutree.c" to "include/linux/srcutree.h". 2- Implement a matching srcu_readers_active() in "include/linux/srcutiny.h" and use it on the existing open-coded WARN_ON() check in cleanup_srcu_struct(). Signed-off-by: Onur Özkan <work@onurozkan.dev> Reviewed-by: Gary Guo <gary@garyguo.net> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Boqun Feng <boqun@kernel.org> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2026-07-15srcu: make init_srcu_struct() consistently wrap __init_srcu_struct()Onur Özkan2-11/+12
Restructure the SRCU initialization functions so it always follows one direction: init_srcu_struct() -> __init_srcu_struct() -> lockdep or generic This uses the same wrapper style as mutex. It avoids the old confusing style where init_srcu_struct() and __init_srcu_struct() called each other in different configs. It also helps Rust side to have simpler helper for SRCU initialization. Signed-off-by: Onur Özkan <work@onurozkan.dev> Reviewed-by: Gary Guo <gary@garyguo.net> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Boqun Feng <boqun@kernel.org> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2026-07-15rcutorture: Abstract reader-segment dump into rcu_torture_dump_read_segs()Paul E. McKenney1-72/+76
This commit abstracts the open-coded dumping of reader segments in the rcu_torture_cleanup() function into a new rcu_torture_dump_read_segs() function. This abstraction will allow reader segments to be dumped for other purposes. Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2026-07-15rcu-tasks: TASKS_TRACE_RCU doesn't need IRQ_WORKPaul E. McKenney1-1/+0
Now that Tasks Trace RCU is implemented in terms of SRCU, it no longer has any particular need for the IRQ_WORK Kconfig option. This commit therefore removes the "select IRQ_WORK" from the TASKS_TRACE_RCU Kconfig option. Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2026-07-15cpufreq: schedutil: Fix self-contradictory comment in sugov_iowait_apply()Zhongqiu Han1-1/+1
The kerneldoc of sugov_iowait_apply() says the IO boost value is increased in sugov_iowait_apply() and, in the same sentence, that it is decreased by the same function. That is self-contradictory, and the first part is wrong: sugov_iowait_apply() only decreases the boost. The boost is actually increased in sugov_iowait_boost(). Fix the comment to name sugov_iowait_boost() as the place where the boost is increased, so it matches the code. No functional change. Fixes: fd7d5287fd65 ("cpufreq: schedutil: Cleanup and document iowait boost") Signed-off-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com> Reviewed-by: Christian Loehle <christian.loehle@arm.com> Link: https://patch.msgid.link/20260703092433.4080165-1-zhongqiu.han@oss.qualcomm.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2026-07-15cpufreq: intel_pstate: Adjust the .adjust_perf() driver callbackRafael J. Wysocki1-1/+3
In some cases, the processor may not actually stick to the "desired" performance level programmed through the driver's .adjust_perf() callback and may go above it, which may not be desirable (for instance, there may be a UCLAMP_MAX limit set for the task currently running on the given CPU which should be respected). Address that by adjusting the .adjust_perf() callback to take an additional argument, max_perf, representing the maximum allowed performance level of the CPU and update the intel_pstate driver to take that argument into account as appropriate. Accordingly, adjust cpufreq_driver_adjust_perf() and the other existing user of .adjust_perf(), which is the amd-pstate driver (but the behavior of that driver is not changed). While at it, also update the cpufreq_driver_adjust_perf() documentation to reflect this change and some previous code changes that have not been taken into account in it. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com> Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org> Link: https://patch.msgid.link/6277654.lOV4Wx5bFT@rafael.j.wysocki [ rjw: Adjusted Rust function formatting ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2026-07-15sched/psi: Shut down rtpoll_timer in psi_cgroup_free()Tejun Heo1-0/+6
psi_schedule_rtpoll_work() is called locklessly from the scheduler hotpath and can race psi_trigger_destroy() taking down the last rtpoll trigger under rtpoll_trigger_lock: psi_schedule_rtpoll_work() psi_trigger_destroy() rcu_read_lock(); task = rcu_dereference(rtpoll_task); rcu_assign_pointer(rtpoll_task, NULL); timer_delete(&rtpoll_timer); mod_timer(&rtpoll_timer, ...); rcu_read_unlock(); synchronize_rcu(); kthread_stop(task_to_destroy); The group can then be freed with the re-armed timer still pending, and poll_timer_fn() runs on freed memory. 461daba06bdc ("psi: eliminate kthread_worker from psi trigger scheduling mechanism") deleted the timer synchronously after the synchronize_rcu(), which prevented this but raced trigger creation instead: the deletion could cancel the timer that a new trigger set armed during the grace period and, as creation also reinitialized the timer at the time, corrupt it. 8f91efd870ea ("psi: Fix race between psi_trigger_create/destroy") moved the initialization into group_init() and the deletion into the locked section, trading the creation races for the window above. Neither placement in the destruction path works. A pending timer firing while the group is alive is harmless though. poll_timer_fn() just wakes the rtpoll waitqueue and doesn't re-arm itself. Bind the timer to the group's lifetime instead and shut it down in psi_cgroup_free(). Nothing can arm it by then. timer_shutdown_sync() because the timer is never armed again. Fixes: 8f91efd870ea ("psi: Fix race between psi_trigger_create/destroy") Cc: stable@vger.kernel.org # v5.10+ Reported-by: Sashiko AI <sashiko-bot@kernel.org> Closes: https://lore.kernel.org/all/20260711000434.36C4A1F000E9@smtp.kernel.org/ Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Tested-by: Matt Fleming <mfleming@cloudflare.com> Acked-by: Suren Baghdasaryan <surenb@google.com>
2026-07-15sched/psi: Create the psimon kthread outside of cgroup_mutexTejun Heo2-17/+75
a5b98009f16d ("sched/psi: fix race between file release and pressure write") made pressure_write() hold cgroup_mutex across psi_trigger_create(), which forks the psimon kthread for the first rtpoll trigger. As kthread creation depends on the whole fork path, the commit inadvertently created a lot of unwanted locking dependencies from cgroup_mutex. sched_ext got hit by one: its enable path blocks forks and then grabs cgroup_mutex, so a pressure write racing a scheduler enable deadlocks, with every other fork piling up behind. Fix it by splitting trigger creation so that the worker is forked with cgroup_mutex dropped and the kernfs active reference left broken. The latter matters because rmdir and cgroup.pressure writes drain active references under cgroup_mutex. Publishing the trigger last keeps error reporting synchronous and preserves the of->priv lifetime rules. The trigger registered in the first stage pins the group's rtpoll machinery across the unlocked window, leaving only creation races to resolve. The catch-up poll on installation covers scheduling attempts dropped while there was no worker. v2: Retagged sched/psi (was cgroup). Fixes: a5b98009f16d ("sched/psi: fix race between file release and pressure write") Cc: stable@vger.kernel.org Cc: Edward Adam Davis <eadavis@qq.com> Cc: Chen Ridong <chenridong@huaweicloud.com> Reported-by: Matt Fleming <mfleming@cloudflare.com> Closes: https://lore.kernel.org/all/20260710100441.2653477-1-matt@readmodwrite.com/ Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Tested-by: Matt Fleming <mfleming@cloudflare.com> Acked-by: Suren Baghdasaryan <surenb@google.com>
2026-07-15bpf: Reject negative const offsets for buffer pointersSun Jian1-12/+19
The verifier rejects variable offsets for PTR_TO_TP_BUFFER and PTR_TO_BUF accesses, but it currently accepts a constant negative offset produced by pointer arithmetic. Commit 022ac0750883 ("bpf: use reg->var_off instead of reg->off for pointers") moved constant pointer offsets from reg->off to reg->var_off. However, __check_buffer_access() continued to check only the instruction offset. An access with reg->var_off equal to -8 and an instruction offset of zero therefore passes verification. For writable raw tracepoints, the access end is also calculated from the unsigned reg->var_off.value. An eight-byte access starting at -8 wraps the calculated end to zero, allowing the program to load and attach without increasing max_tp_access. After ensuring that reg->var_off is constant, calculate the effective access start using signed arithmetic and reject it when it is negative. Use the validated start to calculate the access end for both PTR_TO_TP_BUFFER and PTR_TO_BUF. Fixes: 022ac0750883 ("bpf: use reg->var_off instead of reg->off for pointers") Signed-off-by: Sun Jian <sun.jian.kdev@gmail.com> Acked-by: Shung-Hsi Yu <shung-hsi.yu@suse.com> Cc: stable@vger.kernel.org # 5.2.0 Link: https://patch.msgid.link/20260714093846.18159-2-sun.jian.kdev@gmail.com Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
2026-07-15bpf: Unify helper and kfunc call argument metaAmery Hung2-57/+39
Helper and kfunc argument checking carried two separate meta structs: the verifier-local struct bpf_call_arg_meta and bpf_kfunc_call_arg_meta. Merge them into a single struct bpf_call_arg_meta. This is groundwork for sharing argument checking between helpers and kfuncs. While merging, drop the btf_id field from the helper meta since it is never used. No functional change. Signed-off-by: Amery Hung <ameryhung@gmail.com> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/bpf/20260715064047.1793790-8-ameryhung@gmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-07-15bpf: Drop redundant pkt_access from bpf_call_arg_metaAmery Hung1-6/+4
meta->pkt_access is only ever a copy of fn->pkt_access, assigned once in check_helper_call() and read back in may_access_direct_pkt_data(). Have may_access_direct_pkt_data() take the bpf_func_proto and read fn->pkt_access directly, and drop the meta field along with its assignment. The only non-NULL caller, check_func_arg(), already has fn in scope; the remaining callers pass NULL and are unaffected. No functional change intended. Suggested-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/bpf/20260715064047.1793790-7-ameryhung@gmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-07-15bpf: Unify helper and kfunc allocation-size argument handlingAmery Hung1-40/+47
The constant "size of the PTR_TO_MEM returned in R0" argument is handled by both helpers (ARG_CONST_ALLOC_SIZE_OR_ZERO) and kfuncs (__rdonly_buf_size / __rdwr_buf_size), each with its own meta field (meta->mem_size, meta->r0_size) and duplicated validation. Add struct arg_alloc_mem_desc and a shared process_const_alloc_mem_size(), and replace both fields with meta->arg_alloc_mem. The desc records presence with a 'found' flag instead of using a non-zero size as the sentinel. This also fixes a pre-existing bug on the kfunc return path: "no size argument" was tested as r0_size == 0, so an explicit __rdonly_buf_size/__rdwr_buf_size of 0 was treated as absent and fell through to btf_resolve_size(), giving R0 the size of the pointed-to return type instead of 0. With 'found', an explicit zero size is honored and btf_resolve_size() is used only when no size argument was passed. The size is stored in a u32, matching regs[R0].mem_size. The U32_MAX check now apply to both helper and kfunc through process_const_alloc_mem_size(). Fold bpf_session_cookie return size assignment into current kfunc return size resolution path. Note that verifier saves kfunc return size through r0_size instead of mem_size. The later has no active readers so remove it. Signed-off-by: Amery Hung <ameryhung@gmail.com> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/bpf/20260715064047.1793790-5-ameryhung@gmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-07-15bpf: Pass argno to callees in check_func_arg() instead of argno_from_reg(regno)Amery Hung1-19/+17
check_func_arg() only ever handles register arguments (the caller loops over the first MAX_BPF_FUNC_REG_ARGS arguments), so a single argno_t built from the register number identifies the argument for every callee. Remove the duplicated argno_from_reg() calls to simplify check_func_arg(). 'regno' is still kept for the few places that need the raw register number directly (register reads, verbose R%d messages) and for referring to the neighbouring size/memory argument in the ARG_CONST_SIZE{,_OR_ZERO} cases. No functional change intended. Suggested-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/bpf/20260715064047.1793790-4-ameryhung@gmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-07-15bpf: Factor out raw_mode-related fields in bpf_call_arg_metaAmery Hung1-31/+27
To prepare for unifying the helper and kfunc call_arg_meta, group the scattered MEM_UNINIT ("raw") memory argument fields (raw_mode, regno and access_size) into a new struct arg_raw_mem_desc. The intention is to make it clear about when these are set and used instead of fields with overly generic names. Identify the raw argument once, up front, in check_raw_mode_ok() (like check_proto_release_reg() does for release_regno), recording its regno. check_stack_range_initialized() now recognizes the raw buffer by matching that regno, so the separate raw_mode flag is no longer needed, and the per-argument "meta->raw_mode = arg_type & MEM_UNINIT" assignments in check_func_arg() go away with it. A raw memory argument can be tagged either ARG_PTR_TO_MEM | MEM_UNINIT or ARG_PTR_TO_MAP_VALUE | MEM_UNINIT (the output buffer of bpf_map_pop_elem() and bpf_map_peek_elem()). Either may be passed as a PTR_TO_STACK, which reaches check_stack_range_initialized() through check_helper_mem_access(), so both must be treated as raw. Extend arg_type_is_raw_mem() to match the map value case as well; otherwise check_raw_mode_ok() would not record the regno for it and an uninitialized stack buffer passed to those helpers would be wrongly rejected for programs without CAP_PERFMON. No functional change intended. This patch does not enable raw_mode memory access for kfunc (i.e., uninit stack will not be allowed to be passed to kfunc for unprivileged programs). Existing kfuncs with arguments tagged with __uninit are either priviledged or dynptr kfuncs, which take another path to make sure the access is checked by check_mem_access(). Signed-off-by: Amery Hung <ameryhung@gmail.com> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/bpf/20260715064047.1793790-3-ameryhung@gmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-07-15bpf: Remove dynptr check in check_stack_range_initialized()Amery Hung1-25/+0
For a MEM_UNINIT ("raw mode") helper argument, check_stack_range_initialized() open-coded a scan that rejected any STACK_DYNPTR slot in the range with "potential write to dynptr". This duplicated, and was stricter than, the handling that runs when the buffer is actually marked initialized. check_helper_call() later replays the write byte by byte via check_mem_access(), which goes through destroy_if_dynptr_stack_slot(), which rejects overwritting a referenced dynptr. Therefore drop the redundant scan and rely on check_mem_access(). Signed-off-by: Amery Hung <ameryhung@gmail.com> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/bpf/20260715064047.1793790-2-ameryhung@gmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-07-15liveupdate: Remove redundant INIT_LIST_HEAD in luo_session_allocHongfu Li1-1/+0
luo_session_alloc() calls INIT_LIST_HEAD(&session->file_set.files_list) followed immediately by luo_file_set_init(), which also performs INIT_LIST_HEAD() on the same list head. Remove the duplicate call. Signed-off-by: Hongfu Li <lihongfu@kylinos.cn> Reviewed-by: Pratyush Yadav <pratyush@kernel.org> Link: https://patch.msgid.link/20260714074056.95335-1-hongfu.li@linux.dev Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
2026-07-14tracing/probes: Eliminate recursion in parse_probe_arg()Masami Hiramatsu2-133/+236
To avoid potential stack overflows on limited kernel stacks, convert parse_probe_arg() from a recursive function into a loop-based implementation with a simple local state stack. Since recursion is eliminated using a loop with a fixed-size stack in the context, this restricts the dereference nesting depth. The maximum nesting depth of dereferences is now restricted to the same limit as typecasts (TRACEPROBE_MAX_NESTED_LEVEL, which is 8) and reports the same TOO_MANY_NESTED error. Update ftrace selftests to reflect this restriction and simplify the checks. Note that this change slightly alters the behavior of nested dereferencing in fetcharg. Previously, dereferencing without BTF allowed for up to 14 levels of nesting, whereas dereferencing with BTF was limited to 3 levels. With this change, the nesting depth is now limited to 8 levels in both cases. Link: https://lore.kernel.org/all/178399141396.27810.5390060618628718661.stgit@devnote2/ Assisted-by: Antigravity:gemini-3.5-flash Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
2026-07-14tracing/probes: Extend max length of argument stringMasami Hiramatsu4-4/+5
To support BTF argument parsing (such as accessing fields within nested structures via typecasting), the maximum argument string length needs to be extended. Extend MAX_ARGSTR_LEN from 63 to 255. Since MAX_ARGSTR_LEN was previously reused to format command heads in trace_*probe_match_command_head() functions, introduce a dedicated MAX_COMMON_HEAD_LEN (63) macro for matching command heads and switch these functions to use the new macro. Link: https://lore.kernel.org/all/178399140457.27810.11387684872148824707.stgit@devnote2/ Assisted-by: Antigravity:gemini-3.5-flash Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
2026-07-14tracing/probes: Sort ERRORS list in trace_probe.h alphabeticallyMasami Hiramatsu1-80/+80
Sort the C-macro ERRORS list alphabetically in trace_probe.h to make it easier to find and maintain error entries. Link: https://lore.kernel.org/all/178399139516.27810.14930549550788208142.stgit@devnote2/ Assisted-by: Antigravity:gemini-3.5-flash Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
2026-07-14tracing/probes: Refactor parse_probe_arg()Masami Hiramatsu1-126/+174
Decompose parse_probe_arg() by extracting register, memory/symbol, dereference, immediate, and default BTF/CPU parsing handlers into dedicated static helper functions (parse_probe_arg_register, parse_probe_arg_mem_symbol, parse_probe_arg_deref, parse_probe_arg_imm, and parse_probe_arg_default). This modularizes the recursive argument parser and improves readability. Link: https://lore.kernel.org/all/178399138581.27810.9471730417467607229.stgit@devnote2/ Assisted-by: Antigravity:gemini-3.5-flash Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
2026-07-14tracing/probes: Refactor parse_probe_vars()Masami Hiramatsu1-97/+140
Decompose parse_probe_vars() by extracting retval, stack, current task struct, and function argument parsing logic into dedicated static helper functions (parse_probe_var_retval, parse_probe_var_stack, parse_probe_var_current, and parse_probe_var_arg). This simplifies parse_probe_vars() and improves its readability. Link: https://lore.kernel.org/all/178399137612.27810.14869178899276413372.stgit@devnote2/ Assisted-by: Antigravity:gemini-3.5-flash Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
2026-07-14tracing: fprobe: Remove __packed from generic __fprobe_headerMarkus Schneider-Pargmann (The Capable Hub)1-1/+1
fp pointer and unsigned long have the same size on all relevant architectures that build Linux. Furthermore this struct is only used in architectures that do not set ARCH_DEFINE_ENCODE_FPROBE_HEADER which is set only for 64bit architectures (apart from LoongArch). Both fields are aligned on these architectures so the struct with __packed and without it are the same. Remove the __packed as it is unnecessary. [Masami: Removed Fixes tag because this is not fixing any problem.] Link: https://lore.kernel.org/all/20260428-topic-fprobe-packed-v7-1-v1-1-9abc9b866b4c@baylibre.com/ Signed-off-by: Markus Schneider-Pargmann (The Capable Hub) <msp@baylibre.com> Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
2026-07-14tracing/probes: Add this_cpu_read() and this_cpu_ptr() dereference method to fetchargMasami Hiramatsu (Google)4-45/+134
When tracing the kernel local variables, sometimes we need to get the CPU local variables. To access it, current simple dereference is not enough. Thus, introduce a special this_cpu_read() dereference to access per-cpu variable for the current CPU (accessing other CPU variable may race with updates on other CPUs). Also this_cpu_ptr() is for accessing per-cpu pointer. Those are working as same as the kernel percpu macro. Link: https://lore.kernel.org/all/178271367680.1176915.4711734074448973989.stgit@devnote2/ Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
2026-07-14tracing/probes: Add $current variable supportMasami Hiramatsu (Google)4-3/+42
Since we can use the BTF to cast value to a structure pointer type, it is useful to introduce "$current" special variable support to fetcharg. User can define a fetcharg to access current task_struct properties using BTF info. e.g. $current->cpus_ptr Link: https://lore.kernel.org/all/178271366709.1176915.15320906169981578568.stgit@devnote2/ Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
2026-07-14tracing/probes: Support field specifier option for typecastMasami Hiramatsu (Google)3-57/+121
Add a field specifier option for the typecast. This works like container_of() macro. (STRUCT[,FIELD[.FIELD2...]])VAR This is equivalent to : container_of(VAR, struct STRUCT, FIELD[.FIELD2...]) For example: echo "f tick_nohz_handler next_tick=(tick_sched,sched_timer)timer->next_tick" >> dynamic_events This will trace tick_nohz_handler() with its tick_sched::next_tick which is converted from @timer by contianer_of(tick, struct tick_sched, sched_timer). So, if you enabkle both fprobes:tick_nohz_handler__entry and timer:hrtimer_expire_entry events, we will see something like: <idle>-0 [002] d.h1. 3778.087272: hrtimer_expire_entry: hrtimer=00000000d63db328 f unction=tick_nohz_handler now=3777450051040 <idle>-0 [002] d.h1. 3778.087281: tick_nohz_handler__entry: (tick_nohz_handler+0x4 /0x140) next_tick=3777450000000 Link: https://lore.kernel.org/all/178271365745.1176915.725923927180862257.stgit@devnote2/ Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
2026-07-14tracing/probes: Type casting always involves nested callsMasami Hiramatsu (Google)2-51/+74
This allows type casting to various fetchargs without parentheses by recursively calling parse_probe_arg on the target when type casting is used. For example, this allows the following expressions: - (STRUCT)%REG->FIELD - (STRUCT)$stackN->FIELD - (STRUCT)@SYM->FIELD Note that @SYM+/-OFFSET with typecast needs parentheses like: - (STRUCT)(@SYM-8)->FIELD Link: https://lore.kernel.org/all/178271364804.1176915.17600229399446264813.stgit@devnote2/ Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
2026-07-14tracing/probes: Support nested typecastMasami Hiramatsu (Google)3-9/+82
When we hit an open parenthesis right after typecast closing parenthesis, it means we have nested typecast. This allows us to typecast a generic data member in a structure to a pointer to another structure. For example, to cast a DATA_MEMBER of VAR structure to STRUCT pointer and get MEMBER value. (STRUCT)(VAR->DATA_MEMBER)->MEMBER Also, we can nest typecast. (STRUCT1)((STRUCT2)$ARG->FIELD2)->FIELD1 Currently the max nest level is limited to 3. This also allows user to use typecasting for registers or stacks on kprobe events. e.g. (STRUCT)(%ax)->MEMBER (STRUCT)($stack0)->MEMBER Link: https://lore.kernel.org/all/178271363855.1176915.16793301788257446529.stgit@devnote2/ Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
2026-07-14tracing/probes: Support typecast for various probe eventsMasami Hiramatsu (Google)3-7/+23
Support BTF typecast feature on other probe events, but only if it is kernel function entry or return, and must use function parameter name or $retval. This means you can do: (STRUCT)PARAM->MEMBER Note: you can not use other variables like $stackN, %reg etc. That needs nesting support. To support other probe events, we just need to use last_struct type when we find a function parameter in parse_btf_arg(). This also updates <tracefs>/README file to show struct typecast. Link: https://lore.kernel.org/all/178271362928.1176915.12235759508786922490.stgit@devnote2/ Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
2026-07-13sched_ext: Add scx_bpf_sub_kill() to evict a child sub-schedulerTejun Heo3-12/+84
A cid-form scheduler can grant caps to and revoke them from its child sub-schedulers but has no way to tear one down. Add scx_bpf_sub_kill() to evict a direct child with a printf-style reason that reaches the child's scx_exit_info. No exit code is taken because the child is a separate scheduler whose exit-code semantics the parent cannot know. The child and its subtree are disabled through the usual async path under a new exit kind, SCX_EXIT_PARENT_KILL. The bstr formatting infrastructure in ext.c is exposed through internal.h with scx_ prefixes so the kfunc, which lives in sub.c, can format the reason. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Replay ecaps notifications suppressed by bypassTejun Heo3-1/+40
scx_process_sync_ecaps() consumes ecaps syncs while the sched is bypassing without delivering ops.sub_ecaps_updated(), leaving reported_ecaps stale. Nothing re-queued a sync when bypass lifted, so a cid whose caps never change again would never be notified. Attach-time initial grants hit this every time: they are consumed during the enable bypass window, so a sched never learned its initial effective caps through the callback. Re-queue a sync for every (sched, cpu) with an undelivered delta at the per-cpu bypass exit in scx_bypass(), next to the idle renotify catch-up. The next balance on the cpu then delivers the pending delta with proper dispatch context. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Route ops.update_idle() to sub-schedulers and re-notify owed schedsTejun Heo6-29/+133
__scx_update_idle() notified only the root scheduler. A sub-scheduler that holds a cid needs that cid's idle state to place and kick on it. Deliver ops.update_idle() to every scheduler that holds SCX_CAP_BASE on the transitioning cid. The root holds every cap, so a real transition always reaches it. Real transitions are not enough on their own. A cid that is already idle when a sub-sched gains baseline access produces no transition, so the new holder would never learn it is idle. The ecaps sync arms a re-notify on the gain, and the next idle pick delivers ops.update_idle() to just that sched, leaving holders that already track the cpu untouched. A matching loss of baseline access drops any pending re-notify. Bypass suppresses ops.update_idle() too, so a cpu that goes idle during a bypass window and stays idle yields no transition to re-deliver on un-bypass. Arm the same re-notify for every sched leaving bypass. The acute case is a child granted cids during its own ops.sub_attach(). The grant lands while the child is bypassed and the notify walk skips it, so on un-bypass it holds cids it never saw go idle. The root is owed the same and is armed through a separate per-rq flag, which keeps this working when sub-schedulers are compiled out. v2: Gate the idle catch-up in pick_task_idle() to avoid a double ops.update_idle(). (sashiko AI) Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Authorize remote-move inserts against the placing schedulerTejun Heo3-15/+25
scx_local_or_reject_dsq() authorizes a local-DSQ insert against the caps of the scheduler doing the insert. On the consume/dispatch paths that is the scheduler running balance_one(), passed down through scx_consume_dispatch_q() and move_local_task_to_local_dsq(), so the check is correct. The remote-move path loses it. move_remote_task_to_local_dsq() re-activates @p on the destination rq through enqueue_task_scx(), which reconstructs the scheduler from the task, i.e. @p's owner. When an ancestor places a descendant's task - e.g. draining a bypassed sub-scheduler - the owner is a sub-scheduler of the placer, so authorizing against the owner checks a narrower cap set and can spuriously reject a task the placer is entitled to run. Carry the placing scheduler across the activate_task() boundary the same way enq_flags already are, via a per-rq field set only for the duration of the re-activation, and have scx_local_or_reject_dsq() authorize against it. The placer's caps are a superset of the owner's, so this admits what the placer may run and keeps rejecting what it may not. v2: Document @sch in move_remote_task_to_local_dsq()'s kerneldoc. (Andrea) Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Gate kicks on SCX_CAP_BASE and preemption on SCX_CAP_PREEMPTTejun Heo4-15/+77
A kick forces a scheduling event on the target cpu, and a preemption also evicts the running task. Gate both on caps. Any kick requires baseline access on the cid, and preempting a task the sub-sched does not own - whether by a SCX_ENQ_PREEMPT insert or a SCX_KICK_PREEMPT kick - requires the new SCX_CAP_PREEMPT. Gating either alone would leave a hole - the weakest cap authorizing preempting kicks, or plain kicks disturbing cpus the kicker has no access to. Preempting the sched's own subtree is always allowed, and the cap extends the right to any task on the cid. PREEMPT implies ENQ, and so ENQ_IMMED. A preempting insert tests the running task under the target rq lock and is rejected and reenqueued unless the victim is in the inserter's subtree or it holds PREEMPT. A migration-disabled task is admitted regardless, but with SCX_ENQ_PREEMPT stripped. Kicks are enforced on the delivery path, where the effective caps can be read coherently under the target rq's lock. A kick from a sub-sched lacking SCX_CAP_BASE on the cid is dropped, and a SCX_KICK_PREEMPT kick without PREEMPT for a task outside the kicker's subtree degrades to a plain reschedule. Unlike the enqueue caps, PREEMPT is checked only at the instant of the insert or kick, never as a standing property of a queued task. v2: Clear SCX_ENQ_PREEMPT on the offline and migration_pending force-admits. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Add the SCX_CAP_ENQ capTejun Heo3-5/+22
Add SCX_CAP_ENQ, which gates inserting tasks onto a cid's local DSQ. Unlike IMMED enqueue, plain enqueues can pile up, so ENQ is the stronger cap and implies ENQ_IMMED. Losing ENQ also triggers the reenq scan. The scan tests each queued task and the running task against the cap each needs via scx_caps_for_task(), so an ENQ-only loss reenqueues plain tasks, evicting a running one, while IMMED tasks, which need only ENQ_IMMED, stay put. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Tie cpu occupancy to SCX_CAP_BASE through the task sliceTejun Heo3-12/+218
A task's slice grants it cpu occupancy - how long it holds its cpu. In a sub-scheduler hierarchy cpu access is delegated through revocable capabilities, so a task's occupancy must follow them. Only its own scheduler sets its slice, and extending the slice is allowed only while that scheduler holds baseline cpu access (SCX_CAP_BASE) on the cpu. Otherwise a scheduler could keep occupying a cpu it has been denied simply by handing out long slices. The cap check reads effective caps, which are coherent only under the task's rq lock, and the kernel decrements the slice under that lock as the task runs, so a running task's slice can be changed only there while a queued task's can be set directly. Make scx_bpf_task_set_slice() apply the slice under the rq lock. Synchronously when the caller already holds it, otherwise by stashing it in the new p->scx.slice_oob, tagged with the scheduler's id so a request that outlived a reassignment is dropped. Whether the caller holds @p's current rq lock is tested with p->scx.runnable_cpu. Revocation is enforced through the same grant. When a cpu's effective caps lose SCX_CAP_BASE, the cap-revoke reenq scan also checks the running task and zeroes its slice to evict it. The scan runs as a balance callback after the pick, so this catches both the task that was running when the revoke landed and a capless task the pick just promoted off the local DSQ. The paths that keep a task on its cpu - holding on to the last runnable task in balance, the ENQ_LAST reinsertion and the slice refill on pick - skip tasks lacking baseline access. A migration-disabled task is exempt, mirroring its capless admission on insert. v4: Test rq ownership with p->scx.runnable_cpu, closing a remote-wakeup TOCTOU. (sashiko AI) v3: Keep a pending out-of-band slice request across refill and preserve. (sashiko AI) v2: Only write slice directly when @p is queued on the held rq. (sashiko AI) Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Track the cpu a task is runnable onTejun Heo1-0/+9
Add p->scx.runnable_cpu, the cpu @p is runnable on, or -1 when it is not. It is stamped as @p joins the runnable_list (set_task_runnable()) and cleared as it leaves (clr_task_runnable()), both under the rq lock. task_cpu() can't answer "is @p on this rq" reliably: a remote wakeup changes it under @p's pi_lock alone, without the source rq lock, so it can read as the locked rq while @p is really elsewhere. runnable_cpu changes only under the rq lock, so a caller holding an rq lock can compare against it to know whether that is @p's current rq. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Route task slice writes through set_task_slice()Tejun Heo1-13/+19
A later change makes set_task_slice() also drop a pending out-of-band slice request, so the BPF-triggered writes to p->scx.slice need to funnel through one place. Introduce set_task_slice() and route those writes through it. update_curr_scx() decrements curr->scx.slice directly for accounting and is left alone. No functional change - the helper only assigns p->scx.slice. v2: Reword the set_task_slice comment to "BPF-triggered writes". (Andrea) Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Assign a unique id to each scheduler instanceTejun Heo2-0/+7
Neither a scx_sched pointer nor its cgroup id uniquely identifies a scheduler instance. A freed sched's memory can be reallocated, and a cgroup can detach one sched and attach another. Add a monotonic, never-reused u64 id. A later patch compares it to drop a slice request that outlived a change of a task's owning scheduler. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Add the SCX_CAP_ENQ_IMMED capTejun Heo4-6/+19
Replace the __SCX_CAP_DUMMY placeholder with SCX_CAP_ENQ_IMMED, which gates inserting IMMED tasks onto a cid's local DSQ. An IMMED enqueue is guaranteed to either get its task running on the cpu at once or hand it back to the scheduler, so IMMED work can never pile up on the cpu's queue and a cpu can be shared across sub-scheds through IMMED access without any of them swamping it. That makes ENQ_IMMED the natural baseline, the minimal cap to make any use of a cpu. SCX_CAP_BASE aliases it so gates on basic cpu access can state the intention instead of naming ENQ_IMMED. Enforcement covers inserts and queued tasks. An insert without the cap is diverted to the reject DSQ, and queued tasks are reenqueued when the cap is lost. scx_bpf_sub_dispatch() skips a child that lacks the cap on the cpu, as its inserts would only be rejected. Vacating the running task on cap loss lands in a later patch. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Add SCX_ENQ_IGNORE_CAPS for in-place restoreTejun Heo3-2/+9
A SAVE/RESTORE requeue re-inserts a running task in place and is immediately followed by set_next_task_scx(). It is not a real scheduling event: the task is already admitted to its cid and must return to the local DSQ unconditionally. scx_caps_for_enq() maps an enqueue to the cap its local-DSQ insert requires. Add SCX_ENQ_IGNORE_CAPS, set it on the RESTORE-in-place branch of enqueue_task_scx(), and have scx_caps_for_enq() require no caps for it, so the cid admission gate never diverts an in-place restore to the reject DSQ. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Add reject DSQ for cap-rejected dispatchesTejun Heo5-9/+231
When a sub-scheduler dispatches a task to a CPU it lacks the required capability on, the task must be rejected rather than allowed to run. Add the machinery for that. Each rq gets a reject DSQ, a kernel-internal holding queue that is never run and that the BPF scheduler cannot reach. An insert that must be refused is diverted there instead of the local DSQ, and a deferred requeue then hands the parked tasks back to the BPF scheduler to re-decide. A cap revoke extends this to already-queued tasks. When the revoke reaches the cpu's effective caps, the cpu scans its local DSQ and reenqueues the tasks that no longer qualify. A migration-disabled task must run on its cpu, so a capless one is admitted anyway and counted in the new SCX_EV_SUB_FORCED_ADMIT event. This is preparation for the actual sub-sched cap enforcement. The divert is wired but inert here. v2: Admit offline-rq and migration_pending inserts to local, not reject. (sashiko AI) Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Generalize local-DSQ handling to rq-owned DSQsTejun Heo1-12/+22
The local DSQ is synchronized by the containing rq lock rather than its own dsq->lock. A later patch adds a second such DSQ. In preparation, factor the "rq owns the lock" test into dsq_is_rq_owned() and rename local_dsq_post_enq() to rq_owned_post_enq(), taking @rq explicitly. No behavior change. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Add sub_ecaps_updated() effective-cap change notifierTejun Heo4-15/+154
A sub-scheduler that gains or loses effective caps on a cpu may want to act on it right away - e.g. place or preempt on a newly usable cpu. The existing ops.sub_caps_updated() doesn't fit as it is delivered asynchronously to scheduling operations and can arrive before the per-cpu effective caps go live. Add ops.sub_ecaps_updated(cid, before, after), a cid-form callback fired from scx_process_sync_ecaps() when a sub-sched's effective caps on a cid change. It runs in dispatch context so the sched can insert, kick or preempt on the cid directly. @before is the caps as of the last delivery. Cpu hotplug rides the same machinery. Going down zeroes each sched's ecaps on the cpu's cid, with queued syncs discarded at consumption while the cpu is inactive. Coming back up queues a sync for every sched. reported_ecaps is kept across the down/up cycle, so the resync fires the callback only if ownership actually changed while the cpu was down. v2: Compute cid below the active-cpu guard; discard queued syncs on !cpu_active(). (sashiko AI) Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Maintain per-cpu effective cap copies for single-read checksTejun Heo5-3/+180
Checking a sched's caps on a cid would need to test several cap bits against caps[] to account for implied caps. Also, caps[] modifications aren't synchronized against scheduling operations on each cpu, which can lead to awkward race conditions. Collect them per cpu instead. caps[] under pshard->lock stays the target configuration. scx_sched_pcpu->ecaps is added, the transposed effective copy: the set of cap bits the sched holds on that cpu which can be accessed with a single read. It is stable under the rq lock. It can also be read locklessly with READ_ONCE(). Grant and revoke only mutate caps[]. They queue a sync request on the target cpu's rq->scx.ecaps_to_sync and kick it, and the cpu recomputes the queued scheds' ecaps from caps[] in balance_one() under its own rq lock. A dying sched runs the sync directly to retire its queued request before freeing. As held references can defer the freeing past the enclosing root scheduler's lifetime, root enable discards leftover sync requests before going live. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Add coalescing sub_caps_updated() notifier for sub-schedulersTejun Heo4-9/+254
Wire up ops_cid.sub_caps_updated() to notify sub-scheds of cap changes. Three constraints shape the design: 1. Static memory. Deliveries use a fixed-size buffer, both for runtime efficiency and so notifications can't be lost under memory pressure. 2. High-frequency updates. Grant/revoke can mutate caps in bursts, and the notifier path must absorb that without amplifying it. 3. Recursive grant/revoke from the callback. A child receiving a notification can call grant/revoke on its own children, which can cascade recursively down its subtree. (1) and (2) lead to coalescing into a fixed payload. Each delivery carries a single (cmask, caps) pair covering every change since the previous one. Direction (set vs cleared) isn't encoded as it doesn't fit in the fixed-size summary. The callback queries scx_bpf_sub_caps() for current state. Only one delivery is in flight per shard. Further changes fold into the same buffer and ship as the next callback, so a shard's callbacks fire in order. (3) leads to deferred delivery. Events accumulate during grant/revoke and are delivered after the shard lock is released. v2: - Request a private stack for ops.sub_caps_updated(). (sashiko AI) - Build cmask_arena_out via scx_cmask_ref, not by re-reading its header. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>