NFS上のファイルへのI/O待ちは %iowait、%sys のどちらに計上されるか?

NFS上のファイルへのI/O待ちが %iowait、%sys のどちらに計上されるのとかという話。
NFS でなんであれ、Linux でいうと、I/Oを発行したプロセスまたはスレッドが

  • TASK_INTERRUPTIBLE でスリープしていれば %idle に
  • TASK_UNINTERRUPTIBLE でスリープしていれば %iowait に
  • 非同期I/Oを行ってほとんどスリープしていなければ %user(ユーザーモードでの実行時間が) と %sys(カーネルモードでの実行時間が) に

計上されると思う。
なので、実装次第で変わると思う。当然、OS の NFS クライアントを使うか Oracle Database の DirectNFS を使うかでは違うと思う。
vmstat は /proc/stat を参照して表示しているだけで、プロセスアカウンティングは kernel/sched.c あたりでやっていると思う。

  • kernel/sched.c
/*
 *  kernel/sched.c
 *
 *  Kernel scheduler and related syscalls
 *
 *  Copyright (C) 1991-2002  Linus Torvalds
 *
 *  1996-12-23  Modified by Dave Grothe to fix bugs in semaphores and
 *		make semaphores SMP safe
 *  1998-11-19	Implemented schedule_timeout() and related stuff
 *		by Andrea Arcangeli
 *  2002-01-04	New ultra-scalable O(1) scheduler by Ingo Molnar:
 *		hybrid priority-list and round-robin design with
 *		an array-switch method of distributing timeslices
 *		and per-CPU runqueues.  Cleanups and useful suggestions
 *		by Davide Libenzi, preemptible kernel bits by Robert Love.
 *  2003-09-03	Interactivity tuning by Con Kolivas.
 *  2004-04-02	Scheduler domains code by Nick Piggin
 *  2007-04-15  Work begun on replacing all interactivity tuning with a
 *              fair scheduling design by Con Kolivas.
 *  2007-05-05  Load balancing (smp-nice) and other improvements
 *              by Peter Williams
 *  2007-05-06  Interactivity improvements to CFS by Mike Galbraith
 *  2007-07-01  Group scheduling enhancements by Srivatsa Vaddagiri
 *  2007-11-29  RT balancing improvements by Steven Rostedt, Gregory Haskins,
 *              Thomas Gleixner, Mike Kravetz
 */
 
(中略)

/*
 * Account for idle time.
 * @cputime: the cpu time spent in idle wait
 */
void account_idle_time(cputime_t cputime)
{
	struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
	cputime64_t cputime64 = cputime_to_cputime64(cputime);
	struct rq *rq = this_rq();

	if (atomic_read(&rq->nr_iowait) > 0)
		cpustat->iowait = cputime64_add(cpustat->iowait, cputime64);
	else
		cpustat->idle = cputime64_add(cpustat->idle, cputime64);
}

時間のあるときに strace や DTrace でトレースとったり、Linux Kernel のソースやらから動的・静的の両面から調べてみよう。