aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/acct.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/acct.c')
-rw-r--r--kernel/acct.c125
1 files changed, 76 insertions, 49 deletions
diff --git a/kernel/acct.c b/kernel/acct.c
index 6802020e0ceb..f4330acead46 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -43,7 +43,6 @@
43 * a struct file opened for write. Fixed. 2/6/2000, AV. 43 * a struct file opened for write. Fixed. 2/6/2000, AV.
44 */ 44 */
45 45
46#include <linux/config.h>
47#include <linux/mm.h> 46#include <linux/mm.h>
48#include <linux/slab.h> 47#include <linux/slab.h>
49#include <linux/acct.h> 48#include <linux/acct.h>
@@ -75,7 +74,7 @@ int acct_parm[3] = {4, 2, 30};
75/* 74/*
76 * External references and all of the globals. 75 * External references and all of the globals.
77 */ 76 */
78static void do_acct_process(long, struct file *); 77static void do_acct_process(struct file *);
79 78
80/* 79/*
81 * This structure is used so that all the data protected by lock 80 * This structure is used so that all the data protected by lock
@@ -196,7 +195,7 @@ static void acct_file_reopen(struct file *file)
196 if (old_acct) { 195 if (old_acct) {
197 mnt_unpin(old_acct->f_vfsmnt); 196 mnt_unpin(old_acct->f_vfsmnt);
198 spin_unlock(&acct_globals.lock); 197 spin_unlock(&acct_globals.lock);
199 do_acct_process(0, old_acct); 198 do_acct_process(old_acct);
200 filp_close(old_acct, NULL); 199 filp_close(old_acct, NULL);
201 spin_lock(&acct_globals.lock); 200 spin_lock(&acct_globals.lock);
202 } 201 }
@@ -419,16 +418,15 @@ static u32 encode_float(u64 value)
419/* 418/*
420 * do_acct_process does all actual work. Caller holds the reference to file. 419 * do_acct_process does all actual work. Caller holds the reference to file.
421 */ 420 */
422static void do_acct_process(long exitcode, struct file *file) 421static void do_acct_process(struct file *file)
423{ 422{
423 struct pacct_struct *pacct = &current->signal->pacct;
424 acct_t ac; 424 acct_t ac;
425 mm_segment_t fs; 425 mm_segment_t fs;
426 unsigned long vsize;
427 unsigned long flim; 426 unsigned long flim;
428 u64 elapsed; 427 u64 elapsed;
429 u64 run_time; 428 u64 run_time;
430 struct timespec uptime; 429 struct timespec uptime;
431 unsigned long jiffies;
432 430
433 /* 431 /*
434 * First check to see if there is enough free_space to continue 432 * First check to see if there is enough free_space to continue
@@ -469,12 +467,6 @@ static void do_acct_process(long exitcode, struct file *file)
469#endif 467#endif
470 do_div(elapsed, AHZ); 468 do_div(elapsed, AHZ);
471 ac.ac_btime = xtime.tv_sec - elapsed; 469 ac.ac_btime = xtime.tv_sec - elapsed;
472 jiffies = cputime_to_jiffies(cputime_add(current->utime,
473 current->signal->utime));
474 ac.ac_utime = encode_comp_t(jiffies_to_AHZ(jiffies));
475 jiffies = cputime_to_jiffies(cputime_add(current->stime,
476 current->signal->stime));
477 ac.ac_stime = encode_comp_t(jiffies_to_AHZ(jiffies));
478 /* we really need to bite the bullet and change layout */ 470 /* we really need to bite the bullet and change layout */
479 ac.ac_uid = current->uid; 471 ac.ac_uid = current->uid;
480 ac.ac_gid = current->gid; 472 ac.ac_gid = current->gid;
@@ -491,42 +483,27 @@ static void do_acct_process(long exitcode, struct file *file)
491 ac.ac_ppid = current->parent->tgid; 483 ac.ac_ppid = current->parent->tgid;
492#endif 484#endif
493 485
494 read_lock(&tasklist_lock); /* pin current->signal */ 486 mutex_lock(&tty_mutex);
487 /* FIXME: Whoever is responsible for current->signal locking needs
488 to use the same locking all over the kernel and document it */
489 read_lock(&tasklist_lock);
495 ac.ac_tty = current->signal->tty ? 490 ac.ac_tty = current->signal->tty ?
496 old_encode_dev(tty_devnum(current->signal->tty)) : 0; 491 old_encode_dev(tty_devnum(current->signal->tty)) : 0;
497 read_unlock(&tasklist_lock); 492 read_unlock(&tasklist_lock);
498 493 mutex_unlock(&tty_mutex);
499 ac.ac_flag = 0; 494
500 if (current->flags & PF_FORKNOEXEC) 495 spin_lock_irq(&current->sighand->siglock);
501 ac.ac_flag |= AFORK; 496 ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime)));
502 if (current->flags & PF_SUPERPRIV) 497 ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime)));
503 ac.ac_flag |= ASU; 498 ac.ac_flag = pacct->ac_flag;
504 if (current->flags & PF_DUMPCORE) 499 ac.ac_mem = encode_comp_t(pacct->ac_mem);
505 ac.ac_flag |= ACORE; 500 ac.ac_minflt = encode_comp_t(pacct->ac_minflt);
506 if (current->flags & PF_SIGNALED) 501 ac.ac_majflt = encode_comp_t(pacct->ac_majflt);
507 ac.ac_flag |= AXSIG; 502 ac.ac_exitcode = pacct->ac_exitcode;
508 503 spin_unlock_irq(&current->sighand->siglock);
509 vsize = 0;
510 if (current->mm) {
511 struct vm_area_struct *vma;
512 down_read(&current->mm->mmap_sem);
513 vma = current->mm->mmap;
514 while (vma) {
515 vsize += vma->vm_end - vma->vm_start;
516 vma = vma->vm_next;
517 }
518 up_read(&current->mm->mmap_sem);
519 }
520 vsize = vsize / 1024;
521 ac.ac_mem = encode_comp_t(vsize);
522 ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */ 504 ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */
523 ac.ac_rw = encode_comp_t(ac.ac_io / 1024); 505 ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
524 ac.ac_minflt = encode_comp_t(current->signal->min_flt +
525 current->min_flt);
526 ac.ac_majflt = encode_comp_t(current->signal->maj_flt +
527 current->maj_flt);
528 ac.ac_swaps = encode_comp_t(0); 506 ac.ac_swaps = encode_comp_t(0);
529 ac.ac_exitcode = exitcode;
530 507
531 /* 508 /*
532 * Kernel segment override to datasegment and write it 509 * Kernel segment override to datasegment and write it
@@ -546,12 +523,64 @@ static void do_acct_process(long exitcode, struct file *file)
546} 523}
547 524
548/** 525/**
526 * acct_init_pacct - initialize a new pacct_struct
527 * @pacct: per-process accounting info struct to initialize
528 */
529void acct_init_pacct(struct pacct_struct *pacct)
530{
531 memset(pacct, 0, sizeof(struct pacct_struct));
532 pacct->ac_utime = pacct->ac_stime = cputime_zero;
533}
534
535/**
536 * acct_collect - collect accounting information into pacct_struct
537 * @exitcode: task exit code
538 * @group_dead: not 0, if this thread is the last one in the process.
539 */
540void acct_collect(long exitcode, int group_dead)
541{
542 struct pacct_struct *pacct = &current->signal->pacct;
543 unsigned long vsize = 0;
544
545 if (group_dead && current->mm) {
546 struct vm_area_struct *vma;
547 down_read(&current->mm->mmap_sem);
548 vma = current->mm->mmap;
549 while (vma) {
550 vsize += vma->vm_end - vma->vm_start;
551 vma = vma->vm_next;
552 }
553 up_read(&current->mm->mmap_sem);
554 }
555
556 spin_lock_irq(&current->sighand->siglock);
557 if (group_dead)
558 pacct->ac_mem = vsize / 1024;
559 if (thread_group_leader(current)) {
560 pacct->ac_exitcode = exitcode;
561 if (current->flags & PF_FORKNOEXEC)
562 pacct->ac_flag |= AFORK;
563 }
564 if (current->flags & PF_SUPERPRIV)
565 pacct->ac_flag |= ASU;
566 if (current->flags & PF_DUMPCORE)
567 pacct->ac_flag |= ACORE;
568 if (current->flags & PF_SIGNALED)
569 pacct->ac_flag |= AXSIG;
570 pacct->ac_utime = cputime_add(pacct->ac_utime, current->utime);
571 pacct->ac_stime = cputime_add(pacct->ac_stime, current->stime);
572 pacct->ac_minflt += current->min_flt;
573 pacct->ac_majflt += current->maj_flt;
574 spin_unlock_irq(&current->sighand->siglock);
575}
576
577/**
549 * acct_process - now just a wrapper around do_acct_process 578 * acct_process - now just a wrapper around do_acct_process
550 * @exitcode: task exit code 579 * @exitcode: task exit code
551 * 580 *
552 * handles process accounting for an exiting task 581 * handles process accounting for an exiting task
553 */ 582 */
554void acct_process(long exitcode) 583void acct_process(void)
555{ 584{
556 struct file *file = NULL; 585 struct file *file = NULL;
557 586
@@ -570,7 +599,7 @@ void acct_process(long exitcode)
570 get_file(file); 599 get_file(file);
571 spin_unlock(&acct_globals.lock); 600 spin_unlock(&acct_globals.lock);
572 601
573 do_acct_process(exitcode, file); 602 do_acct_process(file);
574 fput(file); 603 fput(file);
575} 604}
576 605
@@ -599,9 +628,7 @@ void acct_update_integrals(struct task_struct *tsk)
599 */ 628 */
600void acct_clear_integrals(struct task_struct *tsk) 629void acct_clear_integrals(struct task_struct *tsk)
601{ 630{
602 if (tsk) { 631 tsk->acct_stimexpd = 0;
603 tsk->acct_stimexpd = 0; 632 tsk->acct_rss_mem1 = 0;
604 tsk->acct_rss_mem1 = 0; 633 tsk->acct_vm_mem1 = 0;
605 tsk->acct_vm_mem1 = 0;
606 }
607} 634}