Message ID | 1416562192-14114-1-git-send-email-daniel.lezcano@linaro.org (mailing list archive) |
---|---|
State | Superseded, archived |
Delegated to: | Len Brown |
Headers | show |
On 11/21/2014 04:05 PM, Rafael J. Wysocki wrote: > On Friday, November 21, 2014 10:29:51 AM Daniel Lezcano wrote: >> The commit 8e92b6605d introduced the TIME_VALID flag for the C1 state >> if this one is a mwait state assuming the interrupt will be enabled >> before reading the end time of the idle state. >> >> The changelog of this commit mention a potential problem with the menu >> governor but not a real observation and I assume it described an old >> code as the commit is from 2008. >> >> I have been digging through the code and I didn't find any place where the >> interrupts are enabled before reading the time. Moreover with the changes >> in the meantime, we moved the time measurements in the cpuidle core as well >> as the interrupts enabling making sure the time is measured before the >> interrupt are enabled again in a single place. >> >> Remove this test as the time measurement is always valid for this >> state. >> >> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> > > Well, I need Len to have a look at this. Ok thanks. If you have time, is it possible also you have a look at the patchset I sent : [PATCH V3 0/6] sched: idle: cpuidle: cleanups and fixes and give your opinion about the poll state Peter and I we were discussing ? Regards -- Daniel >> --- >> drivers/acpi/processor_idle.c | 2 -- >> 1 file changed, 2 deletions(-) >> >> diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c >> index 380b4b4..7afba40 100644 >> --- a/drivers/acpi/processor_idle.c >> +++ b/drivers/acpi/processor_idle.c >> @@ -985,8 +985,6 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) >> state->flags = 0; >> switch (cx->type) { >> case ACPI_STATE_C1: >> - if (cx->entry_method != ACPI_CSTATE_FFH) >> - state->flags |= CPUIDLE_FLAG_TIME_INVALID; >> >> state->enter = acpi_idle_enter_c1; >> state->enter_dead = acpi_idle_play_dead; >> >
On Friday, November 21, 2014 10:29:51 AM Daniel Lezcano wrote: > The commit 8e92b6605d introduced the TIME_VALID flag for the C1 state > if this one is a mwait state assuming the interrupt will be enabled > before reading the end time of the idle state. > > The changelog of this commit mention a potential problem with the menu > governor but not a real observation and I assume it described an old > code as the commit is from 2008. > > I have been digging through the code and I didn't find any place where the > interrupts are enabled before reading the time. Moreover with the changes > in the meantime, we moved the time measurements in the cpuidle core as well > as the interrupts enabling making sure the time is measured before the > interrupt are enabled again in a single place. > > Remove this test as the time measurement is always valid for this > state. > > Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Well, I need Len to have a look at this. > --- > drivers/acpi/processor_idle.c | 2 -- > 1 file changed, 2 deletions(-) > > diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c > index 380b4b4..7afba40 100644 > --- a/drivers/acpi/processor_idle.c > +++ b/drivers/acpi/processor_idle.c > @@ -985,8 +985,6 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) > state->flags = 0; > switch (cx->type) { > case ACPI_STATE_C1: > - if (cx->entry_method != ACPI_CSTATE_FFH) > - state->flags |= CPUIDLE_FLAG_TIME_INVALID; > > state->enter = acpi_idle_enter_c1; > state->enter_dead = acpi_idle_play_dead; >
On 11/21/2014 04:01 PM, Daniel Lezcano wrote: > On 11/21/2014 04:05 PM, Rafael J. Wysocki wrote: >> On Friday, November 21, 2014 10:29:51 AM Daniel Lezcano wrote: >>> The commit 8e92b6605d introduced the TIME_VALID flag for the C1 state >>> if this one is a mwait state assuming the interrupt will be enabled >>> before reading the end time of the idle state. >>> >>> The changelog of this commit mention a potential problem with the menu >>> governor but not a real observation and I assume it described an old >>> code as the commit is from 2008. >>> >>> I have been digging through the code and I didn't find any place >>> where the >>> interrupts are enabled before reading the time. Moreover with the >>> changes >>> in the meantime, we moved the time measurements in the cpuidle core >>> as well >>> as the interrupts enabling making sure the time is measured before the >>> interrupt are enabled again in a single place. >>> >>> Remove this test as the time measurement is always valid for this >>> state. >>> >>> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> >> >> Well, I need Len to have a look at this. Hi, any news on that ? Thanks -- Daniel > Ok thanks. > > If you have time, is it possible also you have a look at the patchset I > sent : > > [PATCH V3 0/6] sched: idle: cpuidle: cleanups and fixes > > and give your opinion about the poll state Peter and I we were discussing ? > > Regards > > -- Daniel > >>> --- >>> drivers/acpi/processor_idle.c | 2 -- >>> 1 file changed, 2 deletions(-) >>> >>> diff --git a/drivers/acpi/processor_idle.c >>> b/drivers/acpi/processor_idle.c >>> index 380b4b4..7afba40 100644 >>> --- a/drivers/acpi/processor_idle.c >>> +++ b/drivers/acpi/processor_idle.c >>> @@ -985,8 +985,6 @@ static int >>> acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) >>> state->flags = 0; >>> switch (cx->type) { >>> case ACPI_STATE_C1: >>> - if (cx->entry_method != ACPI_CSTATE_FFH) >>> - state->flags |= CPUIDLE_FLAG_TIME_INVALID; >>> >>> state->enter = acpi_idle_enter_c1; >>> state->enter_dead = acpi_idle_play_dead; >>> >> > >
>>>> The commit 8e92b6605d introduced the TIME_VALID flag for the C1 state >>>> if this one is a mwait state assuming the interrupt will be enabled >>>> before reading the end time of the idle state. ... >>>> I have been digging through the code and I didn't find any place >>>> where the interrupts are enabled before reading the time. Linux is correct as it stands, and the patch proposed here is not correct. Note that on x86, the "STI" instruction enables interrupts: static inline void native_safe_halt(void) { asm volatile("sti; hlt": : :"memory"); } We get here via acpi_safe_halt(), which is invoked with interrupts disabled via the cpuidle enter path. As it needs to return with interrupts disabled, it hacks them off again, but not before the actual interrupt is serviced -- which is what throws off the time-stamps in this path, and why the CPUIDLE_FLAG_TIME_INVALID exists. /* * Callers should disable interrupts before the call and enable * interrupts after return. */ static void acpi_safe_halt(void) { if (!tif_need_resched()) { safe_halt(); local_irq_disable(); } } That said... I think if ladder and menu were more clever, we could delete CPUIDLE_FLAG_TIME_INVALID... Today, we use this flag to set our last_residency to the amount of time until the predicted next timer expires. There are only two cases: First, we could have taken and serviced an interrupt -- all before the timer would have expired. In this case, we are rounding up last_residency to the max, the duration till the next timer would have expired. Second, we could take the timer, and we could service it for a long time, and we'd return a time that is longer than the expected time. So here we are truncating down to the expected duration till the next timer. But in case #1, our "invalid" measurement is actually more accurate than what we are rounding up to. And in case #2, we don't need a flag to detect it -- indeed menu already checks for that case: /* Make sure our coefficients do not exceed unity */ if (measured_us > data->next_timer_us) measured_us = data->next_timer_us; cheers, Len Brown, Intel Open Source Technology Center -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 380b4b4..7afba40 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -985,8 +985,6 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) state->flags = 0; switch (cx->type) { case ACPI_STATE_C1: - if (cx->entry_method != ACPI_CSTATE_FFH) - state->flags |= CPUIDLE_FLAG_TIME_INVALID; state->enter = acpi_idle_enter_c1; state->enter_dead = acpi_idle_play_dead;
The commit 8e92b6605d introduced the TIME_VALID flag for the C1 state if this one is a mwait state assuming the interrupt will be enabled before reading the end time of the idle state. The changelog of this commit mention a potential problem with the menu governor but not a real observation and I assume it described an old code as the commit is from 2008. I have been digging through the code and I didn't find any place where the interrupts are enabled before reading the time. Moreover with the changes in the meantime, we moved the time measurements in the cpuidle core as well as the interrupts enabling making sure the time is measured before the interrupt are enabled again in a single place. Remove this test as the time measurement is always valid for this state. Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> --- drivers/acpi/processor_idle.c | 2 -- 1 file changed, 2 deletions(-)