Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b663a79c191508f27cd885224b592a878c0ba0f6
Commit:     b663a79c191508f27cd885224b592a878c0ba0f6
Parent:     a6c15c2b0fbfd5c0a84f5f0e1e3f20f85d2b8692
Author:     Maxim Uvarov <[EMAIL PROTECTED]>
AuthorDate: Sun Jul 15 23:40:48 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Mon Jul 16 09:05:46 2007 -0700

    taskstats: add context-switch counters
    
    Make available to the user the following task and process performance
    statistics:
    
        * Involuntary Context Switches (task_struct->nivcsw)
        * Voluntary Context Switches (task_struct->nvcsw)
    
    Statistics information is available from:
        1. taskstats interface (Documentation/accounting/)
        2. /proc/PID/status (task only).
    
    This data is useful for detecting hyperactivity patterns between processes.
    
    [EMAIL PROTECTED]: cleanup]
    Signed-off-by: Maxim Uvarov <[EMAIL PROTECTED]>
    Cc: Shailabh Nagar <[EMAIL PROTECTED]>
    Cc: Balbir Singh <[EMAIL PROTECTED]>
    Cc: Jay Lan <[EMAIL PROTECTED]>
    Cc: Jonathan Lim <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 Documentation/accounting/getdelays.c          |   19 +++++++++++++++++--
 Documentation/accounting/taskstats-struct.txt |    6 ++++++
 fs/proc/array.c                               |   10 ++++++++++
 include/linux/taskstats.h                     |    5 ++++-
 kernel/taskstats.c                            |    4 ++++
 5 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/Documentation/accounting/getdelays.c 
b/Documentation/accounting/getdelays.c
index 71acc28..24c5aad 100644
--- a/Documentation/accounting/getdelays.c
+++ b/Documentation/accounting/getdelays.c
@@ -49,6 +49,7 @@ char name[100];
 int dbg;
 int print_delays;
 int print_io_accounting;
+int print_task_context_switch_counts;
 __u64 stime, utime;
 
 #define PRINTF(fmt, arg...) {                  \
@@ -195,7 +196,7 @@ void print_delayacct(struct taskstats *t)
               "IO    %15s%15s\n"
               "      %15llu%15llu\n"
               "MEM   %15s%15s\n"
-              "      %15llu%15llu\n\n",
+              "      %15llu%15llu\n"
               "count", "real total", "virtual total", "delay total",
               t->cpu_count, t->cpu_run_real_total, t->cpu_run_virtual_total,
               t->cpu_delay_total,
@@ -204,6 +205,14 @@ void print_delayacct(struct taskstats *t)
               "count", "delay total", t->swapin_count, t->swapin_delay_total);
 }
 
+void task_context_switch_counts(struct taskstats *t)
+{
+       printf("\n\nTask   %15s%15s\n"
+              "       %15lu%15lu\n",
+              "voluntary", "nonvoluntary",
+              t->nvcsw, t->nivcsw);
+}
+
 void print_ioacct(struct taskstats *t)
 {
        printf("%s: read=%llu, write=%llu, cancelled_write=%llu\n",
@@ -235,7 +244,7 @@ int main(int argc, char *argv[])
        struct msgtemplate msg;
 
        while (1) {
-               c = getopt(argc, argv, "diw:r:m:t:p:vl");
+               c = getopt(argc, argv, "qdiw:r:m:t:p:vl");
                if (c < 0)
                        break;
 
@@ -248,6 +257,10 @@ int main(int argc, char *argv[])
                        printf("printing IO accounting\n");
                        print_io_accounting = 1;
                        break;
+               case 'q':
+                       printf("printing task/process context switch rates\n");
+                       print_task_context_switch_counts = 1;
+                       break;
                case 'w':
                        logfile = strdup(optarg);
                        printf("write to file %s\n", logfile);
@@ -389,6 +402,8 @@ int main(int argc, char *argv[])
                                                        print_delayacct((struct 
taskstats *) NLA_DATA(na));
                                                if (print_io_accounting)
                                                        print_ioacct((struct 
taskstats *) NLA_DATA(na));
+                                               if 
(print_task_context_switch_counts)
+                                                       
task_context_switch_counts((struct taskstats *) NLA_DATA(na));
                                                if (fd) {
                                                        if (write(fd, 
NLA_DATA(na), na->nla_len) < 0) {
                                                                err(1,"write 
error\n");
diff --git a/Documentation/accounting/taskstats-struct.txt 
b/Documentation/accounting/taskstats-struct.txt
index 661c797..8aa7529 100644
--- a/Documentation/accounting/taskstats-struct.txt
+++ b/Documentation/accounting/taskstats-struct.txt
@@ -22,6 +22,8 @@ There are three different groups of fields in the struct 
taskstats:
     /* Extended accounting fields end */
     Their values are collected if CONFIG_TASK_XACCT is set.
 
+4) Per-task and per-thread context switch count statistics
+
 Future extension should add fields to the end of the taskstats struct, and
 should not change the relative position of each field within the struct.
 
@@ -158,4 +160,8 @@ struct taskstats {
 
        /* Extended accounting fields end */
 
+4) Per-task and per-thread statistics
+       __u64   nvcsw;                  /* Context voluntary switch counter */
+       __u64   nivcsw;                 /* Context involuntary switch counter */
+
 }
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 680c913..9cbab7e 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -289,6 +289,15 @@ static inline char *task_cap(struct task_struct *p, char 
*buffer)
                            cap_t(p->cap_effective));
 }
 
+static inline char *task_context_switch_counts(struct task_struct *p,
+                                               char *buffer)
+{
+       return buffer + sprintf(buffer, "voluntary_ctxt_switches:\t%lu\n"
+                           "nonvoluntary_ctxt_switches:\t%lu\n",
+                           p->nvcsw,
+                           p->nivcsw);
+}
+
 int proc_pid_status(struct task_struct *task, char * buffer)
 {
        char * orig = buffer;
@@ -307,6 +316,7 @@ int proc_pid_status(struct task_struct *task, char * buffer)
 #if defined(CONFIG_S390)
        buffer = task_show_regs(task, buffer);
 #endif
+       buffer = task_context_switch_counts(task, buffer);
        return buffer - orig;
 }
 
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h
index a46104a..dce1ed2 100644
--- a/include/linux/taskstats.h
+++ b/include/linux/taskstats.h
@@ -31,7 +31,7 @@
  */
 
 
-#define TASKSTATS_VERSION      4
+#define TASKSTATS_VERSION      5
 #define TS_COMM_LEN            32      /* should be >= TASK_COMM_LEN
                                         * in linux/sched.h */
 
@@ -149,6 +149,9 @@ struct taskstats {
        __u64   read_bytes;             /* bytes of read I/O */
        __u64   write_bytes;            /* bytes of write I/O */
        __u64   cancelled_write_bytes;  /* bytes of cancelled write I/O */
+
+       __u64  nvcsw;                   /* voluntary_ctxt_switches */
+       __u64  nivcsw;                  /* nonvoluntary_ctxt_switches */
 };
 
 
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 906cae7..059431e 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -196,6 +196,8 @@ static int fill_pid(pid_t pid, struct task_struct *tsk,
 
        /* fill in basic acct fields */
        stats->version = TASKSTATS_VERSION;
+       stats->nvcsw = tsk->nvcsw;
+       stats->nivcsw = tsk->nivcsw;
        bacct_add_tsk(stats, tsk);
 
        /* fill in extended acct fields */
@@ -242,6 +244,8 @@ static int fill_tgid(pid_t tgid, struct task_struct *first,
                 */
                delayacct_add_tsk(stats, tsk);
 
+               stats->nvcsw += tsk->nvcsw;
+               stats->nivcsw += tsk->nivcsw;
        } while_each_thread(first, tsk);
 
        unlock_task_sighand(first, &flags);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to