summaryrefslogtreecommitdiff
path: root/tools/sched_ext
AgeCommit message (Collapse)Author
5 daysMerge tag 'sched_ext-for-7.4-fixes' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext Pull sched_ext fixes from Tejun Heo: "This is a big pull for fixes, but much of it was in the works before the merge window. Most of these fixes are in sub-scheduler support, which nests BPF schedulers under a parent that hands them CPUs. It was heavily reworked over recent cycles and is now functionally complete. Porting real schedulers on it drove the latest additions and keeps finding corner cases. For example, once CPUs are shared and can be taken back, the kernel must keep every task moving when its scheduler can't run it or is failing, and those fallbacks interact subtly with each other and with other new core features. - The fallback paths meant to keep a task moving when its scheduler can't run it or is failing could themselves leave it stuck - The stall watchdog could blame a scheduler for time it wasn't responsible for, even taking down all of sched_ext - Sub-schedulers were told late, or not at all, which CPUs they could use - Deferred callbacks could stay queued or be dropped under core scheduling and proxy execution, with a sched/core fix to the duplicate check - Hardening: tracing programs can no longer call kfuncs that could deadlock the CPU" * tag 'sched_ext-for-7.4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext: (34 commits) sched_ext: Reject scx_bpf_sub_grant/revoke() in tracing programs sched_ext: Fix the rescue overload pick ejecting the wrong sub under bypass sched_ext: Fix use-after-free of a NONE rescuee leaving its sched while running sched_ext: Fix a lone IMMED task waiting behind a kept prev sched_ext: Fix queued bypassed tasks stalling when the host loses SCX_CAP_BASE sched_ext: Let the bypass load balancer move tasks homed on other cpus sched_ext: Factor out bypass_lb_move() and insert with the donor DSQ unlocked sched_ext: Fix the bypass load balancer stranding tasks on cpus where the host lacks SCX_CAP_BASE sched_ext: Fix bypassed tasks stalling when the host lacks SCX_CAP_BASE sched_ext: Expire prev's slice in dispatch_one() under bypass sched_ext: Fix a cpu idling after put_prev_task_scx() queues its task on the local DSQ sched_ext: Refuse extending a kernel slice sched_ext: Mark the rescue grant as a kernel slice with SCX_TASK_KERNEL_SLICE sched_ext: Fix a cpu idling with a runnable rescuee sched_ext: Restore a rescuee's slice after ops.stopping() sched_ext: Fix rescue served time disagreeing with the slice under proxy execution sched_ext: Move refill_task_slice_dfl() below apply_slice_vtime() sched_ext: Fix bypassed tasks looping on a host without SCX_CAP_ENQ sched_ext: Fix bypassed tasks stranded by the reenqueue limit sched_ext: Clear holding_cpu where the claim is confirmed ...
7 dayssched_ext: Mark the rescue grant as a kernel slice with SCX_TASK_KERNEL_SLICETejun Heo
In the following patches, bypassed tasks run under rescue when their host lacks SCX_CAP_BASE on the cpu. Under bypass the kernel zeroes the running task's slice at every tick, as it does not trust the scheduler's slices. A rescue grant has to survive that, or it is served a tick at a time with the rescuee sent to the tail of the local DSQ each time. The generic slice handling can't tell a kernel grant from a scheduler's slice. Mark the grant as a kernel slice with SCX_TASK_KERNEL_SLICE, set at rescue admission and cleared when the slice ends. The generic slice handling leaves it alone. The default refill does nothing for it, and the three zeroings go through the new expire_task_slice(), which skips it: - the bypass tick's zeroing of the running task - the eviction of a running task that can't stay on the cpu when bypass lifts - the cap-revoke eviction of a running task Schedulers keep their control. Preemption and scx_bpf_task_set_slice() still apply, and the rescue stays bounded by served time. The sites that recognized the rescuee by identity, the reenqueue scan and put_prev_task_scx()'s reinsert, test the flag instead. scx_task_has_kernel_slice() hides the test behind the scx_has_subs() static key, as only a sub-scheduler's task can carry the flag. The flag's entries join the enum tables in tools/sched_ext. No kernel slice reaches a zeroing until bypassed tasks run under rescue. The cap-revoke eviction skipped the rescuee already, and bypass entry ends an open rescue, so the bypass tick and the eviction at bypass lift see none. The refill is the one behavior change. The pick refills a zero slice only for a task that can stay on the cpu, so it concerns a rescuee whose scheduler holds BASE there. A scheduler may zero such a queued rescuee's slice, and the next pick used to refill it to the default. Now the rescuee runs on the zero slice until the next tick. There put_prev_task_scx() restores the remainder when another task is runnable. When nothing else is runnable, dispatch_one() keeps the rescuee as the last task. The pick then ends its zero slice, which ends the rescue, and refills the default. A scheduler with SCX_OPS_ENQ_LAST skips the keep-last test. scx_rescue_keep() restores the remainder there instead and the rescue goes on. v2: - scx_rescue_admit()'s kerneldoc no longer mentions a served-time snapshot. - The description covers a scheduler with SCX_OPS_ENQ_LAST, whose rescuee dispatch_one() keeps on the remainder. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
7 dayssched_ext: Pack scx_ent_flags' multi-bit fields at the topTejun Heo
The following patches add a flag for a kernel-owned slice to scx_ent_flags. The two 3-bit fields, the task state at bits 8 to 10 and the reenqueue reason at bits 12 to 14, sit right above the single-bit flags, so the new flag would have to take bit 11 or 15, out of sequence with the rest. Pack the fields at the top of the word, below SCX_TASK_CURSOR, the state at bits 25 to 27 and the reason at bits 28 to 30, so that the single-bit flags continue from bit 8. The renumbering changes the values a BPF scheduler reads from p->scx.flags. Nothing in the kernel or the in-tree schedulers hardcodes the numbers. The enum ABI table in tools/sched_ext/include/scx/enums_abi.autogen.h, kept for repairing enum values that a kernel's BTF truncates, is regenerated for the two fields. In the scx repository, scx_eevdf tests SCX_TASK_REENQ_IMMED and SCX_TASK_REENQ_PREEMPTED against SCX_TASK_REENQ_REASON_MASK. Those three names belong in its load-time enum table, so that they follow the running kernel. No behavior change. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
11 daysMerge tag 'mm-stable-2026-10-19-21-33' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull MM updates from Andrew Morton: - "selftests/mm: improve khugepaged coverage" (Kiryl Shutsemau): Give khugepaged a proper workout. Extend the tests to all supported mTHP orders, check exactly which windows collapsed, and make scan completion deterministic. Race collapse against faults, pinning, fork and remap; verify that the contents survive. Add coverage for whole-page-table zaps and memory pressure too. - "selftests/mm: separate GUP microbenchmarking from functional testing" (Sarthak Sharma): Untangle GUP benchmarking from correctness testing. Move the benchmark into tools/mm, add a standalone harness-based GUP selftest, and move shared helpers into tools/lib/mm. Give each tool one job instead of mixing timing measurements with correctness checks. Cover the mapping, pinning and batch-size combinations explicitly. - "mm: Switch device DAX to section-based vmemmap optimization" (Muchun Song): Apply section-based vmemmap optimization to device DAX. Rework the backing metadata layout to save memory while preserving the handling of device memory hotplug and its different alignment and lifetime requirements. - "mm: Introduce section-based vmemmap optimization for HugeTLB" (Muchun Song): Cut the memory consumed by HugeTLB's struct page array with section-based vmemmap optimization. Arrange the metadata so large huge pages need fewer backing pages, while keeping initialization, teardown and the various hugepage configurations straight. - "mm/huge_memory: clean up and decouple the anon and file split helpers" (Kairui Song): Separate anonymous and file-backed folio splitting, which have rather different locking and bookkeeping requirements. Move the work into separate helpers, drop dead checks and tidy swap-cache handling. Fix error paths, including one that could leave a folio frozen. Keep the swap cache cases separate from file-cache splitting. - "mm: Unconditional per-VMA locks and cleanups" (Dave Hansen): Make per-VMA locking unconditional and clean up the old conditional code around it. This removes configuration-dependent plumbing and lets callers depend on one locking model rather than carrying both cases along. - "memcg: remove the v1 soft limit" (Shakeel Butt): Remove the old cgroup v1 memory soft-limit machinery. This has long since been superseded by the newer memory-control interfaces; hauling around a separate reclaim scheme for it no longer buys us much. - "read proc/pid/smaps_rollup under per-vma lock" (Suren Baghdasaryan): Read /proc/PID/smaps_rollup using per-VMA locks where possible, rather than holding mmap_lock across the entire walk. Retain the contention fallback and add tearing tests. This considerably reduces latency when another thread is busy changing its mappings. - "mm/damon: introduce data access-as-a-data attribute" (SJ Park): Teach DAMON to expose memory access observations as data attributes, making them available to the probe and filtering machinery. Extend the interfaces, documentation and tests so the new information can be used rather than merely collected. - "Remove PG_private by using page/folio->private checks instead" (Zi Yan): Get rid of PG_private and use the folio's private pointer to say whether private data is attached. Convert the filesystem users, including erofs, f2fs and md, and clean up the old accessors and flags. There are a few special cases, notably swapcache and hugetlb, which need explicit care. - "mm: make userland page table freeing RCU-safe" (Lorenzo Stoakes): Make freeing userspace page tables safe against RCU readers. Sort out the page-table lifetime and locking rules so walkers cannot stumble over freed tables while mappings are being torn down. - "make unused huge shrinker memcg aware" (Qi Zheng): Make shmem's unused-huge-folio shrinker aware of memory cgroups, so reclaim can find those folios under the right memcg. Wire up the per-memcg tracking and its lifetime rules, and give the shrinklist its own lockdep class to avoid spurious dependency reports. - "mm: Drop pxd_ERROR()" (Anshuman Khandual): Remove the old pxd_ERROR() page-table checks and their architecture-specific baggage. Simplify the common page-table interfaces and callers now that these checks no longer serve a useful purpose. - "memcg: group struct fields by access pattern" (Shakeel Butt): Rearrange memcg's hot and cold fields according to how they're actually accessed. Keep frequently updated counters and their neighboring state from fighting over cachelines and reduce needless cacheline traffic. - "mm/damon/core: fix the size charged for a filter-trimmed region" (Donggeun Yoo): Fix DAMOS quota accounting when a filter trims a monitoring region. Charge only the part left after filtering, not the original region, and add KUnit coverage. Previously the excluded memory could eat into the quota and make schemes run more slowly than requested. - "mm/damon: add kunit and selftests for probes and probe weights" (SJ Park): Add more tests for DAMON probes and their weights, including validation and the results reported to userspace. This is mostly about catching regressions in the newer probe infrastructure before they become harder to diagnose. - "mm: memcontrol: constify the read side of the read side of the memcg API" (Tal Zussman): Mark the read-only parts of the memcg interface const, from folio and lruvec accessors to counters and swap helpers. Most of this is mechanical, but it makes the contracts clearer and lets the compiler catch accidental writes. - "mm/damon/vaddr: support {prep,apply}_probes" (SJ Park): Support the new prepare/apply probe operations in DAMON's virtual-address backend. This brings vaddr monitoring into line with the probe infrastructure and makes the added probe types useful there too. - "mm/mglru: clean up folio counters and flag usage" (Kairui Song): Simplify MGLRU's folio counters and flag handling. Remove redundant accounting paths and make the state transitions easier to follow without changing the intended reclaim policy. - "arch, mm/execmem: resolve confusion about set_direct_map_valid_noflush()" (Mike Rapoport (Microsoft)): Clarify and straighten out the set_direct_map_valid_noflush() interface across architectures and execmem. Make the requested mapping changes and the callers' expectations agree, rather than relying on subtly different architecture behavior. - "mm: zswap: free cold writeback folios promptly" (Alexandre Ghiti): Free zswap writeback folios as soon as their disk write completes. They are cold temporary buffers, so putting them on the LRU only makes reclaim rediscover them later. Extend swap-cache dropbehind and let zswap keep these folios off the LRU altogether. - "mm: gup: cleanup gup_fast call chain" (Aristeu Rozanski): Clean up the GUP-fast call chain and simplify how the fast-path helpers pass their arguments and results around. Keep the page-pin behavior the same while making the call sequence easier to maintain. - "mm: optimize zone-device memmap initialization" (Li Zhe): Speed up initialization of zone-device struct pages. Avoid redundant work when setting up large device-memory ranges, where touching every descriptor can get expensive. - "mm/zswap: shrink zswap_entry via a pool id" (Jianyue Wu): Reduce the size of zswap_entry by storing a compact pool identifier instead of a full pointer. Keep the pool lookup and lifetime handling correct while saving per-entry metadata. - "mm/damon: support access monitoring of hugetlb-backed memory" (Krishna Iyer): Let DAMON monitor hugetlb-backed memory too. Extend the relevant access checks and add coverage so those mappings no longer fall through a hole in the monitoring machinery. - "mm/execmem: fixes and cleanups for the ROX cache" (Mike Rapoport): Tidy execmem's read-only-executable cache and fix its handling of the awkward allocation and release cases. The aim is to make the cache's ownership and permission transitions more predictable. - "zsmallc: remove old object read API" (Sergey Senozhatsky): Drop zsmalloc's old object-read API and move its remaining users to the supported access mechanism. This removes a duplicate interface which we no longer need. - "mm/mempolicy: stop copying state in the interleave paths" (Gregory Price): Stop copying mempolicy state in the interleave paths when a reference to the existing policy will do. This avoids extra work and makes the ownership rules less obscure. - "mm/mglru: speed up inc_min_seq() and fix cold/hot inversions" (Barry Song): Make MGLRU's generation advancement cheaper and fix cases where cold and hot folios end up in the wrong order. Adjust the counter and list handling so reclaim doesn't keep passing over the better eviction candidates. - "mm: Fix MF_DELAYED handling on memory failure" (Lisa Wang): Treat MF_DELAYED as a partially completed memory-failure operation, not an outright failure. Propagate that result correctly through shmem and the generic handler, fix the extra-reference accounting, and add tests for the resulting SIGBUS behavior. - "tools/mm/page_owner_sort: fix --sort, add module filter, improve usage" (Ye Liu): Fix page_owner_sort's --sort handling, add module-based filtering and make the usage output more helpful. This makes the tool less frustrating when tracking down who is holding on to pages. - "mm/damon: move damos filter range arguments validation to core" (SJ Park): Move DAMOS filter range validation into the core, where all callers can share it. Also close the sysfs read-twice races which could pass inconsistent ranges, and add tests for invalid input. - "mm/damon: misc cleanups" (Zenghui Yu): Clean up a collection of small DAMON rough edges in the core, interfaces and tests. No large behavior change here, just simpler code and fewer opportunities for confusion. - "mm/damon: cleanup code, add test cases, and update guidances in docs" (SJ Park): Clean up DAMON's core and interfaces, add missing test cases and bring the documentation into line with the code. These changes should make the newer facilities easier to understand and maintain. - "mm/damon: introduce hugepage_size probe filter" (SJ Park): Add a DAMON probe filter for hugepage size. Let users select a range of folio sizes through sysfs, validate the range and document the new interface, so monitoring can concentrate on memory backed by the desired hugepage sizes. - "selftests/mm: pagemap_ioctl test fixes and cleanups" (Zenghui Yu): Fix some pagemap ioctl test assumptions and clean up their setup and reporting. Make failures point to the operation that went wrong rather than to test harness bookkeeping. - "mm: avoid large folio splits when swap is unavailable" (Johannes Weiner): Avoid splitting large folios merely to attempt swap when no swap space is available. There is little point paying for an expensive split when reclaim cannot actually swap the resulting pages out. - "mm: workingset: fix the shadow node budget under MGLRU" (Hui Zhu): Fix the workingset shadow-node budget with MGLRU enabled. Keep the shadow entries within the intended limits so refault tracking does not quietly consume more metadata than it should. - "selftests/mm: TAP output and global-state fixes" (Song Hu): Fix selftests which produce misleading TAP output or fail to restore global settings after a run. A test ought to leave the system as it found it, particularly when a whole suite follows behind. - "mm: remove page_swap_entry()" (Tal Zussman): Remove page_swap_entry() and convert its remaining users to the folio and swap-entry helpers. Lose an old page-level interface and make the swap paths a little more consistent. - "mm: refactor zonelist constructors and iterators" (Gregory Price): Refactor the zonelist construction and walk helpers to reduce duplicated logic. Keep the allocation ordering rules intact while making it clearer how zones are selected. - "mm: kmemleak: batch the struct page scan" (Breno Leitao): Scan adjacent struct pages in batches instead of taking kmemleak_lock once for every single page. This preserves scan coverage and the lock-hold bound, while cutting overhead substantially on debug kernels. - "mm/damon: misc improvements in tests and documents" (Zenghui Yu): Fix some DAMON selftests which leave kdamond running or fail under Python safe-path mode, and improve the KUnit coverage and documentation. Nothing especially glamorous, but these are worth doing. - "mm/damon: introduce probe_hits_wsum DAMOS core filter" (SJ Park): Add a DAMOS core filter using weighted probe-hit counts. This gives schemes another way to select regions based on what the monitoring probes observed. - "mm/mglru: fix ineffective memory protection for non-kswapd reclaim" (Ridong Chen): Fix MGLRU's memory protection handling for reclaim outside kswapd. The protection settings weren't having the intended effect in these paths, leaving protected memory more exposed than requested. - "mm/damon: improve readability, clarity and test coverage" (SJ Park): Simplify a handful of DAMON core helpers, clarify their behavior and expand test coverage. There are no intended userspace-visible changes in this batch. - "mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func()" (Kefeng Wang): Stop identifying reclaim and compaction workers through the PF_KSWAPD and PF_KCOMPACTD task flags. Use their kthread functions instead and remove the redundant flag plumbing. - "mm/hugetlb: fix surplus accounting and availability checks during demotion" (Longlong Xia): Fix HugeTLB surplus accounting and availability checks when demoting huge pages. Keep the counters and reservation decisions consistent as one huge page turns into several smaller ones. - "mm/damon: add kunit tests for probe_hits handling and probe params validation" (Jason Angelov): Add KUnit tests for DAMON probe-hit handling and invalid probe parameters. These cover edge cases that were too easy to miss in ordinary monitoring tests. - "mm/damon: fix misc bugs in kunit, quota goals and sysfs refresh_ms" (SJ Park): Fix a few DAMON bugs in KUnit tests, quota-goal handling and the sysfs refresh interval. Small fixes, but the incorrect results and control behavior were real. - "mm: zswap: optimize zswap invalidate and store" (Kefeng Wang): Simplify zswap's invalidate and store paths to avoid avoidable lookups and work. Keep the entry lifetime rules intact while making those frequent operations cheaper. - "mm: replace custom ratelimiting logic" (Pedro Falcato): Replace hand-rolled MM rate limiting with the common kernel helpers. There is no need to maintain another local version of the same mechanism. - "mm/vmalloc: minor cleanups" (Ye Liu): Tidy some vmalloc initialization and reporting code, and pull duplicated vmap-area insertion work into a helper. No functional changes are intended. - "mm/mglru: clean up isolate_folios for readability and clarity" (Ridong Chen): Clean up MGLRU's isolate_folios() so the decisions are easier to read and verify. Keep reclaim behavior unchanged while removing unnecessary twists in the control flow. - "Catch automatic storage in IDA and Maple Tree definitions" (Yury Norov): Catch IDA and maple-tree definitions placed in automatic storage where the lifetime rules are wrong or easy to get wrong. Add checks so such mistakes are harder to slip through unnoticed. - "mm, swap: some random fixes and cleanups" (Kemeng Shi): Fix and simplify a few unrelated swap paths, removing redundant work and tidying up error handling. A small collection of things which were better fixed than left lying around. - "mm/page_io: folio conversion cleanups" (Tal Zussman): Finish some page-to-folio conversions in swap I/O, removing obsolete wrappers and using folio operations consistently. The I/O behavior is intended to remain the same. - "mm/swap: skip empty clusters in the swapoff scan" (Youngjun Park): Skip empty swap clusters during swapoff instead of walking slots which have nothing to release. This avoids pointless work on sparsely used swap devices. - "mm: trace: decode architecture-specific VMA flags" (Meijing Zhao): Teach the VMA trace output to decode architecture-specific flags, rather than leaving them as unexplained bits. That should make tracing a good deal more useful when debugging unusual mappings. - "mm, swap: don't spin on a bad swap entry" (Breno Leitao): Stop repeatedly retrying a swap entry which is already known to be bad. Make the error path terminate cleanly instead of wasting CPU chasing an entry that cannot be used. - "mm/page_isolation: fix UBSAN shift-out-of-bounds in isolate_single_pageblock" (Qi Xi): Fix an out-of-range shift in isolate_single_pageblock() and tighten its associated boundary handling. UBSAN found the issue; the result should be more robust pageblock isolation. - "mm: khugepaged: fix tracepoint UAF" (Vernon Yang): Fix a use-after-free in khugepaged tracepoint handling. Make sure the information recorded by tracing stays valid for as long as the trace event needs it. - "mm/damon: fix DAMOS bugs in core, paddr and vaddr" (SJ Park): Fix several DAMOS problems across the core and physical- and virtual-address backends. The changes close error cases and bring the implementations back into agreement. - "mm/hugetlb_cgroup: move the per-node usage along with the folio" (Hongfu Li): Move HugeTLB per-node usage accounting when folios migrate between nodes or are reparented to another cgroup. Otherwise numa_stat can retain stale charges and even underflow when the folio is freed. - "docs/core-api: memory-allocation: add k[mz]alloc_obj() and clarify kmalloc" (Mike Rapoport): Document the typed k[mz]alloc_obj() allocation helpers and clear up some kmalloc guidance. Make it easier for callers to choose the right interface. - "selftests/mm: Validate selections and scope memfd_secret setup" (Tianyi Chen): Check selftest selections before running and confine memfd_secret setup to the cases that actually need it. Avoid confusing failures caused by the test harness itself. - "mm/damon: move zero damos quota target_value handling to the core layer" (SJ Park): Handle a zero DAMOS quota goal target in the core rather than making each user of the interface invent its own rule. Keep quota decisions consistent across callers. - "mm/damon: Introduce a huge page collapsing mechanism using auto tuning" (Asier Gutierrez): Add an auto-tuned DAMON mechanism for collapsing huge pages. Use monitoring feedback to decide when collapse is worthwhile rather than forcing one fixed policy onto every workload. - "kmemleak: fix stale documentation and raise the verbose default" (Breno Leitao): Bring the kmemleak documentation up to date and require a third confirming scan before verbose kernels print a suspected leak. The extra scan helps suppress transient false positives in noisy debug builds. - "mm/memory: improve insert_pages() error handling" (Avi Weiss): Tighten insert_pages() error handling so partial failures are reported and cleaned up consistently. The caller should not have to guess how far the operation got. - "mm/damon: allow NULL or unstarted damon_ctx parameter for damon_call()" (SJ Park): Make damon_call() handle NULL and not-yet-started contexts safely. Simplify the rules for callers and avoid an indefinite wait on an invalid state. - "mm/damon: introduce pgidle_set probe filter type" (SJ Park): Add a pgidle_set DAMON probe filter, giving monitoring users another way to select pages by their idle-tracking state. Wire it through the filter interfaces and tests. - "mm/damon/core: remove unused helper functions" (Cheng-Han Wu): Remove DAMON core helpers which no longer have callers. Keep the API surface smaller rather than retaining dead code just in case. - "mm: stop calling pmd_folio() on special PMDs" (Gregory Price): Avoid calling pmd_folio() on special PMD mappings that have no struct page. The old assumption could fault in procfs walkers; use the normal-folio checks and handle those mappings properly. - "mm: remove three unused helpers from mm.h" (Tal Zussman): Remove three unused helpers from mm.h. Fewer obsolete interfaces for the next person to stumble over. - "mm/damon: improvements in efficiency, error handling, documents" (Liew Rui Yan): Skip needless DAMOS quota work once the quota is full, propagate a missing sysfs error and tidy a couple of comments. The ignored error could make a monitoring-start request appear successful when it wasn't. - "docs/mm/damon/design: add explanation of nr_snapshots" (Liew Rui Yan): Explain DAMON's nr_snapshots accounting in the design documentation and straighten out the associated terminology. Make it clearer what users should expect from that counter. - "selftests/cgroup: fixes for test_zswap on single core VM" (Wilson Felipe Pereira): Fix two test_zswap failures on single-CPU VMs. Wait for the exiting child's cgroup to become unpopulated before reconfiguring it, and avoid another test assumption which breaks under constrained scheduling. - "docs/ksm: fix advisor documentation and comment" (Jinjiang Tu): Correct the KSM advisor documentation and a misleading code comment. Keep the description aligned with how the advisor actually works. - "Fix bugs in HugeTLB allocation when mem_cgroup_charge_hugetlb() fails" (Ackerley Tng): Fix HugeTLB allocation cleanup when the memcg charge fails. Make sure failure exits undo what was allocated rather than leaving stale accounting or resources behind. - "mm, memcg: fix memory.peak reset clobbering other fds' watermark" (Ridong Chen): Fix memory.peak reset handling so resetting one file descriptor doesn't overwrite the watermark kept for another. Keep those per-open measurements independent as intended. - "mm: reject zone device folios in more folio walkers" (Gregory Price): Reject zone-device folios in page walkers that cannot safely handle them. Extend the existing checks rather than assuming every folio has ordinary system-memory backing. - "percpu: remove code with no effect" (Sang-Heon Jeon): Remove a few pieces of percpu code which no longer do anything. There is no reason to keep maintaining dead paths. * tag 'mm-stable-2026-10-19-21-33' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (539 commits) mm: shmem: assign a lock class to the unused huge shrinklist mm: vmscan: put rotation-missed folios at the LRU tail mm: kmemleak: scan the struct page array in MAX_SCAN_SIZE batches mm: kmemleak: move the struct page scan into a helper mm/damon: document that a zero sample_interval is accepted mm/damon: fix typos in comments mm/damon/sysfs: propagate damon_call() error in turn_damon_on mm/damon/core: skip quota score setup when the quota is full mm/damon/tests/core-kunit: test the size charged for a filter-trimmed region mm/damon/core: charge only the part of a region the filter left mm: disallow raw PFN mappings of huge/shared zeropage selftests/mm: zap whole PTE tables in the khugepaged race harness selftests/mm: add memory-pressure threads to the khugepaged race harness selftests/mm: race the collapse of windows with holes selftests/mm: add khugepaged race harness selftests/mm: check that one khugepaged pass collapses one window selftests/mm: run every supported collapse order by default selftests/mm: cover a shared-source collapse write race selftests/mm: parameterize the mixed-source collapse case by source order selftests/mm: add order-parameterized khugepaged collapse cases ...
2026-10-19sched_ext: Report the ecaps loss when a cpu goes offlineTejun Heo
When a cpu goes offline, a sub-scheduler's effective caps on its cid are cleared, but neither the sub-scheduler nor its parent is notified. The sub-scheduler keeps treating the cid as usable, and the parent can't act on the loss, e.g. reset the cpuperf target. Report the loss before the root's ops.cpu_offline() and the regain after its ops.cpu_online(). The zeroing at offline was the last change to a sched's ecaps outside a delivery, so they now change only with one. Syncs on an inactive cpu are processed instead of discarded, and the reseed reschedules the cpu itself, as they got no resched when queued. Suspend and hibernation now report their cpu downs and ups as well. This is temporary, and a later patch leaves them out. Two things need care. A cpu going down marks a sync for each sub-scheduler, and its hotplug thread waits until each marked sync has been processed. The cpu's own ext picks process them, and the ext server is started in case a fair task holds the cpu. Only the marked syncs count, so a flood of changes on the cid can't hold up the hotplug. The detach report reaches only active cpus. It holds off cpu hotplug, so a cpu it skips has reported its loss as it went down, and no unreported loss is left to drop. Drop the cpuperf reset from scx_qmap's ops.sub_detach(), as its ops.sub_child_ecaps_updated() now resets the targets on the loss reports. v2: Reschedule from the irq work and document the regain order. v3: Pack nr_ecaps_offline with kick_sync_pending to avoid a hole (Andrea). Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-10-17sched_ext: scx_qmap: Also re-enqueue stranded tasks with ↵Tejun Heo
scx_bpf_dsq_reenq_task() scan_shared_dsq() rescues a task stranded on SHARED_DSQ or HIGHPRI_DSQ by moving it to the rescue path with scx_bpf_dsq_move(). For a task with an odd pid, mark it with scx_bpf_dsq_reenq_task() instead, which sends it back through qmap_enqueue() and its rescue, so that both kfuncs are exercised. scan_shared_dsq() runs from qmap_dispatch() and from the monitor timer, so the kfunc can be called both with the dispatch rq locked and with no rq lock held. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-10-17sched_ext: Add scx_bpf_dsq_reenq_task() to re-enqueue single tasks from a ↵Tejun Heo
DSQ iteration scx_bpf_dsq_reenq() re-enqueues a whole DSQ, but a scheduler that loses the cpus serving a DSQ, such as a sub-scheduler after a cap revoke, needs only the stranded tasks placed again. Add scx_bpf_dsq_reenq_task(), which marks a task from a DSQ iteration. When the iteration ends, the DSQ's deferred re-enqueue walk is scheduled once and re-enqueues only the marked tasks. The kfunc locks the task's rq and the DSQ like scx_bpf_dsq_move() and is callable from the same contexts. The mark is cleared when the task leaves the DSQ, so a task consumed before the walk is not re-enqueued. An iteration's DSQ can be destroyed before the iteration ends, so schedule_dsq_reenq() now skips a destroyed DSQ instead of aborting the scheduler. scx_bpf_dsq_reenq() racing scx_bpf_destroy_dsq() takes the same path. Declare the kfunc for the tools and add a compat probe. v2: Note in the kerneldoc that another iteration's re-enqueue may take a marked task early, and that a task on another scheduler returns false (Andrea). Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-10-14sched_ext: Add SCX_ECODE_RSN_CGROUP_OFFLINE to user_exit_info.hTao Cui
The kernel-side scx_exit_code enum gained SCX_ECODE_RSN_CGROUP_OFFLINE in ebeca1f930ea ("sched_ext: Introduce cgroup sub-sched support"), which exits a scheduler when its cgroup goes offline, but the tools-side user_exit_info.h was not updated. Userspace cannot decode exit codes carrying this reason. Add the missing enum value. Signed-off-by: Tao Cui <cuitao@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-10-09sched_ext: scx_qmap: Reset a child's cpuperf targets once its PERF revoke ↵Tejun Heo
takes effect A child that ran a cid at a low cpuperf target leaves the target there when PERF is revoked, since the kernel resets targets only at root enable. Reset the target from ops.sub_child_ecaps_updated() once the revoke is in effect. A detach reports nothing, so ops.sub_detach() resets the child's cids, and the pool unless another child holds it. Count the deliveries in the hier stats. v2: Reset from ops.sub_detach() for a detaching child's cids. v3: Skip the pool at detach while another child holds it (Andrea Righi). Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-10-06mm: replace PF_KCOMPACTD flag with kthread_func() checkKefeng Wang
PF_KCOMPACTD was introduced by commit ce6d9c1c2b5c ("NFS: fix nfs_release_folio() to not deadlock via kcompactd writeback") so nfs_release_folio() could detect kcompactd context and skip writeback. The flag is only consumed by current_is_kcompactd(), whose sole caller is nfs_release_folio(). Replace the flag-based check with kthread_func(current) == kcompactd, freeing the 0x00010000 PF flag bit. Link: https://lore.kernel.org/20260902131653.1338227-5-wangkefeng.wang@huawei.com Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Acked-by: Shakeel Butt <shakeel.butt@linux.dev> Acked-by: Zi Yan <ziy@nvidia.com> Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org> Reviewed-by: David Hildenbrand (Arm) <david@kernel.org> Cc: Brendan Jackman <brendan.jackman@linux.dev> Cc: Carlos Maiolino <cem@kernel.org> Cc: Christian Brauner <brauner@kernel.org> Cc: Christoph Hellwig <hch@lst.de> Cc: "Darrick J. Wong" <djwong@kernel.org> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Suren Baghdasaryan <surenb@google.com>
2026-10-06mm: replace PF_KSWAPD flag with kthread_func() checkKefeng Wang
The preceding commits removed the last consumer that propagated PF_KSWAPD beyond kswapd itself (XFS btree split worker inheritance). The only remaining setter of PF_KSWAPD is kswapd(), and every current_is_kswapd() caller only needs to check whether the current task *is* the kswapd thread, not whether it inherited the flag. Replace the flag-based test with kthread_func(current) == kswapd, freeing the 0x00020000 PF flag bit. Link: https://lore.kernel.org/20260902131653.1338227-4-wangkefeng.wang@huawei.com Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Acked-by: Shakeel Butt <shakeel.butt@linux.dev> Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org> Acked-by: Zi Yan <ziy@nvidia.com> Cc: Brendan Jackman <brendan.jackman@linux.dev> Cc: Carlos Maiolino <cem@kernel.org> Cc: Christian Brauner <brauner@kernel.org> Cc: Christoph Hellwig <hch@lst.de> Cc: "Darrick J. Wong" <djwong@kernel.org> Cc: David Hildenbrand <david@kernel.org> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Suren Baghdasaryan <surenb@google.com>
2026-10-06sched_ext: scx_qmap: Show actual cid use per participantTejun Heo
qmap's hier stats show how much cid-time the partition handed each participant, not how much of it was used. Track the sched running on each cid from ops.sub_cid_sched_updated() and charge the intervals to the participant, then print the use next to the allocation. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-10-06sched_ext: scx_qmap: Size the cid range buffer for large machinesTejun Heo
The hier rows' cid range buffer holds 128 characters. When no two consecutive cids share an owner, which SMT siblings numbered far apart produce, every cid prints on its own and the list is cut off with "...". Size the buffer for that worst case at the build's cpu cap, off the stack. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-30sched_ext: Introduce scx_bpf_cgroup_nr_cpus()Andrea Righi
Hierarchical BPF schedulers may need to know how many CPUs a cgroup can run on when distributing group-wide weights. For example, fair's group share calculation scales a group's weight by the smaller of its estimated runnable task count and the number of CPUs in its effective cpuset. Without that count, a BPF scheduler can only use the machine-wide CPU count and may give a group confined to a few CPUs excessive shares. A task's effective affinity can include per-task restrictions, so it cannot reliably represent the group's cpuset. Reading the cpuset directly from BPF would require CO-RE access to private cgroup and cpuset structures, including inherited cpuset resolution, making the approach fragile across kernel versions. Add scx_bpf_cgroup_nr_cpus(), which returns the same count fair uses through cpuset_num_cpus(). The count is independent of CPU or CID numbering, so the kfunc is available to both cpu-form and cid-form schedulers from any context. Also add a compat wrapper which falls back to nr_cpu_ids on older kernels. Signed-off-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-30sched_ext: Sync tools autogen enum headers from the scx repoTejun Heo
Sync the four autogen enum headers with the scx repo at c9b90b3ad3d0 ("scheds/include: Sync with kernel sched_ext/for-7.4 (c6fe97c34a1a)"). The enum definition and ABI tables pick up the enumerators the kernel gained since the last sync. The two lookup tables are taken verbatim from scx's copies so the files stay identical: their task state lookups move from the removed scx_task_state to scx_ent_flags, where 7203d77d6e04 ("sched_ext: Simplify task state handling") put the states, and until now resolved to zero. The only entry the kernel copy gains is SCX_RQ_BAL_KEEP, which scx keeps for older kernels and which zero-fills here. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-30sched_ext: Sync common and compat headers from the scx repoTejun Heo
Sync cid.bpf.h, common.bpf.h, compat.bpf.h and compat.h with the scx repo at c9b90b3ad3d0 ("scheds/include: Sync with kernel sched_ext/for-7.4 (c6fe97c34a1a)"), which accumulated the following since the last sync: - cid.bpf.h grew the cmask helpers the cid-form schedulers use: fill, empty and end tests, unchecked and word-level access, distribute picks over an arena rotor indexed by cid, range set and clear, and three-operand and, or and andnot that report whether the result is empty. Its word loops walk with bpf_arena_for() and its bit helpers take the fetching atomics when the loader's probe finds the JIT lowers them. - The prolog probe's default now makes is_migration_disabled() over-report, which errs toward local-only dispatch instead of crashing, and the cid-form open macros repoint the probe at bpf_scx_reg_cid(), which cid-form schedulers register through. - scx_bpf_kick_cid() and scx_bpf_cidperf_set() changed their return types without being renamed, so compat.bpf.h declares both flavors of each and lets the kernel pick, the way scx_bpf_dsq_insert() is handled. - A macro supplies scx_bpf_cid_topo()'s size argument from the output buffer, TRAILING_OVERLAP() embeds a struct that ends in a flexible array together with its storage, bpf_arena_for() walks a range in a form the verifier converges on, and features.bpf.h carries the kernel feature bits the loader probes before load. const-defs.h holds the per-architecture cacheline size that cid.bpf.h aligns its rotor slots to. scx_qmap already used the cmask helpers, and the three-operand forms of cmask_and() and cmask_andnot() had not reached its copy of cid.bpf.h, so tools/sched_ext no longer built against scx's headers. Its five calls take the three-operand form now, with the copy-then-operate pairs folded into one call each. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-28sched_ext: scx_qmap: Add proxy execution supportAndrea Righi
Add a -X option to opt scx_qmap into queueing mutex-blocked tasks for proxy execution. Without the option, SCX_OPS_ENQ_BLOCKED remains clear and mutex waiters block normally. With -X, blocked donors are passed to qmap_enqueue() with SCX_ENQ_BLOCKED. When scx_qmap receives a blocked donor, select a cid allowed by the task and held by qmap, preferring its current cid. Dispatch the donor to that cid's local DSQ with a fresh slice and SCX_ENQ_PREEMPT, adding SCX_ENQ_IMMED when the cid is time-shared. This places the donor at the head of an eligible DSQ and requests an immediate reschedule, allowing the core proxy-exec path to run the mutex owner using the donor's scheduling context as soon as the donor is selected. Partition ownership can change concurrently with enqueue, so the self-cid intersection can disappear between the initial check and cid selection. Validate the selected cid before indexing per-cid state or constructing a local DSQ id, and fall back to rescue placement if the intersection has disappeared. The blocked policy is intentionally unfair and can strongly prioritize tasks using contended mutexes, but scx_qmap is a demo scheduler and such aggressive behavior makes proxy-exec support easy to observe. Count all blocked dispatch attempts in nr_enq_blocked and report their per-interval delta. Acked-by: John Stultz <jstultz@google.com> Signed-off-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-28sched_ext: Delegate proxy donor admission to BPF schedulersAndrea Righi
Proxy execution keeps a mutex-blocked donor runnable so that its scheduling context can execute the mutex owner. Define SCX_OPS_ENQ_BLOCKED as the admission contract for retained donors. Schedulers without the flag block EXT donors normally. Schedulers with the flag continue to own blocked donors and receive them through ops.enqueue() with SCX_ENQ_BLOCKED, allowing BPF to choose their DSQ, CPU and ordering. After BPF dispatches a donor, proxy execution may move its context to the rq of the mutex owner. This move is distinct from BPF placement: proxy_set_task_cpu() changes task_cpu() while preserving the donor's pre-proxy CPU in wake_cpu as the starting point for normal wakeup placement. A proxy-migrated donor returns through the full wakeup activation path when the mutex is released. Do not carry a retained proxy session across BPF scheduler ownership changes. Before root activation, parent-to-child takeover, rehome or punt, fully deactivate a retained donor unconditionally. The incoming scheduler then starts with clean task state and applies its admission policy the next time the task blocks. A retained donor can wake through ttwu_runnable() without another enqueue_task_scx() call. Use WF_TTWU_RQ to identify this path, where the wakeup skipped activation and enqueueing. wakeup_preempt_scx() requests dispatch reconsideration after is_blocked is cleared. A full wakeup activation has already enqueued the task and does not need another reschedule. Blocked-donor enqueueing takes precedence over the exiting and migration-disabled local-DSQ fallbacks, so that an opted-in scheduler sees every eligible donor request. Co-developed-by: John Stultz <jstultz@google.com> Signed-off-by: John Stultz <jstultz@google.com> Signed-off-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-28sched_ext: Handle proxy-exec races in remote DSQ transfersAndrea Righi
Without proxy execution, the DSQ lock and holding_cpu handshake ensure that a task cannot be dequeued or start running during an rq-lock handoff without clearing holding_cpu. Proxy execution is an exception: a task can start physically executing as a lock owner while its scheduling context remains on a DSQ; its on-CPU or migration-disabled state can therefore change without clearing holding_cpu. Recheck these states after acquiring the source rq lock. If the transfer can no longer proceed, park the task on the source rq's reject DSQ and reenqueue it through its owning scheduler. This preserves the BPF scheduler's placement policy and keeps descendant tasks within their sub-scheduler's cap grants. Queue a deferred drain for every rejection. If a drain finds a proxy-rejected task still running or donating, leave it parked and record a retry request on the rq. scx_proxy_reenqueue_retry() consumes the request and schedules another drain when proxy state changes. Without this change and proxy execution enabled, stress-ng --pipeherd can trigger this race and migrate an active execution context, leading to sleeping-while-atomic warnings and subsequent lockdep corruption. This is a preparatory change to support proxy execution with sched_ext. Suggested-by: Tejun Heo <tj@kernel.org> Signed-off-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-28sched_ext: Fix ops.running/stopping() pairing for proxy-exec donorsAndrea Righi
With proxy execution, pick_next_task() can select a blocked task as the scheduling context before find_proxy_task() resolves the execution context. From the BPF scheduler perspective, that donor is running while its scheduling context drives the lock owner; ops.tick() and other accounting must therefore remain enclosed by a matching ops.running()/ops.stopping() session. In this scenario, the session boundaries do not always match physical task switches. Keep the "running" session open when the same donor continues on the same CPU. When proxy execution migrates a donor's scheduling context to another CPU, end its running session on the source CPU and start a new session on the destination CPU only after proxy resolution succeeds. This prevents a failed resolution from exposing a provisional ops.running() event. Track these sessions with a new SCX_TASK_RUN_TRACKED flag. The explicit running-state tracking is also required by later donor-based accounting: it prevents an EXT owner executing for a non-EXT donor from being treated as the active EXT scheduling context when it is dequeued. This is a preparatory change for enabling proxy execution together with sched_ext. Acked-by: John Stultz <jstultz@google.com> Signed-off-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-28tools/sched_ext: Add SCX_OPS_OPEN_OPTS for schedulers using open optsFuyu Zhao
Add SCX_OPS_OPEN_OPTS() and SCX_OPS_CID_OPEN_OPTS() to allow sched_ext schedulers to pass bpf_object_open_opts when opening BPF skeletons. This allows sched_ext schedulers using open opts to retain the existing compatibility handling instead of bypassing it. Signed-off-by: Fuyu Zhao <zhaofuyu@vivo.com> Reviewed-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-26sched_ext: Merge branch 'for-7.3-fixes' into for-7.4Tejun Heo
Pull to receive 94480606a677 ("sched_ext: Add a size argument to scx_bpf_cid_topo() so struct scx_cid_topo can grow") for the upcoming cluster level. Conflicts: kept both declarations where 5cadf7545cc6 ("sched_ext: Add a CID NUMA node lookup kfunc") added one next to the changed scx_bpf_cid_topo() line, and pointed 29871903f3a3 ("sched_ext: Don't deliver duplicate ops.cgroup_set_idle() for same value") at the renamed tg->scx.sched_idle. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-26sched_ext: Add a size argument to scx_bpf_cid_topo() so struct scx_cid_topo ↵Tejun Heo
can grow scx_bpf_cid_topo() copies struct scx_cid_topo into a buffer the BPF program sized from its own vmlinux.h while the verifier sizes the write from the running kernel's BTF. The struct may grow and each growth then breaks every scheduler built against the older layout, rejected at load or written past its buffer. This is the usual hole for a struct handed to BPF, closed elsewhere with a size argument, and it was missed here. Take the buffer size, copy the smaller of it and the kernel's struct and set the rest to -1. Accesses to the copy are CO-RE relocated, so the struct can grow by appending fields, which its comment now states. The kfunc changes in place: the cid interface is still being finalized and no released scheduler uses the current form. Fixes: e9b55af47edf ("sched_ext: Add topological CPU IDs (cids)") Cc: stable@vger.kernel.org # v7.2+ Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-09-26sched_ext: Add a CID NUMA node lookup kfuncAndrea Righi
CID-form schedulers may need the physical NUMA node for a CID, for example to allocate arena memory on that node. The CID topology's node index is not a physical NUMA node ID, and scx_bpf_cpu_node() is restricted to CPU-form schedulers. Add scx_bpf_cid_node() to return the physical NUMA node for a CID and provide a compatibility helper that returns NUMA_NO_NODE on kernels without this kfunc. Signed-off-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-19sched_ext: Pass the initial cmask to cid-form ops.enable()Tejun Heo
The cid-form API has an obvious hole. A task's cid mask is only visible through ops.set_cmask(), which fires on affinity changes and class switches but not when a task enters a scheduler through fork, sub-sched enable or re-home, and there is no p->cpus_ptr equivalent to fall back on. Schedulers work around it by seeding the mask in ops.init_task() from p->cpus_ptr cid by cid, which is subtly wrong: on sub-sched enable and re-home, an affinity change between init_task() and enable() is delivered to the sched the task is still on, and nothing corrects the new sched's copy afterwards. Fix it by adding struct scx_enable_args to cid-form ops.enable() carrying the task's cmask, built in the per-cpu scratch under the rq lock as the task enters the scheduler, and calling set_cmask() with the same mask right after enable(), ahead of set_weight(). A scheduler can then track affinity in set_cmask() alone, and scx_qmap drops its init_task() seed. set_cmask() no longer fires for a cid-form task before it is enabled, and the class-switch republish in switching_to_scx() is limited to the cpu form. This changes the cid-form ops.enable() signature, which is fine as the cid-form API is still considered unreleased. An args struct rather than a bare cmask argument leaves room for more initial state without another signature change, and the cmask travels as a plain arena address because BTF can't type arena struct members yet. v2: The cmask travels as a u64 arena address, cmask_arena_addr, instead of a kernel-typed pointer, with the typing limitation and the planned typed alias documented (Sashiko review). v3: The initial set_cmask() is delivered before set_weight() so that the mask is in place when weight-dependent state is derived (Andrea Righi). Selftest added. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-09-18sched_ext: Add lazy preemption supportAndrea Righi
The fair scheduling class can request lazy rescheduling, deferring an in-kernel scheduling boundary until returning to user space or until the next scheduler tick. sched_ext only exposes immediate preemption, preventing BPF schedulers from making the same trade-off. Add SCX_ENQ_PREEMPT_LAZY and SCX_KICK_PREEMPT_LAZY. Both expire the current sched_ext task slice but request lazy rescheduling. Immediate preemption, WAIT and plain kicks take precedence when requests are combined, while a lazy enqueue to a non-local DSQ retains the head-insertion semantics of SCX_ENQ_PREEMPT. Add SCX_OPS_LAZY_RESCHED as the default slice-expiry policy for newly enabled tasks and initialize it before ops.enable(). Add scx_bpf_task_set_lazy_resched() so the owning scheduler can override the persistent policy per task from any callback while preserving sub-scheduler task ownership boundaries. Bypass continues to force immediate rescheduling. For an infinite-slice task whose tick is stopped, set the lazy reschedule request before restoring the scheduler tick dependency. This lets the dependency update's IPI serve the request on return to user space and guarantees that the next tick promotes it otherwise. Use pinned rq locking for remote kick delivery so RQCF_UPDATED reflects clock updates since lock acquisition. Accumulate kick requests independently and resolve precedence while holding the target rq lock. Reject invalid SCX_KICK_IDLE combinations and unknown kick flags, which were previously silently ignored. Tested-by: Tao Cui <cuitao@kylinos.cn> Signed-off-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-15sched_ext: Maintain an online cid mask in the scheduler arenaTejun Heo
Schedulers on the default cid mapping treat [0, nr_online_cids) as the online set and restart on hotplug. Schedulers that install their own mapping with scx_bpf_cid_override() have no way to learn which cids are online: the count no longer identifies members and the CPU-form cpumask is unusable from cid programs. This is an obvious hole in the cid API. Add scx_bpf_online_cmask(), a kernel-maintained cmask in the scheduler's arena, allocated alongside the per-CPU scratch masks and populated after the cid mapping is finalized and before ops.init(), for child schedulers too. The pointer stays valid through ops.exit() with no reference to take. It is the arena offset as a void pointer, the same form struct_ops arena arguments arrive in. The verifier types the void return as a scalar for the program's arena cast. The mask follows the SCX hotplug notifications: seeded from cpu_active_mask and updated before ops.cid_online/offline() runs, so it lags cpu_online_mask only inside a hotplug transition. Updates walk the scheduler list under the lock that also serializes unlinking. Reads are live, not atomic snapshots. Root initialization excludes hotplug. v2: Reworded the getter kerneldoc (Andrea Righi). Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-09-15sched_ext: scx_qmap: Restore unused idle claims from ops.dispatch()Tejun Heo
scx_qmap tracks idle cids itself. pick_direct_dispatch_cid() claims a cid by clearing its bit and the task is inserted into that cid's local DSQ, which kicks the CPU. When the task does not arrive, for example because the insert fell back to the global DSQ after an affinity change, the CPU wakes, finds nothing and picks idle again. That is not an idle transition, so ops.update_idle() is not called and the cid stays marked busy until an unrelated task runs on it. Restore the claim from ops.dispatch(). The kick guarantees a dispatch on the kicked CPU, and when it finds nothing to run with a NULL @prev, the CPU is going back to idle. Document the pattern in ops.update_idle(), which reports only actual transitions. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com> Cc: Andrea Righi <arighi@nvidia.com>
2026-09-08tools/sched_ext: Fix repeated word 'be' in commentHemanth Selam
Drop the second 'be', reported by checkpatch.pl as a possible repeated word. Only touches a comment, no code changes. Assisted-by: Cursor:claude-opus-5 Signed-off-by: Hemanth Selam <hemanth.selam@gmail.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-08tools/sched_ext: Drop the no-op -rdynamic from CFLAGSCheng-Yang Chou
Because CFLAGS only applies to compilation ($(CC) -c), the link-time flag -rdynamic is inert during the build. Schedulers do not rely on exported dynamic symbols, and binaries remain byte-identical without it. Under -Werror, Clang treats this unused argument as a build error: $ make CC=clang-21 clang-21: error: argument unused during compilation: '-rdynamic' [-Werror,-Wunused-command-line-argument] Drop -rdynamic from CFLAGS to ensure clean builds across Clang versions. Signed-off-by: Cheng-Yang Chou <yphbchou0911@gmail.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-06sched_ext: scx_qmap: Fix pending partition work handoffTejun Heo
qmap can leave partition work pending with no runner. The effective-cap callback publishes its request after failing to acquire part_busy, while redistribute() checks for pending work before releasing it. Either ordering can miss a request arriving as the current runner finishes, delaying the update until the round-robin timer runs. Publish requests before trying to become the runner and release part_busy before checking for more work. Have all holders drain pending requests after releasing it, including the stats flush. Distinguish mask refreshes from repartitions so an effective-cap update only rebuilds the partition when a repartition was also requested. Fixes: e9151ed5c944 ("tools/sched_ext: scx_qmap - Expand hierarchical sub-scheduling") Reported-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-09-05sched_ext: scx_qmap: Place only on cids whose caps are in effectTejun Heo
qmap decides placements from self_cids, which redistribute() derives from the caps view at ops.sub_caps_updated() time. That view runs ahead of the cpus: a granted cid can be in self_cids before its cpu has reported the caps in effect through ops.sub_ecaps_updated(). ops.update_idle() only comes once BASE is in effect, so the idle-gated placements reach such a cid only through an idle bit left over from an earlier hold. The highpri scan has no gate at all: parent cpu Y, qmap cpu X grants ENQ on X to qmap sub_caps_updated() adds X to self_cids highpri scan moves a task to X with PREEMPT caps not in effect, move denied, task bounced with REENQ_CAP reject drain, enqueue the scan moves it to X again denied again dispatch syncs ecaps, sub_ecaps_updated(X) Every highpri move to X in that window is denied and bounced. The two callbacks are meant to split the roles: ops.sub_caps_updated() tracks what the node holds and drives what it delegates to its children, while ops.sub_ecaps_updated() says whether a task can run on a cpu now. qmap used the first for both. Track the caps in effect from ops.sub_ecaps_updated() as avail_cids and place only on self_cids & avail_cids, so that self_cids stays the delegation split and avail_cids gates the placement. The stranded tests keep self_cids, as they ask whether the split gives the task anywhere at all. A highpri task whose self_cids lack caps in effect waits for them instead of being moved and bounced. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-09-05sched_ext: scx_qmap: Do not add IMMED to rescue insertsTejun Heo
qmap's stranded fallback forces a task that can run on none of its self cids onto its first allowed cid with SCX_ENQ_RESCUE, and adds SCX_ENQ_IMMED when that cid is a time-share it holds. On such a cid the insert stops being a rescue request: 1. A task is enqueued while none of its allowed cids is in self_cids. At attach self_cids is still empty. 2. qmap inserts it into cid 0's local DSQ with SCX_ENQ_RESCUE | SCX_ENQ_IMMED. 3. The kernel finds ENQ_IMMED held on cid 0, admits the insert and skips the rescue diversion. 4. cid 0's cpu is busy, so the IMMED task is bounced back to qmap with SCX_ENQ_REENQ. 5. qmap's enqueue sees the same inputs and repeats step 2. Nothing runs in between. 6. The reenqueue limit ejects qmap with SCX_EXIT_ERROR_REENQ. The caps granted during the parent's ops.sub_attach() are delivered after the sub already holds its tasks, while the per-cid effective caps that mark the time-shares are delivered from the first dispatch after bypass lifts, so every attach that receives a time-share on a task's first allowed cid starts the loop. Drop IMMED from the rescue inserts so that step 3 diverts to the rescue path. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-09-01sched_ext/scx_flatcg: Make cgv_node_less() wraparound-safeTao Cui
cgv_node_less() compares cvtimes with a plain <, which misorders once cvtime wraps: the wrapped node lands at the front of the tree while the unwrapped ones get stuck behind it. Each CPU picking a cgroup charges it a full slice, making wrap occur earlier than a naive estimate might suggest. Use time_before() instead. cgrp_cap_budget() bounds the lag behind cvtime_now, while the lead is bounded by the slice charge plus pending cvtime_delta on re-insertion, so the cyclic ordering assumptions of time_before() hold. Fixes: a4103eacc2ab ("sched_ext: Add a cgroup scheduler which uses flattened hierarchy") Reported-by: Sashiko <sashiko-bot@kernel.org> Link: https://lore.kernel.org/r/3f1ce004-e259-4e72-a5f7-14a5050053bd@linux.dev Signed-off-by: Tao Cui <cuitao@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-31sched_ext: Check bpf_timer_start return values in scx_qmapWanwu Li
monitor_timerfn(), lowpri_timerfn() and round_robin_timerfn() ignore bpf_timer_start()'s return value: a failed re-arm silently stops the periodic heartbeat, starving every task parked in LOWPRI_DSQ (lowpri) or freezing cid rotation (round-robin). Check the returns and raise scx_bpf_error(), matching the init paths. Signed-off-by: Wanwu Li <liwanwu@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-31sched_ext: Fix vtime delta loss in scx_flatcg cgroup migrationWanwu Li
fcg_cgroup_move() lost the signed vtime offset across cgroup migration in the mechanical conversion to time helpers: time_delta() clamps negative deltas to 0, so a queued task (whose dsq_vtime is normally behind the source frontier) loses its accumulated vtime credit and lands exactly at the destination frontier instead of keeping its relative position. Restore the wrapping signed subtraction. Fixes: 62addc6dbf36 ("sched_ext: Use time helpers in BPF schedulers") Signed-off-by: Wanwu Li <liwanwu@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-31sched_ext: Fix timer pinning and return value in scx_centralWanwu Li
central_timerfn() re-arms the timer with a hardcoded BPF_F_TIMER_CPU_PIN flag and ignores the return value, defeating start_central_timer()'s -EINVAL fallback for kernels without the flag (<6.7): on such kernels the first tick kills the timer permanently with no diagnostic. Honor timer_pinned and check the return like the initial arm does. Fixes: 22a920209ab6 ("sched_ext: Implement tickless support") Signed-off-by: Wanwu Li <liwanwu@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-21sched_ext: Sync common and compat headers from the scx repoTejun Heo
Sync common.bpf.h, compat.bpf.h and compat.h with the scx repo, which accumulated the following: - __COMPAT_read_enum() can now recover 64-bit scx enum values from kernel BTF generated without BTF_KIND_ENUM64 support (pahole < 1.24 or --skip_encoding_btf_enum64, e.g. COS/GKE kernels), substituting values from the build-time vmlinux.h cross-checked against the low 32 bits the kernel does provide. - is_migration_disabled() no longer assumes the BPF prolog always disables migration. Since 8e4f0b1ebcf2 ("bpf: use rcu_read_lock_dont_migrate() for trampoline.c") the prolog only does so under CONFIG_PREEMPT_RCU, so the old current-task test under-reported on v6.18+ !PREEMPT_RCU kernels. A runtime probe on bpf_scx_reg() handles older kernels with backported trampoline behavior. - __COMPAT_scx_bpf_dsq_peek() is gated behind kernel v7.1 where 2f2ea7709266 ("sched_ext: Use dsq->first_task instead of list_empty() in dispatch_enqueue() FIFO-tail") fixed the kfunc spuriously returning NULL on non-empty FIFO DSQs, and the new scx_bpf_reenqueue_local_from_anywhere() provides a callable-from-anywhere reenqueue which prefers the generic scx_bpf_dsq_reenq(). Both were first posted by Gavin Guo and Changwoo Min and are picked up here with the review feedback folded in. - __COMPAT_scx_bpf_cpu_curr() and the scx_bpf_cpu_rq() declaration are restored. Schedulers built from these headers still run on pre-v6.18 kernels where scx_bpf_cpu_curr() does not resolve and the scx_bpf_cpu_rq() fallback still exists. - scx_clock_task() and scx_clock_pelt() document their stale-read behavior for remote idle CPUs under NO_HZ_IDLE. Link: https://lore.kernel.org/all/20260817143126.562923-1-changwoo@igalia.com Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-21sched_ext: Sync tools autogen enum headers from the scx repoTejun Heo
Regenerate enum_defs.autogen.h against the current tree, picking up the dispatch verdict enums and dropping the marker for the removed SCX_RQ_IN_BALANCE. Add enums_abi.autogen.h, a table of 64-bit scx enumerator values generated from vmlinux.h, used as the substitution source when the running kernel's BTF truncates 64-bit enum values to 32 bits. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-17sched_ext: Merge branch 'for-7.3-arena-args' into for-7.3Tejun Heo
Pull to receive the __arena argument conversion: 67f1f4a48c24 ("sched_ext: Pass kernel arena pointers to ops_cid callbacks") a8dc810968af ("sched_ext: Convert sub-cap kfuncs to __arena cmask arguments") a05c5b5cb5cf ("sched_ext: Convert scx_bpf_cid_override() to __arena array arguments") along with the bpf-next branch carrying the __arena argument support they depend on. Conflict in kernel/sched/ext/ext.c between: c384ab8a0b13 ("sched_ext: Move the config-off sub-cap kfunc stubs into sub.c") and: a8dc810968af ("sched_ext: Convert sub-cap kfuncs to __arena cmask arguments") which updated the stubs in their old ext.c location. Resolved by keeping ext.c without the stubs and applying the prototype conversion to the relocated stubs in sub.c. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-15sched_ext: Make core-sched task ordering hierarchy-awareTejun Heo
With sub-schedulers, tasks of different schedulers routinely share rqs and SMT siblings, but scx_prio_less() consults ops.core_sched_before() only when both tasks belong to the same scheduler. Every pair spanning two schedulers falls back to the default ordering, so no scheduler can express ordering across a scheduler boundary, including a root over its sub-schedulers' tasks. Order a pair spanning schedulers by the nearest common ancestor that implements ops.core_sched_before(): both tasks are in its subtree, making this the one op where a scheduler is called on tasks it delegated to its sub-schedulers and may not be scheduling anymore. Same-scheduler pairs keep using the owning scheduler's op so a parent never orders inside a subtree it delegated. The op is skipped when the deciding scheduler is bypassing on either task's CPU. Update scx_qmap to fall back to the kernel's default ordering when handed a delegated task it has no task_ctx for. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-15sched_ext: Fix inverted ops.core_sched_before() invocationTejun Heo
scx_prio_less() implements prio_less() semantics - %true means that @a is the lower priority and should run after @b. ops.core_sched_before() is documented to return %true when @a should run before @b. scx_prio_less() returns the op's value as-is, inverting the documented semantics at runtime. Call the op with the arguments swapped. scx_qmap followed the wiring instead of the documentation and returned %true for the younger task, so the two inversions canceled out and it behaved as intended. Flip its comparison to match. scx_qmap is likely the only current user in or out of the kernel tree. Any scheduler written the same way needs the same flip, while schedulers following the documentation are fixed by this change. Fixes: 7b0888b7cc19 ("sched_ext: Implement core-sched support") Cc: stable@vger.kernel.org # v6.12+ Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-15sched_ext: Rename balance-era identifiers to dispatch termsTejun Heo
sched_class->balance() is gone from sched_ext and what balance_one() does is run dispatch to produce something pickable. Update the balance-era names to dispatch terms: - balance_one() -> dispatch_one() - SCX_RQ_IN_BALANCE -> SCX_RQ_IN_DISPATCH No BPF scheduler reads the flag. The enum autogen headers gain the new name with the old entry retained like other removed enumerators, zero-filling at load time. No functional changes. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-14sched_ext/scx_flatcg: Fix cvtime true-up on slice expiryTao Cui
fcg_dispatch() true-ups the current cgroup's cvtime when its slice expires or its DSQ runs empty while the slice is still active: __sync_fetch_and_add(&cgc->cvtime_delta, (cpuc->cur_at + cgrp_slice_ns - now) * FCG_HWEIGHT_ONE / (cgc->hweight ?: 1)); The true-up should be actual minus charged: on CNS_EXPIRE, the overrun (now - cur_at - cgrp_slice_ns) should be added; on CNS_EMPTY, the unused portion of the slice should be subtracted. The expression above has the sign inverted, and in the CNS_EXPIRE case now is already past cur_at + cgrp_slice_ns, so the u64 subtraction wraps. The multiplication preserves the two's complement encoding but the unsigned division by hweight destroys it, adding roughly 2^64/hweight per expiry instead of a small correction. Under saturation the hweight budget clamp in cgrp_cap_budget() masks most of the garbage, so the weight distribution barely moves, but the accounting is broken all the same. Compute the delta as a signed value and use fetch_and_add()/fetch_and_sub() so that the dividends stay positive, as BPF division is unsigned. Instrumented the true-up and ran a saturated three-leaf cgroup tree on a 4-CPU VM: without the fix, each expiry added ~5e15 (2^64/hweight territory) to cvtime_delta; with it, the corrections are back to slice scale, with the overrun added and the unused portion subtracted. Fixes: a4103eacc2ab ("sched_ext: Add a cgroup scheduler which uses flattened hierarchy") Suggested-by: Tejun Heo <tj@kernel.org> Signed-off-by: Tao Cui <cuitao@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-14sched_ext: Fix scx_bpf_dsq_move_to_local___v2 compat detectionfangqiurong
libbpf strips the last ___flavor suffix when resolving kfunc externs, so the bare ___v2 declaration resolves to scx_bpf_dsq_move_to_local, whose BTF proto lacks @enq_flags. The extern never matches, bpf_ksym_exists() returns false on every kernel that has the ___v2 kfunc, and the macro falls back to ___v1, silently dropping @enq_flags. Add the trailing ___compat suffix used by the other versioned externs in this file (scx_bpf_dsq_insert___v2, scx_bpf_reenqueue_local___v2). Any caller passing non-zero @enq_flags through the compat macro silently loses them. Fixes: 860683763ebf ("sched_ext: Add enq_flags to scx_bpf_dsq_move_to_local()") Cc: stable@vger.kernel.org # v7.1+ Assisted-by: Z.ai:glm-5.2 Signed-off-by: fangqiurong <fangqiurong@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-14sched_ext: Fix scx_bpf_dsq_reenq___compat kfunc extern prototypeTejun Heo
scx_bpf_dsq_reenq() is registered with KF_IMPLICIT_ARGS and its kernel BTF prototype omits the trailing bpf_prog_aux argument. The ___compat extern declares the argument explicitly, so libbpf never matches the prototype and the weak extern silently stays unresolved on every kernel. The wrapper always takes the old fallback path, which disables generic reenq users like scx_qmap's lowpri mechanism and fails non-local reenq with "kernel too old" even on kernels that have the kfunc. Drop the explicit aux argument. Also correct the stale v6.20 reference, the kfunc was added in v7.1. Fixes: 9c34c5074d1b ("sched_ext: Introduce scx_bpf_dsq_reenq() for remote local DSQ reenqueue") Cc: stable@vger.kernel.org # v7.1+ Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-14sched_ext/scx_flatcg: expire cached hweights on weight changesTao Cui
fcg_cgroup_set_weight() updates cgc->weight and the parent's child_weight_sum but doesn't bump hweight_gen, so the hweights cached by cgrp_refresh_hweight() stay stale until some task activation bumps the generation. For cgroups whose tasks never go through a 0->n runnable transition (e.g. persistently busy ones), a cpu.weight change never propagates to scheduling at all. Bump hweight_gen on weight changes so the next refresh recomputes with the new weight. Verified on a flatcg VM: a live cpu.weight 100->800 change on a busy cgroup leaves HWT update at 0 and the distribution unchanged; with it, hweight_gen increments and the refresh recomputes. Signed-off-by: Tao Cui <cuitao@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-12sched_ext: Convert scx_bpf_cid_override() to __arena array argumentsTejun Heo
scx_bpf_cid_override() predates the cid-form arena transition and takes its arrays as verifier-checked mem+size buffers, forcing scx_qmap to keep the cpu_to_cid and shard_start arrays in writable bss while the rest of its state lives in the arena. Unify on arena arguments before cid-form schedulers start seeing real use. BPF now translates between BPF and kernel arena addresses for __arena arguments. Take the arrays as __arena arguments, with the counts passed in entries. The counts now size the snapshot copies and are bounds-checked before them. scx_qmap moves the arrays into struct qmap_arena. As the arena is mmapped at load, the loader populates them between load and attach instead of before load. The arena argument address translation is currently implemented only on x86-64. Schedulers calling this kfunc load only there for now. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-12sched_ext: Convert sub-cap kfuncs to __arena cmask argumentsTejun Heo
The sub-cap kfuncs take their cmask arguments as __ign pointers. The values cross the kfunc boundary as unchecked scalars and scx_cmask_ref_init() rebases them into the arena by hand. BPF now translates between BPF and kernel arena addresses for __arena arguments. Tag the cmask arguments __arena so the kfuncs receive kernel addresses and scx_cmask_ref_init() loses the hand-rolled conversion. The optional denied_out keeps its NULL not-provided signal via __arena__nullable. The mandatory masks use plain __arena. scx_qmap's call sites drop the (void *)(long) casts since the BPF-side declarations type the cmask arguments __arena and take arena pointers directly. The arena argument address translation is currently implemented only on x86-64. Schedulers calling these kfuncs load only there for now. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-12Merge branch 'for-7.3' into for-7.3-arena-argsTejun Heo