diff options
Diffstat (limited to 'kernel/time/timekeeping.c')
-rw-r--r-- | kernel/time/timekeeping.c | 51 |
1 files changed, 26 insertions, 25 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 15be32e19c6..d66b21308f7 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -184,18 +184,6 @@ static void timekeeping_update(bool clearntp) | |||
184 | } | 184 | } |
185 | 185 | ||
186 | 186 | ||
187 | void timekeeping_leap_insert(int leapsecond) | ||
188 | { | ||
189 | unsigned long flags; | ||
190 | |||
191 | write_seqlock_irqsave(&timekeeper.lock, flags); | ||
192 | timekeeper.xtime.tv_sec += leapsecond; | ||
193 | timekeeper.wall_to_monotonic.tv_sec -= leapsecond; | ||
194 | timekeeping_update(false); | ||
195 | write_sequnlock_irqrestore(&timekeeper.lock, flags); | ||
196 | |||
197 | } | ||
198 | |||
199 | /** | 187 | /** |
200 | * timekeeping_forward_now - update clock to the current time | 188 | * timekeeping_forward_now - update clock to the current time |
201 | * | 189 | * |
@@ -448,9 +436,12 @@ EXPORT_SYMBOL(timekeeping_inject_offset); | |||
448 | static int change_clocksource(void *data) | 436 | static int change_clocksource(void *data) |
449 | { | 437 | { |
450 | struct clocksource *new, *old; | 438 | struct clocksource *new, *old; |
439 | unsigned long flags; | ||
451 | 440 | ||
452 | new = (struct clocksource *) data; | 441 | new = (struct clocksource *) data; |
453 | 442 | ||
443 | write_seqlock_irqsave(&timekeeper.lock, flags); | ||
444 | |||
454 | timekeeping_forward_now(); | 445 | timekeeping_forward_now(); |
455 | if (!new->enable || new->enable(new) == 0) { | 446 | if (!new->enable || new->enable(new) == 0) { |
456 | old = timekeeper.clock; | 447 | old = timekeeper.clock; |
@@ -458,6 +449,10 @@ static int change_clocksource(void *data) | |||
458 | if (old->disable) | 449 | if (old->disable) |
459 | old->disable(old); | 450 | old->disable(old); |
460 | } | 451 | } |
452 | timekeeping_update(true); | ||
453 | |||
454 | write_sequnlock_irqrestore(&timekeeper.lock, flags); | ||
455 | |||
461 | return 0; | 456 | return 0; |
462 | } | 457 | } |
463 | 458 | ||
@@ -827,7 +822,7 @@ static void timekeeping_adjust(s64 offset) | |||
827 | int adj; | 822 | int adj; |
828 | 823 | ||
829 | /* | 824 | /* |
830 | * The point of this is to check if the error is greater then half | 825 | * The point of this is to check if the error is greater than half |
831 | * an interval. | 826 | * an interval. |
832 | * | 827 | * |
833 | * First we shift it down from NTP_SHIFT to clocksource->shifted nsecs. | 828 | * First we shift it down from NTP_SHIFT to clocksource->shifted nsecs. |
@@ -835,7 +830,7 @@ static void timekeeping_adjust(s64 offset) | |||
835 | * Note we subtract one in the shift, so that error is really error*2. | 830 | * Note we subtract one in the shift, so that error is really error*2. |
836 | * This "saves" dividing(shifting) interval twice, but keeps the | 831 | * This "saves" dividing(shifting) interval twice, but keeps the |
837 | * (error > interval) comparison as still measuring if error is | 832 | * (error > interval) comparison as still measuring if error is |
838 | * larger then half an interval. | 833 | * larger than half an interval. |
839 | * | 834 | * |
840 | * Note: It does not "save" on aggravation when reading the code. | 835 | * Note: It does not "save" on aggravation when reading the code. |
841 | */ | 836 | */ |
@@ -843,7 +838,7 @@ static void timekeeping_adjust(s64 offset) | |||
843 | if (error > interval) { | 838 | if (error > interval) { |
844 | /* | 839 | /* |
845 | * We now divide error by 4(via shift), which checks if | 840 | * We now divide error by 4(via shift), which checks if |
846 | * the error is greater then twice the interval. | 841 | * the error is greater than twice the interval. |
847 | * If it is greater, we need a bigadjust, if its smaller, | 842 | * If it is greater, we need a bigadjust, if its smaller, |
848 | * we can adjust by 1. | 843 | * we can adjust by 1. |
849 | */ | 844 | */ |
@@ -874,13 +869,15 @@ static void timekeeping_adjust(s64 offset) | |||
874 | } else /* No adjustment needed */ | 869 | } else /* No adjustment needed */ |
875 | return; | 870 | return; |
876 | 871 | ||
877 | WARN_ONCE(timekeeper.clock->maxadj && | 872 | if (unlikely(timekeeper.clock->maxadj && |
878 | (timekeeper.mult + adj > timekeeper.clock->mult + | 873 | (timekeeper.mult + adj > |
879 | timekeeper.clock->maxadj), | 874 | timekeeper.clock->mult + timekeeper.clock->maxadj))) { |
880 | "Adjusting %s more then 11%% (%ld vs %ld)\n", | 875 | printk_once(KERN_WARNING |
876 | "Adjusting %s more than 11%% (%ld vs %ld)\n", | ||
881 | timekeeper.clock->name, (long)timekeeper.mult + adj, | 877 | timekeeper.clock->name, (long)timekeeper.mult + adj, |
882 | (long)timekeeper.clock->mult + | 878 | (long)timekeeper.clock->mult + |
883 | timekeeper.clock->maxadj); | 879 | timekeeper.clock->maxadj); |
880 | } | ||
884 | /* | 881 | /* |
885 | * So the following can be confusing. | 882 | * So the following can be confusing. |
886 | * | 883 | * |
@@ -952,7 +949,7 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) | |||
952 | u64 nsecps = (u64)NSEC_PER_SEC << timekeeper.shift; | 949 | u64 nsecps = (u64)NSEC_PER_SEC << timekeeper.shift; |
953 | u64 raw_nsecs; | 950 | u64 raw_nsecs; |
954 | 951 | ||
955 | /* If the offset is smaller then a shifted interval, do nothing */ | 952 | /* If the offset is smaller than a shifted interval, do nothing */ |
956 | if (offset < timekeeper.cycle_interval<<shift) | 953 | if (offset < timekeeper.cycle_interval<<shift) |
957 | return offset; | 954 | return offset; |
958 | 955 | ||
@@ -962,9 +959,11 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) | |||
962 | 959 | ||
963 | timekeeper.xtime_nsec += timekeeper.xtime_interval << shift; | 960 | timekeeper.xtime_nsec += timekeeper.xtime_interval << shift; |
964 | while (timekeeper.xtime_nsec >= nsecps) { | 961 | while (timekeeper.xtime_nsec >= nsecps) { |
962 | int leap; | ||
965 | timekeeper.xtime_nsec -= nsecps; | 963 | timekeeper.xtime_nsec -= nsecps; |
966 | timekeeper.xtime.tv_sec++; | 964 | timekeeper.xtime.tv_sec++; |
967 | second_overflow(); | 965 | leap = second_overflow(timekeeper.xtime.tv_sec); |
966 | timekeeper.xtime.tv_sec += leap; | ||
968 | } | 967 | } |
969 | 968 | ||
970 | /* Accumulate raw time */ | 969 | /* Accumulate raw time */ |
@@ -1018,13 +1017,13 @@ static void update_wall_time(void) | |||
1018 | * With NO_HZ we may have to accumulate many cycle_intervals | 1017 | * With NO_HZ we may have to accumulate many cycle_intervals |
1019 | * (think "ticks") worth of time at once. To do this efficiently, | 1018 | * (think "ticks") worth of time at once. To do this efficiently, |
1020 | * we calculate the largest doubling multiple of cycle_intervals | 1019 | * we calculate the largest doubling multiple of cycle_intervals |
1021 | * that is smaller then the offset. We then accumulate that | 1020 | * that is smaller than the offset. We then accumulate that |
1022 | * chunk in one go, and then try to consume the next smaller | 1021 | * chunk in one go, and then try to consume the next smaller |
1023 | * doubled multiple. | 1022 | * doubled multiple. |
1024 | */ | 1023 | */ |
1025 | shift = ilog2(offset) - ilog2(timekeeper.cycle_interval); | 1024 | shift = ilog2(offset) - ilog2(timekeeper.cycle_interval); |
1026 | shift = max(0, shift); | 1025 | shift = max(0, shift); |
1027 | /* Bound shift to one less then what overflows tick_length */ | 1026 | /* Bound shift to one less than what overflows tick_length */ |
1028 | maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1; | 1027 | maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1; |
1029 | shift = min(shift, maxshift); | 1028 | shift = min(shift, maxshift); |
1030 | while (offset >= timekeeper.cycle_interval) { | 1029 | while (offset >= timekeeper.cycle_interval) { |
@@ -1072,12 +1071,14 @@ static void update_wall_time(void) | |||
1072 | 1071 | ||
1073 | /* | 1072 | /* |
1074 | * Finally, make sure that after the rounding | 1073 | * Finally, make sure that after the rounding |
1075 | * xtime.tv_nsec isn't larger then NSEC_PER_SEC | 1074 | * xtime.tv_nsec isn't larger than NSEC_PER_SEC |
1076 | */ | 1075 | */ |
1077 | if (unlikely(timekeeper.xtime.tv_nsec >= NSEC_PER_SEC)) { | 1076 | if (unlikely(timekeeper.xtime.tv_nsec >= NSEC_PER_SEC)) { |
1077 | int leap; | ||
1078 | timekeeper.xtime.tv_nsec -= NSEC_PER_SEC; | 1078 | timekeeper.xtime.tv_nsec -= NSEC_PER_SEC; |
1079 | timekeeper.xtime.tv_sec++; | 1079 | timekeeper.xtime.tv_sec++; |
1080 | second_overflow(); | 1080 | leap = second_overflow(timekeeper.xtime.tv_sec); |
1081 | timekeeper.xtime.tv_sec += leap; | ||
1081 | } | 1082 | } |
1082 | 1083 | ||
1083 | timekeeping_update(false); | 1084 | timekeeping_update(false); |