Re: Add pacct_struct to fix some pacct bugs.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



    [PACCT] none-delayed process accounting accumulation

    In current 2.6.17 implementation, signal_struct refered from task_struct
    is used for per-process data structure. The pacct facility also uses it
    as a per-process data structure to store stime, utime, minflt, majflt.
    But those members are saved in __exit_signal(). It's too late.

    For example, if some threads exits at same time, pacct facility has
    a possibility to drop accountings for a part of those threads.
    (see, the following 'The results of original 2.6.17 kernel')
    I think accounting information should be completely collected into
    the per-process data structure before writing out an accounting record.

    This patch fixes this matter. Accumulation of stime, utime, minflt
    and majflt are done before generating accounting record.

    Signed-off-by: KaiGai Kohei <[email protected]>

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 6905ac0..06c72fb 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -360,10 +360,12 @@ struct sighand_struct {

 struct pacct_struct {
 	int			ac_flag;
 	long			ac_exitcode;
 	unsigned long		ac_mem;
+	cputime_t		ac_utime, ac_stime;
+	unsigned long		ac_minflt, ac_majflt;
 };

 /*
  * NOTE! "signal_struct" does not have it's own
  * locking, because a shared signal_struct always
diff --git a/kernel/acct.c b/kernel/acct.c
index 7111fe7..48c701c 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -426,11 +426,10 @@ static void do_acct_process(struct file
 	mm_segment_t fs;
 	unsigned long flim;
 	u64 elapsed;
 	u64 run_time;
 	struct timespec uptime;
-	unsigned long jiffies;

 	/*
 	 * First check to see if there is enough free_space to continue
 	 * the process accounting system.
 	 */
@@ -467,16 +466,10 @@ static void do_acct_process(struct file
 		ac.ac_etime_lo = (u16) etime;
 	}
 #endif
 	do_div(elapsed, AHZ);
 	ac.ac_btime = xtime.tv_sec - elapsed;
-	jiffies = cputime_to_jiffies(cputime_add(current->utime,
-						 current->signal->utime));
-	ac.ac_utime = encode_comp_t(jiffies_to_AHZ(jiffies));
-	jiffies = cputime_to_jiffies(cputime_add(current->stime,
-						 current->signal->stime));
-	ac.ac_stime = encode_comp_t(jiffies_to_AHZ(jiffies));
 	/* we really need to bite the bullet and change layout */
 	ac.ac_uid = current->uid;
 	ac.ac_gid = current->gid;
 #if ACCT_VERSION==2
 	ac.ac_ahz = AHZ;
@@ -495,20 +488,20 @@ static void do_acct_process(struct file
 	ac.ac_tty = current->signal->tty ?
 		old_encode_dev(tty_devnum(current->signal->tty)) : 0;
 	read_unlock(&tasklist_lock);

 	spin_lock(&current->sighand->siglock);
+	ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime)));
+	ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime)));
 	ac.ac_flag = pacct->ac_flag;
 	ac.ac_mem = encode_comp_t(pacct->ac_mem);
+	ac.ac_minflt = encode_comp_t(pacct->ac_minflt);
+	ac.ac_majflt = encode_comp_t(pacct->ac_majflt);
 	ac.ac_exitcode = pacct->ac_exitcode;
 	spin_unlock(&current->sighand->siglock);
 	ac.ac_io = encode_comp_t(0 /* current->io_usage */);	/* %% */
 	ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
-	ac.ac_minflt = encode_comp_t(current->signal->min_flt +
-				     current->min_flt);
-	ac.ac_majflt = encode_comp_t(current->signal->maj_flt +
-				     current->maj_flt);
 	ac.ac_swaps = encode_comp_t(0);

 	/*
          * Kernel segment override to datasegment and write it
          * to the accounting file.
@@ -530,10 +523,11 @@ static void do_acct_process(struct file
  * acct_init_pacct - initialize a new pacct_struct
  */
 void acct_init_pacct(struct pacct_struct *pacct)
 {
 	memset(pacct, 0, sizeof(struct pacct_struct));
+	pacct->ac_utime = pacct->ac_stime = cputime_zero;
 }

 /**
  * acct_collect - collect accounting information into pacct_struct
  * @exitcode: task exit code
@@ -567,10 +561,14 @@ void acct_collect(long exitcode, int gro
 		pacct->ac_flag |= ASU;
 	if (current->flags & PF_DUMPCORE)
 		pacct->ac_flag |= ACORE;
 	if (current->flags & PF_SIGNALED)
 		pacct->ac_flag |= AXSIG;
+	pacct->ac_utime = cputime_add(pacct->ac_utime, current->utime);
+	pacct->ac_stime = cputime_add(pacct->ac_stime, current->stime);
+	pacct->ac_minflt += current->min_flt;
+	pacct->ac_majflt += current->maj_flt;
 	spin_unlock(&current->sighand->siglock);
 }

 /**
  * acct_process - now just a wrapper around do_acct_process

--
Open Source Software Promotion Center, NEC
KaiGai Kohei <[email protected]>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux