aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/time/timekeeping.c36
1 files changed, 19 insertions, 17 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 3be559b6fd0a..b7db4916415b 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1255,7 +1255,7 @@ void __init timekeeping_init(void)
1255 raw_spin_unlock_irqrestore(&timekeeper_lock, flags); 1255 raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
1256} 1256}
1257 1257
1258/* time in seconds when suspend began */ 1258/* time in seconds when suspend began for persistent clock */
1259static struct timespec64 timekeeping_suspend_time; 1259static struct timespec64 timekeeping_suspend_time;
1260 1260
1261/** 1261/**
@@ -1428,24 +1428,26 @@ int timekeeping_suspend(void)
1428 timekeeping_forward_now(tk); 1428 timekeeping_forward_now(tk);
1429 timekeeping_suspended = 1; 1429 timekeeping_suspended = 1;
1430 1430
1431 /* 1431 if (has_persistent_clock()) {
1432 * To avoid drift caused by repeated suspend/resumes,
1433 * which each can add ~1 second drift error,
1434 * try to compensate so the difference in system time
1435 * and persistent_clock time stays close to constant.
1436 */
1437 delta = timespec64_sub(tk_xtime(tk), timekeeping_suspend_time);
1438 delta_delta = timespec64_sub(delta, old_delta);
1439 if (abs(delta_delta.tv_sec) >= 2) {
1440 /* 1432 /*
1441 * if delta_delta is too large, assume time correction 1433 * To avoid drift caused by repeated suspend/resumes,
1442 * has occured and set old_delta to the current delta. 1434 * which each can add ~1 second drift error,
1435 * try to compensate so the difference in system time
1436 * and persistent_clock time stays close to constant.
1443 */ 1437 */
1444 old_delta = delta; 1438 delta = timespec64_sub(tk_xtime(tk), timekeeping_suspend_time);
1445 } else { 1439 delta_delta = timespec64_sub(delta, old_delta);
1446 /* Otherwise try to adjust old_system to compensate */ 1440 if (abs(delta_delta.tv_sec) >= 2) {
1447 timekeeping_suspend_time = 1441 /*
1448 timespec64_add(timekeeping_suspend_time, delta_delta); 1442 * if delta_delta is too large, assume time correction
1443 * has occurred and set old_delta to the current delta.
1444 */
1445 old_delta = delta;
1446 } else {
1447 /* Otherwise try to adjust old_system to compensate */
1448 timekeeping_suspend_time =
1449 timespec64_add(timekeeping_suspend_time, delta_delta);
1450 }
1449 } 1451 }
1450 1452
1451 timekeeping_update(tk, TK_MIRROR); 1453 timekeeping_update(tk, TK_MIRROR);