Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1981

kernel-2.6.18-238.el5.src.rpm

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;