From: Jerome Marchand <jmarchan@redhat.com> Date: Tue, 3 Mar 2009 17:27:25 +0100 Subject: [misc] IO accounting: core statistics Message-id: 20090303162957.433487281@dhcp-0-152.brq.redhat.com O-Subject: [RHEL5.4 Patch 03/12] IO accounting: core statistics Bugzilla: 461636 RH-Acked-by: Jiri Pirko <jpirko@redhat.com> bz461636 Wire up the kernel-private data structures and the accessor functions to manipulate them. Add the auxiliary structure signal_struct_aux to avoid kABI breakage. Patch is upstream: commit 7c3ab7381e79dfc7db14a67c6f4f3285664e1ec2 It also includes fix from 297c5d92634c809cef23d73e7b2556f2528ff7e2 diff --git a/include/linux/sched.h b/include/linux/sched.h index 42883af..eaabf86 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -81,6 +81,7 @@ struct sched_param { #include <linux/resource.h> #include <linux/timer.h> #include <linux/hrtimer.h> +#include <linux/task_io_accounting.h> #include <asm/processor.h> @@ -522,10 +523,13 @@ struct signal_struct { }; struct signal_struct_aux { + u64 rchar, wchar, syscr, syscw; + struct task_io_accounting ioac; }; static inline void init_signal_aux(struct signal_struct_aux *aux) { + memset(aux, 0, sizeof(struct signal_struct_aux)); } struct signal_with_aux_struct { @@ -850,6 +854,7 @@ struct prio_array; struct task_struct_aux { struct completion *vfork_done; /* for vfork() [displaced from task_struct] */ struct list_head *scm_work_list; /*displaced from task_struct for abi compat*/ + struct task_io_accounting ioac; }; #define task_aux(tsk) ((tsk)->auxilliary) diff --git a/include/linux/task_io_accounting.h b/include/linux/task_io_accounting.h new file mode 100644 index 0000000..44d00e9 --- /dev/null +++ b/include/linux/task_io_accounting.h @@ -0,0 +1,37 @@ +/* + * task_io_accounting: a structure which is used for recording a single task's + * IO statistics. + * + * Don't include this header file directly - it is designed to be dragged in via + * sched.h. + * + * Blame akpm@osdl.org for all this. + */ + +#ifdef CONFIG_TASK_IO_ACCOUNTING +struct task_io_accounting { + /* + * The number of bytes which this task has caused to be read from + * storage. + */ + u64 read_bytes; + + /* + * The number of bytes which this task has caused, or shall cause to be + * written to disk. + */ + u64 write_bytes; + + /* + * A task can cause "negative" IO too. If this task truncates some + * dirty pagecache, some IO which another task has been accounted for + * (in its write_bytes) will not be happening. We _could_ just + * subtract that from the truncating task's write_bytes, but there is + * information loss in doing that. + */ + u64 cancelled_write_bytes; +}; +#else +struct task_io_accounting { +}; +#endif diff --git a/include/linux/task_io_accounting_ops.h b/include/linux/task_io_accounting_ops.h new file mode 100644 index 0000000..eeae33b --- /dev/null +++ b/include/linux/task_io_accounting_ops.h @@ -0,0 +1,47 @@ +/* + * Task I/O accounting operations + */ +#ifndef __TASK_IO_ACCOUNTING_OPS_INCLUDED +#define __TASK_IO_ACCOUNTING_OPS_INCLUDED + +#ifdef CONFIG_TASK_IO_ACCOUNTING +static inline void task_io_account_read(size_t bytes) +{ + task_aux(current)->ioac.read_bytes += bytes; +} + +static inline void task_io_account_write(size_t bytes) +{ + task_aux(current)->ioac.write_bytes += bytes; +} + +static inline void task_io_account_cancelled_write(size_t bytes) +{ + task_aux(current)->ioac.cancelled_write_bytes += bytes; +} + +static inline void task_io_accounting_init(struct task_struct *tsk) +{ + memset(&task_aux(tsk)->ioac, 0, sizeof(task_aux(tsk)->ioac)); +} + +#else + +static inline void task_io_account_read(size_t bytes) +{ +} + +static inline void task_io_account_write(size_t bytes) +{ +} + +static inline void task_io_account_cancelled_write(size_t bytes) +{ +} + +static inline void task_io_accounting_init(struct task_struct *tsk) +{ +} + +#endif /* CONFIG_TASK_IO_ACCOUNTING */ +#endif /* __TASK_IO_ACCOUNTING_OPS_INCLUDED */ diff --git a/init/Kconfig b/init/Kconfig index ee0f018..9f130cc 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -183,6 +183,14 @@ config TASK_DELAY_ACCT Say N if unsure. +config TASK_IO_ACCOUNTING + bool "Enable per-task storage I/O accounting (EXPERIMENTAL)" + help + Collect information on the number of bytes of storage I/O which this + task has caused. + + Say N if unsure. + config AUDIT bool "Auditing support" depends on NET diff --git a/kernel/fork.c b/kernel/fork.c index b7508e3..8ef2897 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -36,6 +36,7 @@ #include <linux/syscalls.h> #include <linux/jiffies.h> #include <linux/futex.h> +#include <linux/task_io_accounting_ops.h> #include <linux/rcupdate.h> #include <linux/tracehook.h> #include <linux/mount.h> @@ -1173,6 +1174,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->wchar = 0; /* I/O counter: bytes written */ p->syscr = 0; /* I/O counter: read syscalls */ p->syscw = 0; /* I/O counter: write syscalls */ + task_io_accounting_init(p); acct_clear_integrals(p); p->it_virt_expires = cputime_zero;