On Fri, Sep 18, 2026 at 4:09 AM Yaxiong Tian <[email protected]> wrote:
>
>
> On 2026/9/18 03:34, Rafael J. Wysocki (Intel) wrote:
> > On Wed, Jul 29, 2026 at 8:16 AM Yaxiong Tian <[email protected]> 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?

Reply via email to