basically, when any process need to do I/O and underlying library calls io_schedule() will put CPU into iowait status and then if the CPU is idle (no other active process running), iowait time increases.
below is related code snip from 3.x kernel:
// in kernel/sched/cputime.c
/*
* Account for idle time.
* @cputime: the cpu time spent in idle wait
*/
void account_idle_time(cputime_t cputime)
{
u64 *cpustat = kcpustat_this_cpu->cpustat;
struct rq *rq = this_rq(); // get running queue of this processor/CPU
if (atomic_read(&rq->nr_iowait) > 0) // if there's process in iowait status
cpustat[CPUTIME_IOWAIT] += (__force u64) cputime;
else
cpustat[CPUTIME_IDLE] += (__force u64) cputime;
}
// in kernel/sched/core.c
//
void __sched io_schedule(void)
{
struct rq *rq = raw_rq();
delayacct_blkio_start();
atomic_inc(&rq->nr_iowait); // before entering schedule()
blk_flush_plug(current);
current->in_iowait = 1;
schedule();
current->in_iowait = 0;
atomic_dec(&rq->nr_iowait); // returned from schedule()
delayacct_blkio_end();
}
below is related code snip from 3.x kernel:
// in kernel/sched/cputime.c
/*
* Account for idle time.
* @cputime: the cpu time spent in idle wait
*/
void account_idle_time(cputime_t cputime)
{
u64 *cpustat = kcpustat_this_cpu->cpustat;
struct rq *rq = this_rq(); // get running queue of this processor/CPU
if (atomic_read(&rq->nr_iowait) > 0) // if there's process in iowait status
cpustat[CPUTIME_IOWAIT] += (__force u64) cputime;
else
cpustat[CPUTIME_IDLE] += (__force u64) cputime;
}
// in kernel/sched/core.c
//
void __sched io_schedule(void)
{
struct rq *rq = raw_rq();
delayacct_blkio_start();
atomic_inc(&rq->nr_iowait); // before entering schedule()
blk_flush_plug(current);
current->in_iowait = 1;
schedule();
current->in_iowait = 0;
atomic_dec(&rq->nr_iowait); // returned from schedule()
delayacct_blkio_end();
}
Comments
Post a Comment