[Patch 5/6] Delay accounting: /proc interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Changes since 12/7/05
- Return per-tgid stats as sum of constituent tid data
- for cpu running time, use tsk->sched_info.cpu_time (collected by schedstats)

12/07/05: First post

delayacct-procfs.patch

Creates /proc/<pid>/delay interface for getting delay and cpu statistics
for tasks. The cpu stats are available (non-zero) only if CONFIG_SCHEDSTATS
is enabled.

Signed-off-by: Shailabh Nagar <[email protected]>

 fs/proc/array.c    |   68 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/proc/base.c     |   21 +++++++++++++++-
 fs/proc/internal.h |    2 +
 3 files changed, 90 insertions(+), 1 deletion(-)

Index: linux-2.6.15-rc7/fs/proc/array.c
===================================================================
--- linux-2.6.15-rc7.orig/fs/proc/array.c
+++ linux-2.6.15-rc7/fs/proc/array.c
@@ -488,3 +488,71 @@ int proc_pid_statm(struct task_struct *t
 	return sprintf(buffer,"%d %d %d %d %d %d %d\n",
 		       size, resident, shared, text, lib, data, 0);
 }
+
+#ifdef CONFIG_TASK_DELAY_ACCT
+int proc_pid_delay(struct task_struct *task, char * buffer)
+{
+	unsigned long long run_delay, run_time;
+	unsigned long run_count;
+
+#ifdef CONFIG_SCHEDSTATS
+	run_count = task->sched_info.pcnt ;
+	run_time = jiffies_to_usecs(task->sched_info.cpu_time)*1000;
+	run_delay = jiffies_to_usecs(task->sched_info.run_delay)*1000;
+#else
+	/* Non-zero values, zero count indicates data not collected */
+	run_count = 0;
+	run_time = run_delay = 1;
+#endif
+	return sprintf(buffer,"%lu %llu %llu %u %llu %u %llu\n",
+		       run_count, (uint64_t) run_time, (uint64_t) run_delay,
+		       (unsigned int) task->delays.blkio_count,
+		       (uint64_t) task->delays.blkio_delay,
+		       (unsigned int) task->delays.swapin_count,
+		       (uint64_t) task->delays.swapin_delay);
+}
+
+/*
+ * Sum up delay stats for tid's of the tgid
+ * For any delay stat, a zero delay and non-zero count indicates overflow
+ *
+ */
+int proc_tgid_delay(struct task_struct *task, char * buffer)
+{
+	uint64_t run_time = 0, run_delay = 0, run_count = 0;
+	uint64_t blkio_delay = 0, blkio_count = 0;
+	uint64_t swapin_delay = 0, swapin_count = 0, tmp;
+	struct task_struct *t = task;
+
+	read_lock(&tasklist_lock);
+	do {
+#ifdef CONFIG_SCHEDSTATS
+		run_count += t->sched_info.pcnt;
+		tmp = run_time + jiffies_to_usecs(t->sched_info.cpu_time)*1000;
+		run_time = (tmp < run_time)? 0:tmp ;
+		tmp = run_delay + jiffies_to_usecs(t->sched_info.run_delay)*1000;
+		run_delay = (tmp < run_delay)? 0:tmp;
+#else
+		/* Non-zero values, zero count indicates data not collected */
+		run_count = 0;
+		run_time = run_delay = 1;
+#endif
+		spin_lock(&t->delays.lock);
+		tmp = blkio_delay + t->delays.blkio_delay;
+		blkio_delay = (tmp < blkio_delay)? 0:tmp ;
+		tmp = swapin_delay + t->delays.swapin_delay;
+		swapin_delay = (tmp < swapin_delay)? 0:tmp ;
+		blkio_count += t->delays.blkio_count;
+		swapin_count += t->delays.swapin_count;
+		spin_unlock(&t->delays.lock);
+
+	} while_each_thread(task, t);
+	read_unlock(&tasklist_lock);
+
+	return sprintf(buffer,"%llu %llu %llu %llu %llu %llu %llu\n",
+		       run_count, run_time, run_delay,
+		       blkio_count, blkio_delay,
+		       swapin_count, swapin_delay);
+}
+
+#endif
Index: linux-2.6.15-rc7/fs/proc/base.c
===================================================================
--- linux-2.6.15-rc7.orig/fs/proc/base.c
+++ linux-2.6.15-rc7/fs/proc/base.c
@@ -165,7 +165,10 @@ enum pid_directory_inos {
 #endif
 	PROC_TID_OOM_SCORE,
 	PROC_TID_OOM_ADJUST,
-
+#ifdef CONFIG_TASK_DELAY_ACCT
+        PROC_TID_DELAY_ACCT,
+        PROC_TGID_DELAY_ACCT,
+#endif
 	/* Add new entries before this */
 	PROC_TID_FD_DIR = 0x8000,	/* 0x8000-0xffff */
 };
@@ -220,6 +223,9 @@ static struct pid_entry tgid_base_stuff[
 #ifdef CONFIG_AUDITSYSCALL
 	E(PROC_TGID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
 #endif
+#ifdef CONFIG_TASK_DELAY_ACCT
+	E(PROC_TGID_DELAY_ACCT,"delay",   S_IFREG|S_IRUGO),
+#endif
 	{0,0,NULL,0}
 };
 static struct pid_entry tid_base_stuff[] = {
@@ -262,6 +268,9 @@ static struct pid_entry tid_base_stuff[]
 #ifdef CONFIG_AUDITSYSCALL
 	E(PROC_TID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
 #endif
+#ifdef CONFIG_TASK_DELAY_ACCT
+	E(PROC_TID_DELAY_ACCT,"delay",   S_IFREG|S_IRUGO),
+#endif
 	{0,0,NULL,0}
 };

@@ -1786,6 +1795,16 @@ static struct dentry *proc_pident_lookup
 			inode->i_fop = &proc_loginuid_operations;
 			break;
 #endif
+#ifdef CONFIG_TASK_DELAY_ACCT
+		case PROC_TID_DELAY_ACCT:
+			inode->i_fop = &proc_info_file_operations;
+			ei->op.proc_read = proc_pid_delay;
+			break;
+		case PROC_TGID_DELAY_ACCT:
+			inode->i_fop = &proc_info_file_operations;
+			ei->op.proc_read = proc_tgid_delay;
+			break;
+#endif
 		default:
 			printk("procfs: impossible type (%d)",p->type);
 			iput(inode);
Index: linux-2.6.15-rc7/fs/proc/internal.h
===================================================================
--- linux-2.6.15-rc7.orig/fs/proc/internal.h
+++ linux-2.6.15-rc7/fs/proc/internal.h
@@ -36,6 +36,8 @@ extern int proc_tid_stat(struct task_str
 extern int proc_tgid_stat(struct task_struct *, char *);
 extern int proc_pid_status(struct task_struct *, char *);
 extern int proc_pid_statm(struct task_struct *, char *);
+extern int proc_pid_delay(struct task_struct *, char*);
+extern int proc_tgid_delay(struct task_struct *, char*);

 static inline struct task_struct *proc_task(struct inode *inode)
 {
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux