Re: [PATCH v2 0/6] cpuidle: speed up do_idle() by caching the governor latency QoS constraint
From: Rafael J. Wysocki (Intel)
Date: Fri Sep 18 2026 - 08:09:10 EST
On Fri, Sep 18, 2026 at 4:09 AM Yaxiong Tian <tianyaxiong@xxxxxxxxxx> wrote:
>
>
> On 2026/9/18 03:34, Rafael J. Wysocki (Intel) wrote:
> > On Wed, Jul 29, 2026 at 8:16 AM Yaxiong Tian <tianyaxiong@xxxxxxxxxx> wrote:
> >> cpuidle_governor_latency_req() is evaluated on every idle-state
> >> selection. It aggregates the per-CPU resume latency with the global
> >> CPU latency and wakeup latency QoS limits
> > True.
> >
> >> by repeatedly calling
> >> get_cpu_device() and pm_qos_read_value() cpu_latency_qos_limit()
> >> cpu_wakeup_latency_qos_limit().
> > I would say "every time" rather than "repeatedly", but fair enough.
> >
> > However, those functions don't do anything expensive except for
> > defensive checks that can be omitted. Have you tried to omit them?
> I haven't tried that, but I found that function_graph may introduce measurement errors, especially for very short functions.
> >
> >> Use ftrace's function_graph, we can see:
> >> parent: do_idle
> >> parent_total_ns: 36671010505
> >> parent_count: 5994
> >>
> >> SYMBOL TIME_NS %ROOT %PARENT COUNT
> >> --------------------------------------------------------------------------------------------------
> >> do_idle 36671010505 100.00% 100.00% 5994
> >> cpuidle_idle_call 35566528731 96.99% 96.99% 8570
> >> call_cpuidle 35476606844 96.74% 99.75% 8561
> >> cpuidle_enter 35472932468 96.73% 99.99% 8526
> >> cpuidle_select 52097031 0.14% 0.15% 8580
> >> menu_select 49555181 0.14% 95.12% 8580
> >> tick_nohz_get_sleep_length 28843887 0.08% 58.21% 8570
> >> cpuidle_governor_latency_req 9567488 0.03% 19.31% 8580
> >> tick_nohz_tick_stopped 2057031 0.01% 4.15% 15695
> >> cpuidle_reflect 11427201 0.03% 0.03% 8561
> >> menu_reflect 6579506 0.02% 57.58% 8526
> >> tick_nohz_idle_got_tick 2231559 0.01% 33.92% 8526
> >> __sysvec_apic_timer_interrupt 105520 0.00% 0.92% 3
> >> tick_nohz_idle_stop_tick 8279641 0.02% 0.02% 1475
> >> ---- skip
> >>
> >> The majority of the time spent in cpuidle_enter for CPUs entering
> >> idle state has already been charged to the idle path. Among the
> >> remaining contributors, cpuidle_governor_latency_req() accounts
> >> for a non-negligible portion of the overall latency.
> >>
> >> Under the menu governor this shows up hot: ftrace data shows,
> >> cpuidle_governor_latency_req() accounts for about 19.9% of
> >> menu_select() time (~1.9 us/call). After caching the aggregated
> >> value per CPU and invalidating via QoS notifiers, that share drops to
> >> about 4.2% (~0.3 us/call), roughly a 6x reduction on this path.
> > Is there any real-world workload in which that difference is actually visible?
> Sorry, I only tested it under no load.
>
> >
> >> The ftrace data before and after the optimization is shown below:
> >> 1) original
> >> parent: menu_select
> >> parent_total_ns: 160492937
> >> parent_count: 16718
> >>
> >> SYMBOL TIME_NS %ROOT %PARENT COUNT
> >> --------------------------------------------------------------------------------------------------
> >> menu_select 160492937 100.00% 100.00% 16718
> > Where did you lose menu_update()?
> Because menu_update() was optimized away by the compiler, it can't be seen in /proc/kallsyms, so it won't be traced by ftrace either.
How could it be optimized away?