Skip to main content
Redhat Developers  Logo
  • AI

    Get started with AI

    • Red Hat AI
      Accelerate the development and deployment of enterprise AI solutions.
    • AI learning hub
      Explore learning materials and tools, organized by task.
    • AI interactive demos
      Click through scenarios with Red Hat AI, including training LLMs and more.
    • AI/ML learning paths
      Expand your OpenShift AI knowledge using these learning resources.
    • AI quickstarts
      Focused AI use cases designed for fast deployment on Red Hat AI platforms.
    • No-cost AI training
      Foundational Red Hat AI training.

    Featured resources

    • OpenShift AI learning
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

    Red Hat AI Factory with NVIDIA

    • Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.
    • Explore the solution
  • Learn

    Self-guided

    • Documentation
      Find answers, get step-by-step guidance, and learn how to use Red Hat products.
    • Learning paths
      Explore curated walkthroughs for common development tasks.
    • Guided learning
      Receive custom learning paths powered by our AI assistant.
    • See all learning

    Hands-on

    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.
    • Interactive labs
      Learn by doing in these hands-on, browser-based experiences.
    • Interactive demos
      Click through product features in these guided tours.

    Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics

    Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
  • Build

    Get started

    • Red Hat build of Podman Desktop
      A downloadable, local development hub to experiment with our products and builds.
    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.

    Download products

    • Access product downloads to start building and testing right away.
    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset

    References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
  • Community

    Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions

    Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github

    Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

    Join the Red Hat Developer program

    • Download Red Hat products and project builds, access support documentation, learning content, and more.
    • Explore the benefits

One kernel feature, 93% system throughput gone: A Red Hat Enterprise Linux 10.2 kernel regression and how to mitigate it

Mitigate a kernel scheduler regression with no reboot required

August 4, 2026
Sayali Bhavsar
Related topics:
Linux
Related products:
Red Hat Enterprise Linux

    TL;DR — During performance validation of Red Hat Enterprise Linux 10.2, we identified a kernel scheduler regression that reduced system throughput by up to 93% on multi-NUMA instance types. The regression is bimodal: Workloads either run at full speed or experience severe CPU work starvation. Eliminate this throughput collapse at runtime without rebooting by disabling the NI_RANDOM scheduler feature:

    echo NO_NI_RANDOM > /sys/kernel/debug/sched/features

    Every Red Hat Enterprise Linux (RHEL) minor release carries hundreds of kernel patches. Most of them are invisible to performance. This one is not. During RHEL 10.2 compose validation, the team caught a regression that caused up to 93% throughput loss on CockroachDB across multiple AWS instance types (see figure 1). A few other benchmarks flagged minor issues on individual instances, but nothing else came close to this magnitude.

    What is CockroachDB?

    CockroachDB is a distributed SQL database, but with the Phoronix wrapper it serves as a system benchmark. This runs cockroachdb as a single-node server on a local machine — no network, no distributed coordination — so the only variables are the kernel, CPU, and memory subsystem. The benchmark spawns 128 to 1024 concurrent workers that perform random reads and writes against a single key-value table for 90 seconds, measuring throughput in ops/s. CockroachDB is written in Go, which multiplexes thousands of goroutines across operating system (OS) threads, placing heavy demand on the kernel's thread scheduler, making it an effective stress test for exactly the kind of regression we found.

    Geomean of various benchmarks run on Red Hat Enterprise Linux 10.2.
    Figure 1: Geomean of various benchmarks run on Red Hat Enterprise Linux 10.2.

    What problem does the regression cause?

    This is the story of how I found the regression, what I ruled out, and why it was so hard to pin down.

    Of 29 instance types tested, the major hit was large machines. The pattern was immediate: large multi-NUMA instances experience severe degradation, while small single-NUMA instances remain largely unaffected. So I picked the worst-performing instance (m6a.24xlarge, 96 vCPUs, two NUMA nodes, AMD EPYC 7R13) and began investigating (see figure 2).

    InstanceProcessorvCPUsNUMADelta
    m6a.24xlargeAMD EPYC 7R13962-68%
    m5.24xlargeXeon 8175M962-65%
    m7a.16xlargeAMD EPYC 9R14642-31%
    m7i.16xlargeXeon 8488C642-15%
    CockroachDB benchmark ran on various AWS instances.
    Figure 2: CockroachDB benchmark ran on various AWS instances.

    The first surprise: It doesn't wobble, it flips

    I ran 10 iterations on each kernel — RHEL 10.1 (6.12.0-124.38.1) and 10.2 (6.12.0-211.7.1) — with identical configuration. The same instance type, same availability zone, same tunables, same Phoronix cockroach-1.1.0 benchmark, XFS, SELinux enforcing, no tuned profile, no swap, no hugepages. The only differences were the kernel and glibc versions.

    RHEL 10.1 stays within a 3% band across all iterations. RHEL 10.2 has two catastrophic swings: -69.4% entering the degraded state and +231.1% recovering from it.

    IterRHEL 10.2 GeoMean10.2 Run-to-RunRHEL 10.1 GeoMean10.1 Run-to-RunDeltaDelta %
    1127,553-126,620-9330.70%
    2124,467-2.40%126,323-0.20%-1,856-1.50%
    338,047-69.40%126,4610.10%-88,414-69.90%
    437,983-0.20%127,4590.80%-89,476-70.20%
    538,2980.80%124,154-2.60%-85,856-69.20%
    638,099-0.50%127,7392.90%-89,640-70.20%
    738,2200.30%125,460-1.80%-87,240-69.50%
    838,3150.20%127,2771.40%-88,962-69.90%
    9126,802231.10%126,176-0.90%6260.50%
    10125,893-0.70%127,1040.70%-1,211-1.00%
    Avg73,368-126,477--53,110-42.00%
    StdDev40,197-1,060---
    CoV54.80%-0.84%---
    Max +ve swing-231.10%-2.90%--
    Max -ve swing--69.40%--2.60%--

    Breaking down iteration 3 by individual workload shows the regression scales with both write ratio and concurrency

    WorkloadRHEL 10.1RHEL 10.2Delta (10.2 vs 10.1)
    60% c=12879,1745,269-93%
    60% c=256105,82412,340-88%
    60% c=512118,79925,140-79%
    95% c=128131,00537,948-71%
    95% c=256149,32291,496-39%
    95% c=512167,405144,323-14%
    60% c=1024118,83352,456-56%
    95% c=1024164,032157,428-4%

    The performance doesn't fluctuate, it flips. Iterations 1 (127,553) and 2 (124,467) match 10.1 within 1.5%. On iteration 3, throughput drops to 38,047-a 69.4% fall in a single step. It stays locked between 37,983 and 38,315 for six consecutive iterations (CoV under 1% within the degraded band), then snaps back to 126,802 on iteration 9. That's a 231% jump between consecutive runs. Iteration 10 holds at 125,893, confirming the recovery is real.

    This is not noise. It is a binary state change. The system has two stable operating points and something tips it from one to the other. What triggers the recovery is not yet understood. The degraded state persists for six consecutive iterations (~9 hours of runtime), then resolves spontaneously between iterations 8 and 9 with no configuration change or restart. Per entity load tracking (PELT) load averages decay with a 32ms half-life, which is far shorter than the inter-iteration gap-so simple time-based decay does not explain why the system stays degraded for hours and then recovers. The trigger likely involves a secondary state change (a NUMA rebalance, a memory compaction event, or a topology update) that resets the newidle pull probability, but I have not confirmed this.

    The second surprise: RHEL 10.2 CPUs are 95% idle

    Next I captured vmstat 1 during active benchmarking on both kernels and the pattern was unmistakable: One second, r=128 runnable processes, the next, r=0 and id=85%. The work existed. CockroachDB was running, the workload generator was running, but CPUs were not picking it up. This is work starvation, and it is the unmistakable signature of a scheduler regression.

    MetricRHEL 10.1RHEL 10.2
    r (runnable)109-1320-128
    us (user %)73%3-4%
    id (idle %)8%85-95%

    The cumulative vmstat data on RHEL 10.2 showed what was happening underneath the flip. Idle time staircase-dropped from 67% after the first run to 60% by the fourth, then plateaued. Interrupts climbed from 7,591 at clean boot to 215,576 (a 28x increase) then flattened at the same point. Context switches during the benchmark climbed from 312K/s on the first run to 553K/s on the fifth, a 77% increase within a single session.

    MetricBefore Run 1 (clean boot)After Run 1After Run 2After Run 3After Run 4After Run 5
    us0%24%26%27%29%29%
    sy0%8%9%10%10%10%
    id100%67%65%63%60%60%
    cs/s0312,637340,511440,528493,689552,996
    in/s7,591165,327183,991199,600215,576214,093

    The scheduler was accumulating state across runs and not letting go, likely PELT load averages drifting up and never fully decaying between iterations.

    Where the work went

    Thread stack traces during the degraded state told the story. 148 CockroachDB threads were blocked in futex_do_wait — Go runtime locks. Another 24 were idle in hrtimer_nanosleep.

    TIDOn CPU (ms)Waiting (ms)Wait %
    480491,3271,88659%
    470621,5631,87955%
    470631,07284044%
    470641,34387239%
    470691,37090940%

    Only 4 threads were actually running. Zero threads were in dequeue_task, throttle_cfs, or load_balance. No kernel-level scheduler stalls. The scheduler was not distributing wake-ups, so threads that could run were stuck waiting for lock holders that never got CPU time.

    ProcessStack FunctionCount
    Serverfutex_do_wait49
    Serverhrtimer_nanosleep15
    Serversched_yield2
    Workloadfutex_do_wait99
    Workloadhrtimer_nanosleep9
    Workloadsched_yield6
    Workloadsyscall_exit_to_user_mode3
    Workloadirqentry_exit_to_user_mode1

    Schedstat showed the other half of the problem. Even when threads were runnable, they spent 39-59% of their time waiting for the scheduler to pick them up.

    NUMA placement was not the cause. RHEL 10.2 counters showed half the activity of 10.1, consistent with half the throughput, and zero numa_miss on both sides.

    The regression scaled with how much the workload depended on the scheduler to distribute work: -93% at low concurrency with write-heavy traffic (128 connections, 60% reads), -4% at high concurrency with read-heavy traffic (1024 connections, 95% reads).

    Having confirmed the symptom, I needed to isolate the cause. The kernel is the only variable.

    • glibc: CockroachDB bundles jemalloc and bypasses glibc malloc entirely, so that's not a factor.
    • Hardware: Reproducible on fresh instances in the same availability zone.
    • Reboot: I got degraded throughput from the very first run on a freshly rebooted instance.

    With thousands of commits between the 10.1 and 10.2 kernels, a full git bisect was not practical. Each run takes 90 minutes per workload. With 8 workloads across multiple iterations, a single bisect step could take 12+ hours.

    I used kbisect-dbs, a centralized bisection database maintained by Red Hat's kernel performance team, to narrow 18,848 commits down to 35 scheduler-related changes. These fell into six functional groups. I tested each group through targeted kernel reverts, with multiple CockroachDB test runs

    • CFS bandwidth throttle: Eight commits rewriting cfs_rq-based accounting to task-based. Reverting the group delayed the degraded state by one or two runs but didn't prevent it. A timing factor, not the root cause.
    • PELT load tracking: Idle-time accounting changes. Cleared individually.
    • EEVDF entity scheduling: min_slice tuning and related changes. Cleared individually.
    • Deadline server: Cleared individually.
    • Miscellaneous: SD_OVERLAP to SD_NUMA refactor, wait_task_inactive force-dequeue, hrtick donor, CONFIG_SCHED_CLASS_EXT across core.c, topology.c, and kernel config. All cleared.
    • Newidle balance: Three commits controlling whether idle CPUs steal work from busy ones. The strongest suspects given the symptoms. Individually, none reproduced the regression. These commits are tightly coupled, so reverting one without the others doesn't compile cleanly. But one of them (NI_RANDOM) is a runtime-togglable SCHED_FEAT, which revealed a new path.

    Conclusion and workaround

    Disabling NI_RANDOM breaks the feedback loop where randomized newidle balancing starves runnable threads on multi-NUMA hardware. The fix is a single runtime toggle no reboot required:

    echo NO_NI_RANDOM > /sys/kernel/debug/sched/features

    To persist across reboots, create a tmpfiles drop-in:

    # /etc/tmpfiles.d/sched_features.conf
    w- /sys/kernel/debug/sched/features - - - - NO_NI_RANDOM

    Chris Mason at Meta reported the original newidle balance overhead idle CPUs burning cycles on balance attempts that almost always failed. Peter Zijlstra's proportional-randomization fix (NI_RANDOM) solved that problem, but introduced the starvation behavior we caught here. Both the original patches and further refinements are working through the mainline with backports to v6.12 already posted.. Until those land in RHEL, disabling NI_RANDOM restores full throughput.

    Related Posts

    • Performance and load testing in Identity Management (IdM) systems using encrypted DNS (eDNS) and CoreDNS in OpenShift clusters

    • Performance and load testing in Identity Management (IdM) systems using encrypted DNS (eDNS)

    • Visualize Performance Co-Pilot data with geomaps in Grafana

    • How to run performance tests using benchmark-runner

    • High Scale Performance Testing: Virt Density

    Recent Posts

    • One kernel feature, 93% system throughput gone: A Red Hat Enterprise Linux 10.2 kernel regression and how to mitigate it

    • Kafka Monthly Digest: July 2026

    • Stop patching and build a better WordPress stack with Red Hat Hardened Images

    • Multitenant AI inference with dynamic resource allocation on OpenShift

    • Inference-time scaling on Red Hat AI: Improving model reliability

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer tools
    • Interactive tutorials
    • API catalog

    Quicklinks

    • Learning resources
    • E-books
    • Cheat sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site status dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2026 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Chat Support

    Please log in with your Red Hat account to access chat support.