diff options
| -rw-r--r-- | kernel/time/timekeeping.c | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 2b021b0e8507..025e136f3881 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
| @@ -802,14 +802,44 @@ static void timekeeping_adjust(s64 offset) | |||
| 802 | s64 error, interval = timekeeper.cycle_interval; | 802 | s64 error, interval = timekeeper.cycle_interval; |
| 803 | int adj; | 803 | int adj; |
| 804 | 804 | ||
| 805 | /* | ||
| 806 | * The point of this is to check if the error is greater then half | ||
| 807 | * an interval. | ||
| 808 | * | ||
| 809 | * First we shift it down from NTP_SHIFT to clocksource->shifted nsecs. | ||
| 810 | * | ||
| 811 | * Note we subtract one in the shift, so that error is really error*2. | ||
| 812 | * This "saves" dividing(shifting) intererval twice, but keeps the | ||
| 813 | * (error > interval) comparision as still measuring if error is | ||
| 814 | * larger then half an interval. | ||
| 815 | * | ||
| 816 | * Note: It does not "save" on aggrivation when reading the code. | ||
| 817 | */ | ||
| 805 | error = timekeeper.ntp_error >> (timekeeper.ntp_error_shift - 1); | 818 | error = timekeeper.ntp_error >> (timekeeper.ntp_error_shift - 1); |
| 806 | if (error > interval) { | 819 | if (error > interval) { |
| 820 | /* | ||
| 821 | * We now divide error by 4(via shift), which checks if | ||
| 822 | * the error is greater then twice the interval. | ||
| 823 | * If it is greater, we need a bigadjust, if its smaller, | ||
| 824 | * we can adjust by 1. | ||
| 825 | */ | ||
| 807 | error >>= 2; | 826 | error >>= 2; |
| 827 | /* | ||
| 828 | * XXX - In update_wall_time, we round up to the next | ||
| 829 | * nanosecond, and store the amount rounded up into | ||
| 830 | * the error. This causes the likely below to be unlikely. | ||
| 831 | * | ||
| 832 | * The properfix is to avoid rounding up by using | ||
| 833 | * the high precision timekeeper.xtime_nsec instead of | ||
| 834 | * xtime.tv_nsec everywhere. Fixing this will take some | ||
| 835 | * time. | ||
| 836 | */ | ||
| 808 | if (likely(error <= interval)) | 837 | if (likely(error <= interval)) |
| 809 | adj = 1; | 838 | adj = 1; |
| 810 | else | 839 | else |
| 811 | adj = timekeeping_bigadjust(error, &interval, &offset); | 840 | adj = timekeeping_bigadjust(error, &interval, &offset); |
| 812 | } else if (error < -interval) { | 841 | } else if (error < -interval) { |
| 842 | /* See comment above, this is just switched for the negative */ | ||
| 813 | error >>= 2; | 843 | error >>= 2; |
| 814 | if (likely(error >= -interval)) { | 844 | if (likely(error >= -interval)) { |
| 815 | adj = -1; | 845 | adj = -1; |
| @@ -817,9 +847,58 @@ static void timekeeping_adjust(s64 offset) | |||
| 817 | offset = -offset; | 847 | offset = -offset; |
| 818 | } else | 848 | } else |
| 819 | adj = timekeeping_bigadjust(error, &interval, &offset); | 849 | adj = timekeeping_bigadjust(error, &interval, &offset); |
| 820 | } else | 850 | } else /* No adjustment needed */ |
| 821 | return; | 851 | return; |
| 822 | 852 | ||
| 853 | /* | ||
| 854 | * So the following can be confusing. | ||
| 855 | * | ||
| 856 | * To keep things simple, lets assume adj == 1 for now. | ||
| 857 | * | ||
| 858 | * When adj != 1, remember that the interval and offset values | ||
| 859 | * have been appropriately scaled so the math is the same. | ||
| 860 | * | ||
| 861 | * The basic idea here is that we're increasing the multiplier | ||
| 862 | * by one, this causes the xtime_interval to be incremented by | ||
| 863 | * one cycle_interval. This is because: | ||
| 864 | * xtime_interval = cycle_interval * mult | ||
| 865 | * So if mult is being incremented by one: | ||
| 866 | * xtime_interval = cycle_interval * (mult + 1) | ||
| 867 | * Its the same as: | ||
| 868 | * xtime_interval = (cycle_interval * mult) + cycle_interval | ||
| 869 | * Which can be shortened to: | ||
| 870 | * xtime_interval += cycle_interval | ||
| 871 | * | ||
| 872 | * So offset stores the non-accumulated cycles. Thus the current | ||
| 873 | * time (in shifted nanoseconds) is: | ||
| 874 | * now = (offset * adj) + xtime_nsec | ||
| 875 | * Now, even though we're adjusting the clock frequency, we have | ||
| 876 | * to keep time consistent. In other words, we can't jump back | ||
| 877 | * in time, and we also want to avoid jumping forward in time. | ||
| 878 | * | ||
| 879 | * So given the same offset value, we need the time to be the same | ||
| 880 | * both before and after the freq adjustment. | ||
| 881 | * now = (offset * adj_1) + xtime_nsec_1 | ||
| 882 | * now = (offset * adj_2) + xtime_nsec_2 | ||
| 883 | * So: | ||
| 884 | * (offset * adj_1) + xtime_nsec_1 = | ||
| 885 | * (offset * adj_2) + xtime_nsec_2 | ||
| 886 | * And we know: | ||
| 887 | * adj_2 = adj_1 + 1 | ||
| 888 | * So: | ||
| 889 | * (offset * adj_1) + xtime_nsec_1 = | ||
| 890 | * (offset * (adj_1+1)) + xtime_nsec_2 | ||
| 891 | * (offset * adj_1) + xtime_nsec_1 = | ||
| 892 | * (offset * adj_1) + offset + xtime_nsec_2 | ||
| 893 | * Canceling the sides: | ||
| 894 | * xtime_nsec_1 = offset + xtime_nsec_2 | ||
| 895 | * Which gives us: | ||
| 896 | * xtime_nsec_2 = xtime_nsec_1 - offset | ||
| 897 | * Which simplfies to: | ||
| 898 | * xtime_nsec -= offset | ||
| 899 | * | ||
| 900 | * XXX - TODO: Doc ntp_error calculation. | ||
| 901 | */ | ||
| 823 | timekeeper.mult += adj; | 902 | timekeeper.mult += adj; |
| 824 | timekeeper.xtime_interval += interval; | 903 | timekeeper.xtime_interval += interval; |
| 825 | timekeeper.xtime_nsec -= offset; | 904 | timekeeper.xtime_nsec -= offset; |
