* [PATCH v2 0/2] tsacct: keep task begin times stable across suspend
@ 2026-10-30 5:42 Hungyu Lin
2026-10-30 5:42 ` [PATCH v2 1/2] timekeeping: Read getboottime64() offsets under the sequence counter Hungyu Lin
2026-10-30 5:42 ` [PATCH v2 2/2] tsacct: keep task begin times stable across suspend Hungyu Lin
0 siblings, 2 replies; 3+ messages in thread
From: Hungyu Lin @ 2026-10-30 5:42 UTC (permalink / raw)
To: tglx, jstultz
Cc: sboyd, mlichvar, akpm, oleg, linux-kernel, stable, dennylin0707
Keep taskstats begin times stable across suspend without changing the
MONOTONIC elapsed-time fields.
Patch 1 makes getboottime64() sample its offsets under tk_core.seq.
Patch 2 uses that helper and the task's BOOTTIME start timestamp, and
clamps negative begin times to zero. Keep the helper prerequisite when
backporting the taskstats change.
Changes in v2, addressing Andrew Morton's review:
- Add the getboottime64() sampling prerequisite as patch 1/2.
- Lower-clamp ac_btime64 without imposing a 32-bit upper limit.
- Add Cc: stable to both patches.
- Rebase onto mainline d89e1d186ec9.
Validation used GCC 13.3.0 with W=1. ARM64 and native 32-bit SMP x86 QEMU
guests pass all 36 checks, including the original 24. The 32-bit helper
stress reproduced inconsistent timestamps before the fix and none after.
Suspend time was injected through the real timekeeping hook.
v1: https://lore.kernel.org/r/20261026005506.2253-1-dennylin0707@gmail.com
Hungyu Lin (2):
timekeeping: Read getboottime64() offsets under the sequence counter
tsacct: keep task begin times stable across suspend
kernel/time/timekeeping.c | 8 +++++++-
kernel/tsacct.c | 10 ++++++----
2 files changed, 13 insertions(+), 5 deletions(-)
base-commit: d89e1d186ec9271bf78e62771779e9fc03bf0fc3
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v2 1/2] timekeeping: Read getboottime64() offsets under the sequence counter
2026-10-30 5:42 [PATCH v2 0/2] tsacct: keep task begin times stable across suspend Hungyu Lin
@ 2026-10-30 5:42 ` Hungyu Lin
2026-10-30 5:42 ` [PATCH v2 2/2] tsacct: keep task begin times stable across suspend Hungyu Lin
1 sibling, 0 replies; 3+ messages in thread
From: Hungyu Lin @ 2026-10-30 5:42 UTC (permalink / raw)
To: tglx, jstultz
Cc: sboyd, mlichvar, akpm, oleg, linux-kernel, stable, dennylin0707
getboottime64() computes the wall-clock boot timestamp from offs_real
minus offs_boot without checking tk_core.seq. A concurrent timekeeping
update can leave the reader with an inconsistent pair of offsets or,
on 32-bit systems, a torn 64-bit offset, producing an incorrect boot
timestamp.
Read both offsets under tk_core.seq and retry if an update overlaps
the sample. Convert the resulting local value to a timespec64 afterward.
Fixes: 7c3f1a573237 ("Introduce boot based time")
Cc: stable@vger.kernel.org
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
---
New prerequisite in v2, addressing Andrew Morton's review.
kernel/time/timekeeping.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index dcf47f1ffdcf..7d7a7372f3c8 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -2700,7 +2700,13 @@ void update_wall_time(void)
void getboottime64(struct timespec64 *ts)
{
struct timekeeper *tk = &tk_core.timekeeper;
- ktime_t t = ktime_sub(tk->offs_real, tk->offs_boot);
+ unsigned int seq;
+ ktime_t t;
+
+ do {
+ seq = read_seqcount_begin(&tk_core.seq);
+ t = ktime_sub(tk->offs_real, tk->offs_boot);
+ } while (read_seqcount_retry(&tk_core.seq, seq));
*ts = ktime_to_timespec64(t);
}
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v2 2/2] tsacct: keep task begin times stable across suspend
2026-10-30 5:42 [PATCH v2 0/2] tsacct: keep task begin times stable across suspend Hungyu Lin
2026-10-30 5:42 ` [PATCH v2 1/2] timekeeping: Read getboottime64() offsets under the sequence counter Hungyu Lin
@ 2026-10-30 5:42 ` Hungyu Lin
1 sibling, 0 replies; 3+ messages in thread
From: Hungyu Lin @ 2026-10-30 5:42 UTC (permalink / raw)
To: tglx, jstultz
Cc: sboyd, mlichvar, akpm, oleg, linux-kernel, stable, dennylin0707
bacct_add_tsk() derives ac_btime and ac_btime64 by subtracting a
CLOCK_MONOTONIC elapsed duration from CLOCK_REALTIME. MONOTONIC stops
during suspend while REALTIME continues, so querying an existing task
after resume moves its reported begin time forward by the time spent
suspended.
Calculate the begin time from the wall-clock boot timestamp and the
task's CLOCK_BOOTTIME start timestamp instead. This accounts for suspend
and adds the nanoseconds before truncating to seconds. Keep ac_etime and
ac_tgetime on CLOCK_MONOTONIC and retain the existing rebasing when the
wall clock is adjusted.
The new begin time can be negative: setting CLOCK_REALTIME is bounded
by CLOCK_MONOTONIC, which excludes suspend, rather than CLOCK_BOOTTIME.
A permitted backward clock adjustment after suspend can therefore put
the task's begin time before the epoch. Clamp ac_btime64 at zero too,
instead of wrapping in the unsigned field, and retain its positive range.
Fixes: f3cef7a99469 ("[PATCH] csa: basic accounting over taskstats")
Cc: stable@vger.kernel.org
Reported-by: Oleg Nesterov <oleg@redhat.com>
Link: https://lore.kernel.org/r/20130611200600.GA15168@redhat.com
Suggested-by: Thomas Gleixner <tglx@kernel.org>
Link: https://lore.kernel.org/r/alpine.DEB.2.21.1911071335320.4256@nanos.tec.linutronix.de
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
---
Changes in v2:
- Clamp negative ac_btime64 values to zero without a 32-bit upper limit.
- Precede this change with the getboottime64() sampling fix.
- Add Cc: stable and rebase onto mainline d89e1d186ec9.
kernel/tsacct.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/kernel/tsacct.c b/kernel/tsacct.c
index 5c153106e642..48320684c7c0 100644
--- a/kernel/tsacct.c
+++ b/kernel/tsacct.c
@@ -24,7 +24,7 @@ void bacct_add_tsk(struct user_namespace *user_ns,
const struct cred *tcred;
u64 utime, stime, utimescaled, stimescaled;
u64 now_ns, delta;
- time64_t btime;
+ struct timespec64 btime;
BUILD_BUG_ON(TS_COMM_LEN < TASK_COMM_LEN);
@@ -39,9 +39,11 @@ void bacct_add_tsk(struct user_namespace *user_ns,
do_div(delta, NSEC_PER_USEC);
stats->ac_etime = delta;
/* 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;
+ getboottime64(&btime);
+ btime = timespec64_add(btime, ns_to_timespec64(tsk->start_boottime));
+ stats->ac_btime = clamp_t(time64_t, btime.tv_sec, 0, U32_MAX);
+ /* Setting the clock back after suspend can make btime negative. */
+ stats->ac_btime64 = max_t(time64_t, btime.tv_sec, 0);
if (tsk->flags & PF_EXITING)
stats->ac_exitcode = tsk->exit_code;
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-30 5:42 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-30 5:42 [PATCH v2 0/2] tsacct: keep task begin times stable across suspend Hungyu Lin
2026-10-30 5:42 ` [PATCH v2 1/2] timekeeping: Read getboottime64() offsets under the sequence counter Hungyu Lin
2026-10-30 5:42 ` [PATCH v2 2/2] tsacct: keep task begin times stable across suspend Hungyu Lin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®