diff options
Diffstat (limited to 'kernel/time/timekeeping.c')
-rw-r--r-- | kernel/time/timekeeping.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index d563c1960302..34b4cedfa80d 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -305,8 +305,7 @@ static inline s64 timekeeping_get_ns(struct tk_read_base *tkr) | |||
305 | 305 | ||
306 | delta = timekeeping_get_delta(tkr); | 306 | delta = timekeeping_get_delta(tkr); |
307 | 307 | ||
308 | nsec = delta * tkr->mult + tkr->xtime_nsec; | 308 | nsec = (delta * tkr->mult + tkr->xtime_nsec) >> tkr->shift; |
309 | nsec >>= tkr->shift; | ||
310 | 309 | ||
311 | /* If arch requires, add in get_arch_timeoffset() */ | 310 | /* If arch requires, add in get_arch_timeoffset() */ |
312 | return nsec + arch_gettimeoffset(); | 311 | return nsec + arch_gettimeoffset(); |
@@ -846,6 +845,19 @@ time64_t ktime_get_real_seconds(void) | |||
846 | } | 845 | } |
847 | EXPORT_SYMBOL_GPL(ktime_get_real_seconds); | 846 | EXPORT_SYMBOL_GPL(ktime_get_real_seconds); |
848 | 847 | ||
848 | /** | ||
849 | * __ktime_get_real_seconds - The same as ktime_get_real_seconds | ||
850 | * but without the sequence counter protect. This internal function | ||
851 | * is called just when timekeeping lock is already held. | ||
852 | */ | ||
853 | time64_t __ktime_get_real_seconds(void) | ||
854 | { | ||
855 | struct timekeeper *tk = &tk_core.timekeeper; | ||
856 | |||
857 | return tk->xtime_sec; | ||
858 | } | ||
859 | |||
860 | |||
849 | #ifdef CONFIG_NTP_PPS | 861 | #ifdef CONFIG_NTP_PPS |
850 | 862 | ||
851 | /** | 863 | /** |
@@ -959,7 +971,7 @@ int timekeeping_inject_offset(struct timespec *ts) | |||
959 | struct timespec64 ts64, tmp; | 971 | struct timespec64 ts64, tmp; |
960 | int ret = 0; | 972 | int ret = 0; |
961 | 973 | ||
962 | if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) | 974 | if (!timespec_inject_offset_valid(ts)) |
963 | return -EINVAL; | 975 | return -EINVAL; |
964 | 976 | ||
965 | ts64 = timespec_to_timespec64(*ts); | 977 | ts64 = timespec_to_timespec64(*ts); |
@@ -1592,9 +1604,12 @@ static __always_inline void timekeeping_freqadjust(struct timekeeper *tk, | |||
1592 | { | 1604 | { |
1593 | s64 interval = tk->cycle_interval; | 1605 | s64 interval = tk->cycle_interval; |
1594 | s64 xinterval = tk->xtime_interval; | 1606 | s64 xinterval = tk->xtime_interval; |
1607 | u32 base = tk->tkr_mono.clock->mult; | ||
1608 | u32 max = tk->tkr_mono.clock->maxadj; | ||
1609 | u32 cur_adj = tk->tkr_mono.mult; | ||
1595 | s64 tick_error; | 1610 | s64 tick_error; |
1596 | bool negative; | 1611 | bool negative; |
1597 | u32 adj; | 1612 | u32 adj_scale; |
1598 | 1613 | ||
1599 | /* Remove any current error adj from freq calculation */ | 1614 | /* Remove any current error adj from freq calculation */ |
1600 | if (tk->ntp_err_mult) | 1615 | if (tk->ntp_err_mult) |
@@ -1613,13 +1628,33 @@ static __always_inline void timekeeping_freqadjust(struct timekeeper *tk, | |||
1613 | /* preserve the direction of correction */ | 1628 | /* preserve the direction of correction */ |
1614 | negative = (tick_error < 0); | 1629 | negative = (tick_error < 0); |
1615 | 1630 | ||
1616 | /* Sort out the magnitude of the correction */ | 1631 | /* If any adjustment would pass the max, just return */ |
1632 | if (negative && (cur_adj - 1) <= (base - max)) | ||
1633 | return; | ||
1634 | if (!negative && (cur_adj + 1) >= (base + max)) | ||
1635 | return; | ||
1636 | /* | ||
1637 | * Sort out the magnitude of the correction, but | ||
1638 | * avoid making so large a correction that we go | ||
1639 | * over the max adjustment. | ||
1640 | */ | ||
1641 | adj_scale = 0; | ||
1617 | tick_error = abs(tick_error); | 1642 | tick_error = abs(tick_error); |
1618 | for (adj = 0; tick_error > interval; adj++) | 1643 | while (tick_error > interval) { |
1644 | u32 adj = 1 << (adj_scale + 1); | ||
1645 | |||
1646 | /* Check if adjustment gets us within 1 unit from the max */ | ||
1647 | if (negative && (cur_adj - adj) <= (base - max)) | ||
1648 | break; | ||
1649 | if (!negative && (cur_adj + adj) >= (base + max)) | ||
1650 | break; | ||
1651 | |||
1652 | adj_scale++; | ||
1619 | tick_error >>= 1; | 1653 | tick_error >>= 1; |
1654 | } | ||
1620 | 1655 | ||
1621 | /* scale the corrections */ | 1656 | /* scale the corrections */ |
1622 | timekeeping_apply_adjustment(tk, offset, negative, adj); | 1657 | timekeeping_apply_adjustment(tk, offset, negative, adj_scale); |
1623 | } | 1658 | } |
1624 | 1659 | ||
1625 | /* | 1660 | /* |