As there is only a 32-bit ac_btime field in taskstat and we should handle dates after the overflow, add a new field with the same information but 64-bit width that can hold a full time64_t.
Signed-off-by: Arnd Bergmann arnd@arndb.de --- include/uapi/linux/taskstats.h | 5 ++++- kernel/tsacct.c | 1 + 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/taskstats.h b/include/uapi/linux/taskstats.h index 7d3ea366e93b..ccbd08709321 100644 --- a/include/uapi/linux/taskstats.h +++ b/include/uapi/linux/taskstats.h @@ -34,7 +34,7 @@ */
-#define TASKSTATS_VERSION 9 +#define TASKSTATS_VERSION 10 #define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN * in linux/sched.h */
@@ -169,6 +169,9 @@ struct taskstats { /* Delay waiting for thrashing page */ __u64 thrashing_count; __u64 thrashing_delay_total; + + /* v10: 64-bit btime to avoid overflow */ + __u64 ac_btime64; /* 64-bit begin time */ };
diff --git a/kernel/tsacct.c b/kernel/tsacct.c index ab12616ee6fb..257ffb993ea2 100644 --- a/kernel/tsacct.c +++ b/kernel/tsacct.c @@ -36,6 +36,7 @@ void bacct_add_tsk(struct user_namespace *user_ns, /* Convert to seconds for btime (note y2106 limit) */ btime = ktime_get_real_seconds() - div_u64(delta, USEC_PER_SEC); stats->ac_btime = clamp_t(time64_t, btime, 0, U32_MAX); + stats->ac_btime64 = btime;
if (thread_group_leader(tsk)) { stats->ac_exitcode = tsk->exit_code;