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