aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/array.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2007-07-09 12:51:59 -0400
committerIngo Molnar <mingo@elte.hu>2007-07-09 12:51:59 -0400
commitb27f03d4bdc145a09fb7b0c0e004b29f1ee555fa (patch)
tree37b918b7dcc548671db53d4f3c2fdc673939e086 /fs/proc/array.c
parent1b9f19c2125dd1021b9327111dc40b14b557ee12 (diff)
sched: make use of precise accounting for /proc task stats
make use of CFS's precise accounting to drive /proc/<pid>/stat statistics. this code was co-authored by: Balbir Singh <balbir@linux.vnet.ibm.com> Dmitry Adamushko <dmitry.adamushko@gmail.com> Ingo Molnar <mingo@elte.hu> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Dmitry Adamushko <dmitry.adamushko@gmail.com>
Diffstat (limited to 'fs/proc/array.c')
-rw-r--r--fs/proc/array.c57
1 files changed, 47 insertions, 10 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 3df644313f9b..98e78e2f18d6 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -310,6 +310,41 @@ int proc_pid_status(struct task_struct *task, char * buffer)
310 return buffer - orig; 310 return buffer - orig;
311} 311}
312 312
313static clock_t task_utime(struct task_struct *p)
314{
315 clock_t utime = cputime_to_clock_t(p->utime),
316 total = utime + cputime_to_clock_t(p->stime);
317 u64 temp;
318
319 /*
320 * Use CFS's precise accounting:
321 */
322 temp = (u64)nsec_to_clock_t(p->se.sum_exec_runtime);
323
324 if (total) {
325 temp *= utime;
326 do_div(temp, total);
327 }
328 utime = (clock_t)temp;
329
330 return utime;
331}
332
333static clock_t task_stime(struct task_struct *p)
334{
335 clock_t stime = cputime_to_clock_t(p->stime);
336
337 /*
338 * Use CFS's precise accounting. (we subtract utime from
339 * the total, to make sure the total observed by userspace
340 * grows monotonically - apps rely on that):
341 */
342 stime = nsec_to_clock_t(p->se.sum_exec_runtime) - task_utime(p);
343
344 return stime;
345}
346
347
313static int do_task_stat(struct task_struct *task, char * buffer, int whole) 348static int do_task_stat(struct task_struct *task, char * buffer, int whole)
314{ 349{
315 unsigned long vsize, eip, esp, wchan = ~0UL; 350 unsigned long vsize, eip, esp, wchan = ~0UL;
@@ -324,7 +359,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
324 unsigned long long start_time; 359 unsigned long long start_time;
325 unsigned long cmin_flt = 0, cmaj_flt = 0; 360 unsigned long cmin_flt = 0, cmaj_flt = 0;
326 unsigned long min_flt = 0, maj_flt = 0; 361 unsigned long min_flt = 0, maj_flt = 0;
327 cputime_t cutime, cstime, utime, stime; 362 cputime_t cutime, cstime;
363 clock_t utime, stime;
328 unsigned long rsslim = 0; 364 unsigned long rsslim = 0;
329 char tcomm[sizeof(task->comm)]; 365 char tcomm[sizeof(task->comm)];
330 unsigned long flags; 366 unsigned long flags;
@@ -342,7 +378,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
342 378
343 sigemptyset(&sigign); 379 sigemptyset(&sigign);
344 sigemptyset(&sigcatch); 380 sigemptyset(&sigcatch);
345 cutime = cstime = utime = stime = cputime_zero; 381 cutime = cstime = cputime_zero;
382 utime = stime = 0;
346 383
347 rcu_read_lock(); 384 rcu_read_lock();
348 if (lock_task_sighand(task, &flags)) { 385 if (lock_task_sighand(task, &flags)) {
@@ -368,15 +405,15 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
368 do { 405 do {
369 min_flt += t->min_flt; 406 min_flt += t->min_flt;
370 maj_flt += t->maj_flt; 407 maj_flt += t->maj_flt;
371 utime = cputime_add(utime, t->utime); 408 utime += task_utime(t);
372 stime = cputime_add(stime, t->stime); 409 stime += task_stime(t);
373 t = next_thread(t); 410 t = next_thread(t);
374 } while (t != task); 411 } while (t != task);
375 412
376 min_flt += sig->min_flt; 413 min_flt += sig->min_flt;
377 maj_flt += sig->maj_flt; 414 maj_flt += sig->maj_flt;
378 utime = cputime_add(utime, sig->utime); 415 utime += cputime_to_clock_t(sig->utime);
379 stime = cputime_add(stime, sig->stime); 416 stime += cputime_to_clock_t(sig->stime);
380 } 417 }
381 418
382 sid = signal_session(sig); 419 sid = signal_session(sig);
@@ -392,8 +429,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
392 if (!whole) { 429 if (!whole) {
393 min_flt = task->min_flt; 430 min_flt = task->min_flt;
394 maj_flt = task->maj_flt; 431 maj_flt = task->maj_flt;
395 utime = task->utime; 432 utime = task_utime(task);
396 stime = task->stime; 433 stime = task_stime(task);
397 } 434 }
398 435
399 /* scale priority and nice values from timeslices to -20..20 */ 436 /* scale priority and nice values from timeslices to -20..20 */
@@ -424,8 +461,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
424 cmin_flt, 461 cmin_flt,
425 maj_flt, 462 maj_flt,
426 cmaj_flt, 463 cmaj_flt,
427 cputime_to_clock_t(utime), 464 utime,
428 cputime_to_clock_t(stime), 465 stime,
429 cputime_to_clock_t(cutime), 466 cputime_to_clock_t(cutime),
430 cputime_to_clock_t(cstime), 467 cputime_to_clock_t(cstime),
431 priority, 468 priority,