Commit a776ac8d authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] add context switch counters

From: Peter Chubb <peterc@gelato.unsw.edu.au>

Currently, the context switch counters reported by getrusage() are
always zero.  The appended patch adds fields to struct task_struct to
count context switches, and adds code to do the counting.

The patch adds 4 longs to struct task struct, and a single addition to
the fast path in schedule().
parent 88907397
...@@ -391,6 +391,7 @@ struct task_struct { ...@@ -391,6 +391,7 @@ struct task_struct {
struct timer_list real_timer; struct timer_list real_timer;
struct list_head posix_timers; /* POSIX.1b Interval Timers */ struct list_head posix_timers; /* POSIX.1b Interval Timers */
unsigned long utime, stime, cutime, cstime; unsigned long utime, stime, cutime, cstime;
unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; /* context switch counts */
u64 start_time; u64 start_time;
/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap; unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
......
...@@ -80,6 +80,8 @@ void release_task(struct task_struct * p) ...@@ -80,6 +80,8 @@ void release_task(struct task_struct * p)
p->parent->cmin_flt += p->min_flt + p->cmin_flt; p->parent->cmin_flt += p->min_flt + p->cmin_flt;
p->parent->cmaj_flt += p->maj_flt + p->cmaj_flt; p->parent->cmaj_flt += p->maj_flt + p->cmaj_flt;
p->parent->cnswap += p->nswap + p->cnswap; p->parent->cnswap += p->nswap + p->cnswap;
p->parent->cnvcsw += p->nvcsw + p->cnvcsw;
p->parent->cnivcsw += p->nivcsw + p->cnivcsw;
sched_exit(p); sched_exit(p);
write_unlock_irq(&tasklist_lock); write_unlock_irq(&tasklist_lock);
spin_unlock(&p->proc_lock); spin_unlock(&p->proc_lock);
......
...@@ -461,6 +461,7 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) ...@@ -461,6 +461,7 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
tsk->min_flt = tsk->maj_flt = 0; tsk->min_flt = tsk->maj_flt = 0;
tsk->cmin_flt = tsk->cmaj_flt = 0; tsk->cmin_flt = tsk->cmaj_flt = 0;
tsk->nswap = tsk->cnswap = 0; tsk->nswap = tsk->cnswap = 0;
tsk->nvcsw = tsk->nivcsw = tsk->cnvcsw = tsk->cnivcsw = 0;
tsk->mm = NULL; tsk->mm = NULL;
tsk->active_mm = NULL; tsk->active_mm = NULL;
......
...@@ -1325,8 +1325,10 @@ asmlinkage void schedule(void) ...@@ -1325,8 +1325,10 @@ asmlinkage void schedule(void)
} }
default: default:
deactivate_task(prev, rq); deactivate_task(prev, rq);
prev->nvcsw++;
break;
case TASK_RUNNING: case TASK_RUNNING:
; prev->nivcsw++;
} }
pick_next_task: pick_next_task:
if (unlikely(!rq->nr_running)) { if (unlikely(!rq->nr_running)) {
......
...@@ -1309,6 +1309,8 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru) ...@@ -1309,6 +1309,8 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
case RUSAGE_SELF: case RUSAGE_SELF:
jiffies_to_timeval(p->utime, &r.ru_utime); jiffies_to_timeval(p->utime, &r.ru_utime);
jiffies_to_timeval(p->stime, &r.ru_stime); jiffies_to_timeval(p->stime, &r.ru_stime);
r.ru_nvcsw = p->nvcsw;
r.ru_nivcsw = p->nivcsw;
r.ru_minflt = p->min_flt; r.ru_minflt = p->min_flt;
r.ru_majflt = p->maj_flt; r.ru_majflt = p->maj_flt;
r.ru_nswap = p->nswap; r.ru_nswap = p->nswap;
...@@ -1316,6 +1318,8 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru) ...@@ -1316,6 +1318,8 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
case RUSAGE_CHILDREN: case RUSAGE_CHILDREN:
jiffies_to_timeval(p->cutime, &r.ru_utime); jiffies_to_timeval(p->cutime, &r.ru_utime);
jiffies_to_timeval(p->cstime, &r.ru_stime); jiffies_to_timeval(p->cstime, &r.ru_stime);
r.ru_nvcsw = p->cnvcsw;
r.ru_nivcsw = p->cnivcsw;
r.ru_minflt = p->cmin_flt; r.ru_minflt = p->cmin_flt;
r.ru_majflt = p->cmaj_flt; r.ru_majflt = p->cmaj_flt;
r.ru_nswap = p->cnswap; r.ru_nswap = p->cnswap;
...@@ -1323,6 +1327,8 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru) ...@@ -1323,6 +1327,8 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
default: default:
jiffies_to_timeval(p->utime + p->cutime, &r.ru_utime); jiffies_to_timeval(p->utime + p->cutime, &r.ru_utime);
jiffies_to_timeval(p->stime + p->cstime, &r.ru_stime); jiffies_to_timeval(p->stime + p->cstime, &r.ru_stime);
r.ru_nvcsw = p->nvcsw + p->cnvcsw;
r.ru_nivcsw = p->nivcsw + p->cnivcsw;
r.ru_minflt = p->min_flt + p->cmin_flt; r.ru_minflt = p->min_flt + p->cmin_flt;
r.ru_majflt = p->maj_flt + p->cmaj_flt; r.ru_majflt = p->maj_flt + p->cmaj_flt;
r.ru_nswap = p->nswap + p->cnswap; r.ru_nswap = p->nswap + p->cnswap;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment