So what's wrong with something like: struct cpu_idletime { seqlock_t seqlock; unsigned long nr_iowait; u64 start; u64 idle_time, u64 iowait_time, } __cacheline_aligned_in_smp;
DEFINE_PER_CPU(struct cpu_idletime, cpu_idletime); void io_schedule(void) { struct cpu_idletime *it = __raw_get_cpu_var(cpu_idletime); write_seqlock(&it->seqlock); if (!it->nr_iowait++) it->start = local_clock(); write_sequnlock(&it->seqlock); current->in_iowait = 1; schedule(); current->in_iowait = 0; write_seqlock(&it->seqlock); if (!--it->nr_iowait) it->iowait_time += local_clock() - it->start; write_sequnlock(&it->seqlock); } Afaict you don't need the preempt disable and atomic muck at all. It will all get a little more complicated to deal with overlapping idle and iowait times, but the idea is the same. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/