Ingo, Thomas, Venki, Adam, Ingo sent some sched hooks to acpi_processor_idle() upstream. As the cpuidle in the acpi test branch deleted this function, that results in a merge conflict. The patch below should resolve the conflict -- but to be honest I'm pretty zonked right now and could have easily screwed it up, so give it a look. thanks, -Len diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index c980cbc..00f1f89 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -64,6 +64,7 @@ ACPI_MODULE_NAME("processor_idle"); #define ACPI_PROCESSOR_FILE_POWER "power" #define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000)) +#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) #define C2_OVERHEAD 1 /* 1us */ #define C3_OVERHEAD 1 /* 1us */ @@ -815,6 +816,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, struct acpi_processor *pr; struct acpi_processor_cx *cx = cpuidle_get_statedata(state); u32 t1, t2; + int sleep_ticks; pr = processors[smp_processor_id()]; if (unlikely(!pr)) @@ -841,6 +843,8 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, ACPI_FLUSH_CPU_CACHE(); t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + /* Tell the scheduler that we are going deep-idle: */ + sched_clock_idle_sleep_event(); acpi_state_timer_broadcast(pr, cx, 1); acpi_idle_do_entry(cx); t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); @@ -850,13 +854,23 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, mark_tsc_unstable("TSC halts in idle");; #endif + /* Compute time (ticks) that we were actually asleep */ + sleep_ticks = ticks_elapsed(t1, t2); + + /* Tell the scheduler how much we idled: */ + sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); + local_irq_enable(); current_thread_info()->status |= TS_POLLING; cx->usage++; acpi_state_timer_broadcast(pr, cx, 0); - cx->time += ticks_elapsed(t1, t2); + + /* Do not account our idle-switching overhead: */ + sleep_ticks -= cx->latency_ticks + C2_OVERHEAD; + + cx->time += sleep_ticks; return ticks_elapsed_in_us(t1, t2); } @@ -876,6 +890,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, struct acpi_processor *pr; struct acpi_processor_cx *cx = cpuidle_get_statedata(state); u32 t1, t2; + int sleep_ticks; pr = processors[smp_processor_id()]; if (unlikely(!pr)) @@ -907,6 +922,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, acpi_idle_update_bm_rld(pr, cx); t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + + /* Tell the scheduler that we are going deep-idle: */ + sched_clock_idle_sleep_event(); + acpi_idle_do_entry(cx); t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); } else { @@ -920,6 +939,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, spin_unlock(&c3_lock); t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + + /* Tell the scheduler that we are going deep-idle: */ + sched_clock_idle_sleep_event(); + acpi_idle_do_entry(cx); t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); @@ -936,13 +959,23 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, mark_tsc_unstable("TSC halts in idle"); #endif + /* Compute time (ticks) that we were actually asleep */ + sleep_ticks = ticks_elapsed(t1, t2); + + /* Tell the scheduler how much we idled: */ + sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); + local_irq_enable(); current_thread_info()->status |= TS_POLLING; cx->usage++; acpi_state_timer_broadcast(pr, cx, 0); - cx->time += ticks_elapsed(t1, t2); + + /* Do not account our idle-switching overhead: */ + sleep_ticks -= cx->latency_ticks + C3_OVERHEAD; + + cx->time += sleep_ticks; return ticks_elapsed_in_us(t1, t2); } - To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html