|
@@ -2376,29 +2376,82 @@ static int proc_base_fill_cache(struct file *filp, void *dirent,
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_TASK_IO_ACCOUNTING
|
|
|
-static int proc_pid_io_accounting(struct task_struct *task, char *buffer)
|
|
|
-{
|
|
|
+static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
|
|
|
+{
|
|
|
+ u64 rchar, wchar, syscr, syscw;
|
|
|
+ struct task_io_accounting ioac;
|
|
|
+
|
|
|
+ if (!whole) {
|
|
|
+ rchar = task->rchar;
|
|
|
+ wchar = task->wchar;
|
|
|
+ syscr = task->syscr;
|
|
|
+ syscw = task->syscw;
|
|
|
+ memcpy(&ioac, &task->ioac, sizeof(ioac));
|
|
|
+ } else {
|
|
|
+ unsigned long flags;
|
|
|
+ struct task_struct *t = task;
|
|
|
+ rchar = wchar = syscr = syscw = 0;
|
|
|
+ memset(&ioac, 0, sizeof(ioac));
|
|
|
+
|
|
|
+ rcu_read_lock();
|
|
|
+ do {
|
|
|
+ rchar += t->rchar;
|
|
|
+ wchar += t->wchar;
|
|
|
+ syscr += t->syscr;
|
|
|
+ syscw += t->syscw;
|
|
|
+
|
|
|
+ ioac.read_bytes += t->ioac.read_bytes;
|
|
|
+ ioac.write_bytes += t->ioac.write_bytes;
|
|
|
+ ioac.cancelled_write_bytes +=
|
|
|
+ t->ioac.cancelled_write_bytes;
|
|
|
+ t = next_thread(t);
|
|
|
+ } while (t != task);
|
|
|
+ rcu_read_unlock();
|
|
|
+
|
|
|
+ if (lock_task_sighand(task, &flags)) {
|
|
|
+ struct signal_struct *sig = task->signal;
|
|
|
+
|
|
|
+ rchar += sig->rchar;
|
|
|
+ wchar += sig->wchar;
|
|
|
+ syscr += sig->syscr;
|
|
|
+ syscw += sig->syscw;
|
|
|
+
|
|
|
+ ioac.read_bytes += sig->ioac.read_bytes;
|
|
|
+ ioac.write_bytes += sig->ioac.write_bytes;
|
|
|
+ ioac.cancelled_write_bytes +=
|
|
|
+ sig->ioac.cancelled_write_bytes;
|
|
|
+
|
|
|
+ unlock_task_sighand(task, &flags);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return sprintf(buffer,
|
|
|
-#ifdef CONFIG_TASK_XACCT
|
|
|
"rchar: %llu\n"
|
|
|
"wchar: %llu\n"
|
|
|
"syscr: %llu\n"
|
|
|
"syscw: %llu\n"
|
|
|
-#endif
|
|
|
"read_bytes: %llu\n"
|
|
|
"write_bytes: %llu\n"
|
|
|
"cancelled_write_bytes: %llu\n",
|
|
|
-#ifdef CONFIG_TASK_XACCT
|
|
|
- (unsigned long long)task->rchar,
|
|
|
- (unsigned long long)task->wchar,
|
|
|
- (unsigned long long)task->syscr,
|
|
|
- (unsigned long long)task->syscw,
|
|
|
-#endif
|
|
|
- (unsigned long long)task->ioac.read_bytes,
|
|
|
- (unsigned long long)task->ioac.write_bytes,
|
|
|
- (unsigned long long)task->ioac.cancelled_write_bytes);
|
|
|
+ (unsigned long long)rchar,
|
|
|
+ (unsigned long long)wchar,
|
|
|
+ (unsigned long long)syscr,
|
|
|
+ (unsigned long long)syscw,
|
|
|
+ (unsigned long long)ioac.read_bytes,
|
|
|
+ (unsigned long long)ioac.write_bytes,
|
|
|
+ (unsigned long long)ioac.cancelled_write_bytes);
|
|
|
+}
|
|
|
+
|
|
|
+static int proc_tid_io_accounting(struct task_struct *task, char *buffer)
|
|
|
+{
|
|
|
+ return do_io_accounting(task, buffer, 0);
|
|
|
}
|
|
|
-#endif
|
|
|
+
|
|
|
+static int proc_tgid_io_accounting(struct task_struct *task, char *buffer)
|
|
|
+{
|
|
|
+ return do_io_accounting(task, buffer, 1);
|
|
|
+}
|
|
|
+#endif /* CONFIG_TASK_IO_ACCOUNTING */
|
|
|
|
|
|
/*
|
|
|
* Thread groups
|
|
@@ -2470,7 +2523,7 @@ static const struct pid_entry tgid_base_stuff[] = {
|
|
|
REG("coredump_filter", S_IRUGO|S_IWUSR, coredump_filter),
|
|
|
#endif
|
|
|
#ifdef CONFIG_TASK_IO_ACCOUNTING
|
|
|
- INF("io", S_IRUGO, pid_io_accounting),
|
|
|
+ INF("io", S_IRUGO, tgid_io_accounting),
|
|
|
#endif
|
|
|
};
|
|
|
|
|
@@ -2797,6 +2850,9 @@ static const struct pid_entry tid_base_stuff[] = {
|
|
|
#ifdef CONFIG_FAULT_INJECTION
|
|
|
REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject),
|
|
|
#endif
|
|
|
+#ifdef CONFIG_TASK_IO_ACCOUNTING
|
|
|
+ INF("io", S_IRUGO, tid_io_accounting),
|
|
|
+#endif
|
|
|
};
|
|
|
|
|
|
static int proc_tid_base_readdir(struct file * filp,
|