taskstats: Cleanup the use of task->exit_code
authorEric W. Biederman <ebiederm@xmission.com>
Mon, 3 Jan 2022 17:32:36 +0000 (11:32 -0600)
committerEric W. Biederman <ebiederm@xmission.com>
Sat, 8 Jan 2022 18:43:57 +0000 (12:43 -0600)
In the function bacct_add_task the code reading task->exit_code was
introduced in commit f3cef7a99469 ("[PATCH] csa: basic accounting over
taskstats"), and it is not entirely clear what the taskstats interface
is trying to return as only returning the exit_code of the first task
in a process doesn't make a lot of sense.

As best as I can figure the intent is to return task->exit_code after
a task exits.  The field is returned with per task fields, so the
exit_code of the entire process is not wanted.  Only the value of the
first task is returned so this is not a useful way to get the per task
ptrace stop code.  The ordinary case of returning this value is
returning after a task exits, which also precludes use for getting
a ptrace value.

It is common to for the first task of a process to also be the last
task of a process so this field may have done something reasonable by
accident in testing.

Make ac_exitcode a reliable per task value by always returning it for
every exited task.

Setting ac_exitcode in a sensible mannter makes it possible to continue
to provide this value going forward.

Cc: Balbir Singh <bsingharora@gmail.com>
Fixes: f3cef7a99469 ("[PATCH] csa: basic accounting over taskstats")
Link: https://lkml.kernel.org/r/20220103213312.9144-5-ebiederm@xmission.com
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
kernel/tsacct.c

index f00de83d02462714526f7c6086e95de172ad9ce5..1d261fbe367bf8845428ed61393d0044de61727d 100644 (file)
@@ -38,11 +38,10 @@ void bacct_add_tsk(struct user_namespace *user_ns,
        stats->ac_btime = clamp_t(time64_t, btime, 0, U32_MAX);
        stats->ac_btime64 = btime;
 
-       if (thread_group_leader(tsk)) {
+       if (tsk->flags & PF_EXITING)
                stats->ac_exitcode = tsk->exit_code;
-               if (tsk->flags & PF_FORKNOEXEC)
-                       stats->ac_flag |= AFORK;
-       }
+       if (thread_group_leader(tsk) && (tsk->flags & PF_FORKNOEXEC))
+               stats->ac_flag |= AFORK;
        if (tsk->flags & PF_SUPERPRIV)
                stats->ac_flag |= ASU;
        if (tsk->flags & PF_DUMPCORE)