aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2005-01-11 01:40:38 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-11 01:40:38 -0800
commit0a71336b6a8858a525007c5b4e0d14ba57f9f315 (patch)
tree12bf4f03dc9747a5cc401bc53f27fcdee13a7ef8 /fs
parent0fada656bc0fbf5403cb7e629a836bfb77e7c096 (diff)
downloadhistory-0a71336b6a8858a525007c5b4e0d14ba57f9f315.tar.gz
[PATCH] cputime: introduce cputime
This patch introduces the concept of (virtual) cputime. Each architecture can define its method to measure cputime. The main idea is to define a cputime_t type and a set of operations on it (see asm-generic/cputime.h). Then use the type for utime, stime, cutime, cstime, it_virt_value, it_virt_incr, it_prof_value and it_prof_incr and use the cputime operations for each access to these variables. The default implementation is jiffies based and the effect of this patch for architectures which use the default implementation should be neglectible. There is a second type cputime64_t which is necessary for the kernel_stat cpu statistics. The default cputime_t is 32 bit and based on HZ, this will overflow after 49.7 days. This is not enough for kernel_stat (ihmo not enough for a processes too), so it is necessary to have a 64 bit type. The third thing that gets introduced by this patch is an additional field for the /proc/stat interface: cpu steal time. An architecture can account cpu steal time by calls to the account_stealtime function. The cpu which backs a virtual processor doesn't spent all of its time for the virtual cpu. To get meaningful cpu usage numbers this involuntary wait time needs to be accounted and exported to user space. From: Hugh Dickins <hugh@veritas.com> The p->signal check in account_system_time is insufficient. If the timer interrupt hits near the end of exit_notify, after EXIT_ZOMBIE has been set, another cpu may release_task (NULLifying p->signal) in between account_system_time's check and check_rlimit's dereference. Nor should account_it_prof risk send_sig. But surely account_user_time is safe? Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/binfmt_elf.c12
-rw-r--r--fs/proc/array.c22
-rw-r--r--fs/proc/proc_misc.c60
3 files changed, 51 insertions, 43 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 0ecc44fb05513e..eaa2c7026e60cd 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1215,16 +1215,16 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
* this and each other thread to finish dying after the
* core dump synchronization phase.
*/
- jiffies_to_timeval(p->utime + p->signal->utime,
+ cputime_to_timeval(cputime_add(p->utime, p->signal->utime),
&prstatus->pr_utime);
- jiffies_to_timeval(p->stime + p->signal->stime,
+ cputime_to_timeval(cputime_add(p->stime, p->signal->stime),
&prstatus->pr_stime);
} else {
- jiffies_to_timeval(p->utime, &prstatus->pr_utime);
- jiffies_to_timeval(p->stime, &prstatus->pr_stime);
+ cputime_to_timeval(p->utime, &prstatus->pr_utime);
+ cputime_to_timeval(p->stime, &prstatus->pr_stime);
}
- jiffies_to_timeval(p->signal->cutime, &prstatus->pr_cutime);
- jiffies_to_timeval(p->signal->cstime, &prstatus->pr_cstime);
+ cputime_to_timeval(p->signal->cutime, &prstatus->pr_cutime);
+ cputime_to_timeval(p->signal->cstime, &prstatus->pr_cstime);
}
static void fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
diff --git a/fs/proc/array.c b/fs/proc/array.c
index e4bd14aa005d3f..eb5c084ede4ac5 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -313,8 +313,9 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
int num_threads = 0;
struct mm_struct *mm;
unsigned long long start_time;
- unsigned long cmin_flt = 0, cmaj_flt = 0, cutime = 0, cstime = 0;
- unsigned long min_flt = 0, maj_flt = 0, utime = 0, stime = 0;
+ unsigned long cmin_flt = 0, cmaj_flt = 0;
+ unsigned long min_flt = 0, maj_flt = 0;
+ cputime_t cutime, cstime, utime, stime;
unsigned long rsslim = 0;
struct task_struct *t;
char tcomm[sizeof(task->comm)];
@@ -332,6 +333,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
sigemptyset(&sigign);
sigemptyset(&sigcatch);
+ cutime = cstime = utime = stime = cputime_zero;
read_lock(&tasklist_lock);
if (task->sighand) {
spin_lock_irq(&task->sighand->siglock);
@@ -344,8 +346,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
do {
min_flt += t->min_flt;
maj_flt += t->maj_flt;
- utime += t->utime;
- stime += t->stime;
+ utime = cputime_add(utime, t->utime);
+ stime = cputime_add(stime, t->stime);
t = next_thread(t);
} while (t != task);
}
@@ -367,8 +369,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
if (whole) {
min_flt += task->signal->min_flt;
maj_flt += task->signal->maj_flt;
- utime += task->signal->utime;
- stime += task->signal->stime;
+ utime = cputime_add(utime, task->signal->utime);
+ stime = cputime_add(stime, task->signal->stime);
}
}
ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0;
@@ -411,10 +413,10 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
cmin_flt,
maj_flt,
cmaj_flt,
- jiffies_to_clock_t(utime),
- jiffies_to_clock_t(stime),
- jiffies_to_clock_t(cutime),
- jiffies_to_clock_t(cstime),
+ cputime_to_clock_t(utime),
+ cputime_to_clock_t(stime),
+ cputime_to_clock_t(cutime),
+ cputime_to_clock_t(cstime),
priority,
nice,
num_threads,
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index c7322cfefe13bb..89d09007df5d19 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -101,10 +101,10 @@ static int uptime_read_proc(char *page, char **start, off_t off,
struct timespec uptime;
struct timespec idle;
int len;
- u64 idle_jiffies = init_task.utime + init_task.stime;
+ cputime_t idletime = cputime_add(init_task.utime, init_task.stime);
do_posix_clock_monotonic_gettime(&uptime);
- jiffies_to_timespec(idle_jiffies, &idle);
+ cputime_to_timespec(idletime, &idle);
len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
(unsigned long) uptime.tv_sec,
(uptime.tv_nsec / (NSEC_PER_SEC / 100)),
@@ -322,9 +322,11 @@ static int show_stat(struct seq_file *p, void *v)
{
int i;
unsigned long jif;
- u64 sum = 0, user = 0, nice = 0, system = 0,
- idle = 0, iowait = 0, irq = 0, softirq = 0;
+ cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
+ u64 sum = 0;
+ user = nice = system = idle = iowait =
+ irq = softirq = steal = cputime64_zero;
jif = - wall_to_monotonic.tv_sec;
if (wall_to_monotonic.tv_nsec)
--jif;
@@ -332,25 +334,27 @@ static int show_stat(struct seq_file *p, void *v)
for_each_cpu(i) {
int j;
- user += kstat_cpu(i).cpustat.user;
- nice += kstat_cpu(i).cpustat.nice;
- system += kstat_cpu(i).cpustat.system;
- idle += kstat_cpu(i).cpustat.idle;
- iowait += kstat_cpu(i).cpustat.iowait;
- irq += kstat_cpu(i).cpustat.irq;
- softirq += kstat_cpu(i).cpustat.softirq;
+ user = cputime64_add(user, kstat_cpu(i).cpustat.user);
+ nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
+ system = cputime64_add(system, kstat_cpu(i).cpustat.system);
+ idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle);
+ iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait);
+ irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
+ softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
+ steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
for (j = 0 ; j < NR_IRQS ; j++)
sum += kstat_cpu(i).irqs[j];
}
- seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu\n",
- (unsigned long long)jiffies_64_to_clock_t(user),
- (unsigned long long)jiffies_64_to_clock_t(nice),
- (unsigned long long)jiffies_64_to_clock_t(system),
- (unsigned long long)jiffies_64_to_clock_t(idle),
- (unsigned long long)jiffies_64_to_clock_t(iowait),
- (unsigned long long)jiffies_64_to_clock_t(irq),
- (unsigned long long)jiffies_64_to_clock_t(softirq));
+ seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu\n",
+ (unsigned long long)cputime64_to_clock_t(user),
+ (unsigned long long)cputime64_to_clock_t(nice),
+ (unsigned long long)cputime64_to_clock_t(system),
+ (unsigned long long)cputime64_to_clock_t(idle),
+ (unsigned long long)cputime64_to_clock_t(iowait),
+ (unsigned long long)cputime64_to_clock_t(irq),
+ (unsigned long long)cputime64_to_clock_t(softirq),
+ (unsigned long long)cputime64_to_clock_t(steal));
for_each_online_cpu(i) {
/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
@@ -361,15 +365,17 @@ static int show_stat(struct seq_file *p, void *v)
iowait = kstat_cpu(i).cpustat.iowait;
irq = kstat_cpu(i).cpustat.irq;
softirq = kstat_cpu(i).cpustat.softirq;
- seq_printf(p, "cpu%d %llu %llu %llu %llu %llu %llu %llu\n",
+ steal = kstat_cpu(i).cpustat.steal;
+ seq_printf(p, "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu\n",
i,
- (unsigned long long)jiffies_64_to_clock_t(user),
- (unsigned long long)jiffies_64_to_clock_t(nice),
- (unsigned long long)jiffies_64_to_clock_t(system),
- (unsigned long long)jiffies_64_to_clock_t(idle),
- (unsigned long long)jiffies_64_to_clock_t(iowait),
- (unsigned long long)jiffies_64_to_clock_t(irq),
- (unsigned long long)jiffies_64_to_clock_t(softirq));
+ (unsigned long long)cputime64_to_clock_t(user),
+ (unsigned long long)cputime64_to_clock_t(nice),
+ (unsigned long long)cputime64_to_clock_t(system),
+ (unsigned long long)cputime64_to_clock_t(idle),
+ (unsigned long long)cputime64_to_clock_t(iowait),
+ (unsigned long long)cputime64_to_clock_t(irq),
+ (unsigned long long)cputime64_to_clock_t(softirq),
+ (unsigned long long)cputime64_to_clock_t(steal));
}
seq_printf(p, "intr %llu", (unsigned long long)sum);