+ pacct-avoidance-to-refer-the-last-thread-as-a-representation-of-the-process.patch added to -mm tree

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

 



The patch titled

     pacct: avoidance to refer the last thread as a representation of the process

has been added to the -mm tree.  Its filename is

     pacct-avoidance-to-refer-the-last-thread-as-a-representation-of-the-process.patch

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: pacct: avoidance to refer the last thread as a representation of the process
From: KaiGai Kohei <kaigai@xxxxxxxxxxxxx>


When pacct facility generate an 'ac_flag' field in accounting record, it
refers a task_struct of the thread which died last in the process.  But any
other task_structs are ignored.

Therefore, pacct facility drops ASU flag even if root-privilege operations are
used by any other threads except the last one.  In addition, AFORK flag is
always set when the thread of group-leader didn't die last, although this
process has called execve() after fork().

We have a same matter in ac_exitcode.  The recorded ac_exitcode is an exit
code of the last thread in the process.  There is a possibility this exitcode
is not the group leader's one.

---- in kernel/acct.c : do_acct_process() ----
        ac.ac_flag = 0;
        if (current->flags & PF_FORKNOEXEC)
                ac.ac_flag |= AFORK;
        if (current->flags & PF_SUPERPRIV)
                ac.ac_flag |= ASU;
        if (current->flags & PF_DUMPCORE)
                ac.ac_flag |= ACORE;
        if (current->flags & PF_SIGNALED)
                ac.ac_flag |= AXSIG;
                  :
               - snip -
                  :
        ac.ac_exitcode = exitcode;
----------------------------------------------

This patch fixes those matters.
- The exit code of group leader is recorded as ac_exitcode.
- ASU, ACORE, AXSIG flag are marked if any task_struct satisfy
  the conditions.
- AFORK flag is marked if only group leader thread satisfy
  the condition.

Signed-off-by: KaiGai Kohei <kaigai@xxxxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 include/linux/acct.h  |    8 +++----
 include/linux/sched.h |    2 +
 kernel/acct.c         |   42 ++++++++++++++++++++++------------------
 kernel/exit.c         |    4 +--
 4 files changed, 32 insertions(+), 24 deletions(-)

diff -puN include/linux/acct.h~pacct-avoidance-to-refer-the-last-thread-as-a-representation-of-the-process include/linux/acct.h
--- a/include/linux/acct.h~pacct-avoidance-to-refer-the-last-thread-as-a-representation-of-the-process
+++ a/include/linux/acct.h
@@ -122,16 +122,16 @@ struct super_block;
 extern void acct_auto_close_mnt(struct vfsmount *m);
 extern void acct_auto_close(struct super_block *sb);
 extern void acct_init_pacct(struct pacct_struct *pacct);
-extern void acct_collect();
-extern void acct_process(long exitcode);
+extern void acct_collect(long exitcode, int group_dead);
+extern void acct_process(void);
 extern void acct_update_integrals(struct task_struct *tsk);
 extern void acct_clear_integrals(struct task_struct *tsk);
 #else
 #define acct_auto_close_mnt(x)	do { } while (0)
 #define acct_auto_close(x)	do { } while (0)
 #define acct_init_pacct(x)	do { } while (0)
-#define acct_collect()		do { } while (0)
-#define acct_process(x)		do { } while (0)
+#define acct_collect(x,y)	do { } while (0)
+#define acct_process()		do { } while (0)
 #define acct_update_integrals(x)		do { } while (0)
 #define acct_clear_integrals(task)	do { } while (0)
 #endif
diff -puN include/linux/sched.h~pacct-avoidance-to-refer-the-last-thread-as-a-representation-of-the-process include/linux/sched.h
--- a/include/linux/sched.h~pacct-avoidance-to-refer-the-last-thread-as-a-representation-of-the-process
+++ a/include/linux/sched.h
@@ -359,6 +359,8 @@ struct sighand_struct {
 };
 
 struct pacct_struct {
+	int			ac_flag;
+	long			ac_exitcode;
 	unsigned long		ac_mem;
 };
 
diff -puN kernel/acct.c~pacct-avoidance-to-refer-the-last-thread-as-a-representation-of-the-process kernel/acct.c
--- a/kernel/acct.c~pacct-avoidance-to-refer-the-last-thread-as-a-representation-of-the-process
+++ a/kernel/acct.c
@@ -75,7 +75,7 @@ int acct_parm[3] = {4, 2, 30};
 /*
  * External references and all of the globals.
  */
-static void do_acct_process(long, struct file *);
+static void do_acct_process(struct file *);
 
 /*
  * This structure is used so that all the data protected by lock
@@ -196,7 +196,7 @@ static void acct_file_reopen(struct file
 	if (old_acct) {
 		mnt_unpin(old_acct->f_vfsmnt);
 		spin_unlock(&acct_globals.lock);
-		do_acct_process(0, old_acct);
+		do_acct_process(old_acct);
 		filp_close(old_acct, NULL);
 		spin_lock(&acct_globals.lock);
 	}
@@ -419,7 +419,7 @@ static u32 encode_float(u64 value)
 /*
  *  do_acct_process does all actual work. Caller holds the reference to file.
  */
-static void do_acct_process(long exitcode, struct file *file)
+static void do_acct_process(struct file *file)
 {
 	struct pacct_struct *pacct = &current->signal->pacct;
 	acct_t ac;
@@ -496,17 +496,10 @@ static void do_acct_process(long exitcod
 		old_encode_dev(tty_devnum(current->signal->tty)) : 0;
 	read_unlock(&tasklist_lock);
 
-	ac.ac_flag = 0;
-	if (current->flags & PF_FORKNOEXEC)
-		ac.ac_flag |= AFORK;
-	if (current->flags & PF_SUPERPRIV)
-		ac.ac_flag |= ASU;
-	if (current->flags & PF_DUMPCORE)
-		ac.ac_flag |= ACORE;
-	if (current->flags & PF_SIGNALED)
-		ac.ac_flag |= AXSIG;
 	spin_lock(&current->sighand->siglock);
+	ac.ac_flag = pacct->ac_flag;
 	ac.ac_mem = encode_comp_t(pacct->ac_mem);
+	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);
@@ -515,7 +508,6 @@ static void do_acct_process(long exitcod
 	ac.ac_majflt = encode_comp_t(current->signal->maj_flt +
 				     current->maj_flt);
 	ac.ac_swaps = encode_comp_t(0);
-	ac.ac_exitcode = exitcode;
 
 	/*
          * Kernel segment override to datasegment and write it
@@ -544,13 +536,15 @@ void acct_init_pacct(struct pacct_struct
 
 /**
  * acct_collect - collect accounting information into pacct_struct
+ * @exitcode: task exit code
+ * @group_dead: not 0, if this thread is the last one in the process.
  */
-void acct_collect(void)
+void acct_collect(long exitcode, int group_dead)
 {
 	struct pacct_struct *pacct = &current->signal->pacct;
 	unsigned long vsize = 0;
 
-	if (current->mm) {
+	if (group_dead && current->mm) {
 		struct vm_area_struct *vma;
 		down_read(&current->mm->mmap_sem);
 		vma = current->mm->mmap;
@@ -562,7 +556,19 @@ void acct_collect(void)
 	}
 
 	spin_lock(&current->sighand->siglock);
-	pacct->ac_mem = vsize / 1024;
+	if (group_dead)
+		pacct->ac_mem = vsize / 1024;
+	if (thread_group_leader(current)) {
+		pacct->ac_exitcode = exitcode;
+		if (current->flags & PF_FORKNOEXEC)
+			pacct->ac_flag |= AFORK;
+	}
+	if (current->flags & PF_SUPERPRIV)
+		pacct->ac_flag |= ASU;
+	if (current->flags & PF_DUMPCORE)
+		pacct->ac_flag |= ACORE;
+	if (current->flags & PF_SIGNALED)
+		pacct->ac_flag |= AXSIG;
 	spin_unlock(&current->sighand->siglock);
 }
 
@@ -572,7 +578,7 @@ void acct_collect(void)
  *
  * handles process accounting for an exiting task
  */
-void acct_process(long exitcode)
+void acct_process()
 {
 	struct file *file = NULL;
 
@@ -591,7 +597,7 @@ void acct_process(long exitcode)
 	get_file(file);
 	spin_unlock(&acct_globals.lock);
 
-	do_acct_process(exitcode, file);
+	do_acct_process(file);
 	fput(file);
 }
 
diff -puN kernel/exit.c~pacct-avoidance-to-refer-the-last-thread-as-a-representation-of-the-process kernel/exit.c
--- a/kernel/exit.c~pacct-avoidance-to-refer-the-last-thread-as-a-representation-of-the-process
+++ a/kernel/exit.c
@@ -894,8 +894,8 @@ fastcall NORET_TYPE void do_exit(long co
 	if (group_dead) {
  		hrtimer_cancel(&tsk->signal->real_timer);
 		exit_itimers(tsk->signal);
-		acct_collect();
 	}
+	acct_collect(code, group_dead);
 	if (unlikely(tsk->robust_list))
 		exit_robust_list(tsk);
 #if defined(CONFIG_FUTEX) && defined(CONFIG_COMPAT)
@@ -907,7 +907,7 @@ fastcall NORET_TYPE void do_exit(long co
 	exit_mm(tsk);
 
 	if (group_dead)
-		acct_process(code);
+		acct_process();
 	exit_sem(tsk);
 	__exit_files(tsk);
 	__exit_fs(tsk);
_

Patches currently in -mm which might be from kaigai@xxxxxxxxxxxxx are

origin.patch
pacct-two-phase-process-accounting.patch
pacct-avoidance-to-refer-the-last-thread-as-a-representation-of-the-process.patch
pacct-none-delayed-process-accounting-accumulation.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux