Merge branch 'fortglx/4.14/time' of https://git.linaro.org/people/john.stultz/linux into timers/core

Pull timekeepig updates from John Stultz

- kselftest improvements

- Use the proper timekeeper in the debug code

- Prevent accessing an unavailable wakeup source in the alarmtimer sysfs
interface.

+106 -18
+9 -2
kernel/time/alarmtimer.c
··· 56 static DEFINE_SPINLOCK(freezer_delta_lock); 57 #endif 58 59 static struct wakeup_source *ws; 60 61 - #ifdef CONFIG_RTC_CLASS 62 /* rtc timer and device for setting alarm wakeups at suspend */ 63 static struct rtc_timer rtctimer; 64 static struct rtc_device *rtcdev; ··· 89 { 90 unsigned long flags; 91 struct rtc_device *rtc = to_rtc_device(dev); 92 93 if (rtcdev) 94 return -EBUSY; ··· 99 if (!device_may_wakeup(rtc->dev.parent)) 100 return -1; 101 102 spin_lock_irqsave(&rtcdev_lock, flags); 103 if (!rtcdev) { 104 rtcdev = rtc; 105 /* hold a reference so it doesn't go away */ 106 get_device(dev); 107 } 108 spin_unlock_irqrestore(&rtcdev_lock, flags); 109 return 0; 110 } 111 ··· 868 error = PTR_ERR(pdev); 869 goto out_drv; 870 } 871 - ws = wakeup_source_register("alarmtimer"); 872 return 0; 873 874 out_drv:
··· 56 static DEFINE_SPINLOCK(freezer_delta_lock); 57 #endif 58 59 + #ifdef CONFIG_RTC_CLASS 60 static struct wakeup_source *ws; 61 62 /* rtc timer and device for setting alarm wakeups at suspend */ 63 static struct rtc_timer rtctimer; 64 static struct rtc_device *rtcdev; ··· 89 { 90 unsigned long flags; 91 struct rtc_device *rtc = to_rtc_device(dev); 92 + struct wakeup_source *__ws; 93 94 if (rtcdev) 95 return -EBUSY; ··· 98 if (!device_may_wakeup(rtc->dev.parent)) 99 return -1; 100 101 + __ws = wakeup_source_register("alarmtimer"); 102 + 103 spin_lock_irqsave(&rtcdev_lock, flags); 104 if (!rtcdev) { 105 rtcdev = rtc; 106 /* hold a reference so it doesn't go away */ 107 get_device(dev); 108 + ws = __ws; 109 + __ws = NULL; 110 } 111 spin_unlock_irqrestore(&rtcdev_lock, flags); 112 + 113 + wakeup_source_unregister(__ws); 114 + 115 return 0; 116 } 117 ··· 860 error = PTR_ERR(pdev); 861 goto out_drv; 862 } 863 return 0; 864 865 out_drv:
+1 -1
kernel/time/timekeeping.c
··· 2066 goto out; 2067 2068 /* Do some additional sanity checking */ 2069 - timekeeping_check_update(real_tk, offset); 2070 2071 /* 2072 * With NO_HZ we may have to accumulate many cycle_intervals
··· 2066 goto out; 2067 2068 /* Do some additional sanity checking */ 2069 + timekeeping_check_update(tk, offset); 2070 2071 /* 2072 * With NO_HZ we may have to accumulate many cycle_intervals
+6 -2
tools/testing/selftests/timers/freq-step.c
··· 33 #define MAX_FREQ_ERROR 10e-6 34 #define MAX_STDDEV 1000e-9 35 36 struct sample { 37 double offset; 38 double time; ··· 266 set_frequency(0.0); 267 268 if (fails) 269 - ksft_exit_fail(); 270 271 - ksft_exit_pass(); 272 }
··· 33 #define MAX_FREQ_ERROR 10e-6 34 #define MAX_STDDEV 1000e-9 35 36 + #ifndef ADJ_SETOFFSET 37 + #define ADJ_SETOFFSET 0x0100 38 + #endif 39 + 40 struct sample { 41 double offset; 42 double time; ··· 262 set_frequency(0.0); 263 264 if (fails) 265 + return ksft_exit_fail(); 266 267 + return ksft_exit_pass(); 268 }
+90 -13
tools/testing/selftests/timers/set-timer-lat.c
··· 20 */ 21 22 23 #include <stdio.h> 24 #include <unistd.h> 25 #include <time.h> ··· 64 int clock_id; 65 struct timespec start_time; 66 long long max_latency_ns; 67 68 char *clockstring(int clockid) 69 { ··· 117 delta_ns -= NSEC_PER_SEC * TIMER_SECS * alarmcount; 118 119 if (delta_ns < 0) 120 - printf("%s timer fired early: FAIL\n", clockstring(clock_id)); 121 122 if (delta_ns > max_latency_ns) 123 max_latency_ns = delta_ns; 124 } 125 126 - int do_timer(int clock_id, int flags) 127 { 128 struct sigevent se; 129 - timer_t tm1; 130 struct itimerspec its1, its2; 131 int err; 132 ··· 145 146 max_latency_ns = 0; 147 alarmcount = 0; 148 149 - err = timer_create(clock_id, &se, &tm1); 150 if (err) { 151 if ((clock_id == CLOCK_REALTIME_ALARM) || 152 (clock_id == CLOCK_BOOTTIME_ALARM)) { ··· 168 its1.it_value.tv_sec = TIMER_SECS; 169 its1.it_value.tv_nsec = 0; 170 } 171 - its1.it_interval.tv_sec = TIMER_SECS; 172 its1.it_interval.tv_nsec = 0; 173 174 - err = timer_settime(tm1, flags, &its1, &its2); 175 if (err) { 176 printf("%s - timer_settime() failed\n", clockstring(clock_id)); 177 return -1; 178 } 179 180 - while (alarmcount < 5) 181 - sleep(1); 182 183 - printf("%-22s %s max latency: %10lld ns : ", 184 - clockstring(clock_id), 185 - flags ? "ABSTIME":"RELTIME", 186 - max_latency_ns); 187 188 - timer_delete(tm1); 189 if (max_latency_ns < UNRESONABLE_LATENCY) { 190 printf("[OK]\n"); 191 return 0; 192 } 193 printf("[FAILED]\n"); 194 return -1; 195 } 196 197 int main(void) ··· 284 285 ret |= do_timer(clock_id, TIMER_ABSTIME); 286 ret |= do_timer(clock_id, 0); 287 } 288 if (ret) 289 return ksft_exit_fail();
··· 20 */ 21 22 23 + #include <errno.h> 24 #include <stdio.h> 25 #include <unistd.h> 26 #include <time.h> ··· 63 int clock_id; 64 struct timespec start_time; 65 long long max_latency_ns; 66 + int timer_fired_early; 67 68 char *clockstring(int clockid) 69 { ··· 115 delta_ns -= NSEC_PER_SEC * TIMER_SECS * alarmcount; 116 117 if (delta_ns < 0) 118 + timer_fired_early = 1; 119 120 if (delta_ns > max_latency_ns) 121 max_latency_ns = delta_ns; 122 } 123 124 + void describe_timer(int flags, int interval) 125 + { 126 + printf("%-22s %s %s ", 127 + clockstring(clock_id), 128 + flags ? "ABSTIME":"RELTIME", 129 + interval ? "PERIODIC":"ONE-SHOT"); 130 + } 131 + 132 + int setup_timer(int clock_id, int flags, int interval, timer_t *tm1) 133 { 134 struct sigevent se; 135 struct itimerspec its1, its2; 136 int err; 137 ··· 136 137 max_latency_ns = 0; 138 alarmcount = 0; 139 + timer_fired_early = 0; 140 141 + err = timer_create(clock_id, &se, tm1); 142 if (err) { 143 if ((clock_id == CLOCK_REALTIME_ALARM) || 144 (clock_id == CLOCK_BOOTTIME_ALARM)) { ··· 158 its1.it_value.tv_sec = TIMER_SECS; 159 its1.it_value.tv_nsec = 0; 160 } 161 + its1.it_interval.tv_sec = interval; 162 its1.it_interval.tv_nsec = 0; 163 164 + err = timer_settime(*tm1, flags, &its1, &its2); 165 if (err) { 166 printf("%s - timer_settime() failed\n", clockstring(clock_id)); 167 return -1; 168 } 169 170 + return 0; 171 + } 172 173 + int check_timer_latency(int flags, int interval) 174 + { 175 + int err = 0; 176 177 + describe_timer(flags, interval); 178 + printf("timer fired early: %7d : ", timer_fired_early); 179 + if (!timer_fired_early) { 180 + printf("[OK]\n"); 181 + } else { 182 + printf("[FAILED]\n"); 183 + err = -1; 184 + } 185 + 186 + describe_timer(flags, interval); 187 + printf("max latency: %10lld ns : ", max_latency_ns); 188 + 189 if (max_latency_ns < UNRESONABLE_LATENCY) { 190 + printf("[OK]\n"); 191 + } else { 192 + printf("[FAILED]\n"); 193 + err = -1; 194 + } 195 + return err; 196 + } 197 + 198 + int check_alarmcount(int flags, int interval) 199 + { 200 + describe_timer(flags, interval); 201 + printf("count: %19d : ", alarmcount); 202 + if (alarmcount == 1) { 203 printf("[OK]\n"); 204 return 0; 205 } 206 printf("[FAILED]\n"); 207 return -1; 208 + } 209 + 210 + int do_timer(int clock_id, int flags) 211 + { 212 + timer_t tm1; 213 + const int interval = TIMER_SECS; 214 + int err; 215 + 216 + err = setup_timer(clock_id, flags, interval, &tm1); 217 + if (err) 218 + return err; 219 + 220 + while (alarmcount < 5) 221 + sleep(1); 222 + 223 + timer_delete(tm1); 224 + return check_timer_latency(flags, interval); 225 + } 226 + 227 + int do_timer_oneshot(int clock_id, int flags) 228 + { 229 + timer_t tm1; 230 + const int interval = 0; 231 + struct timeval timeout; 232 + fd_set fds; 233 + int err; 234 + 235 + err = setup_timer(clock_id, flags, interval, &tm1); 236 + if (err) 237 + return err; 238 + 239 + memset(&timeout, 0, sizeof(timeout)); 240 + timeout.tv_sec = 5; 241 + FD_ZERO(&fds); 242 + do { 243 + err = select(FD_SETSIZE, &fds, NULL, NULL, &timeout); 244 + } while (err == -1 && errno == EINTR); 245 + 246 + timer_delete(tm1); 247 + err = check_timer_latency(flags, interval); 248 + err |= check_alarmcount(flags, interval); 249 + return err; 250 } 251 252 int main(void) ··· 209 210 ret |= do_timer(clock_id, TIMER_ABSTIME); 211 ret |= do_timer(clock_id, 0); 212 + ret |= do_timer_oneshot(clock_id, TIMER_ABSTIME); 213 + ret |= do_timer_oneshot(clock_id, 0); 214 } 215 if (ret) 216 return ksft_exit_fail();