Messages in this thread | | | From | "Rafael J. Wysocki" <> | Date | Mon, 23 Nov 2020 11:26:39 +0100 | Subject | Re: [PATCH 2/2] intel_idle: Fix intel_idle() vs tracing |
| |
On Fri, Nov 20, 2020 at 12:50 PM Peter Zijlstra <peterz@infradead.org> wrote: > > cpuidle->enter() callbacks should not call into tracing because RCU > has already been disabled. Instead of doing the broadcast thing > itself, simply advertise to the cpuidle core that those states stop > the timer. > > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> > --- > drivers/idle/intel_idle.c | 37 ++++++++++++++++++++----------------- > 1 file changed, 20 insertions(+), 17 deletions(-) > > --- a/drivers/idle/intel_idle.c > +++ b/drivers/idle/intel_idle.c > @@ -126,26 +126,9 @@ static __cpuidle int intel_idle(struct c > struct cpuidle_state *state = &drv->states[index]; > unsigned long eax = flg2MWAIT(state->flags); > unsigned long ecx = 1; /* break on interrupt flag */ > - bool tick; > - > - if (!static_cpu_has(X86_FEATURE_ARAT)) { > - /* > - * Switch over to one-shot tick broadcast if the target C-state > - * is deeper than C1. > - */ > - if ((eax >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) { > - tick = true; > - tick_broadcast_enter(); > - } else { > - tick = false; > - } > - } > > mwait_idle_with_hints(eax, ecx); > > - if (!static_cpu_has(X86_FEATURE_ARAT) && tick) > - tick_broadcast_exit(); > - > return index; > } > > @@ -1460,6 +1443,23 @@ static bool __init intel_idle_verify_cst > return true; > } > > +static bool __init intel_idle_state_needs_timer_stop(struct cpuidle_state *state) > +{ > + unsigned long eax = flg2MWAIT(state->flags); > + > + if (boot_cpu_has(X86_FEATURE_ARAT)) > + return false; > + > + /* > + * Switch over to one-shot tick broadcast if the target C-state > + * is deeper than C1. > + */ > + if ((eax >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) > + return true; > + > + return false; > +} > + > static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv) > { > int cstate; > @@ -1507,6 +1507,9 @@ static void __init intel_idle_init_cstat > !(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_ALWAYS_ENABLE))) > drv->states[drv->state_count].flags |= CPUIDLE_FLAG_OFF; > > + if (intel_idle_state_needs_timer_stop(&drv->states[drv->state_count])) > + drv->states[drv->state_count].flags |= CPUIDLE_FLAG_TIMER_STOP; > + > drv->state_count++; > }
This doesn't cover the ACPI case AFAICS.
| |