aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/hrtimer.c14
-rw-r--r--kernel/posix-timers.c16
-rw-r--r--kernel/time.c11
-rw-r--r--kernel/time/ntp.c18
-rw-r--r--kernel/time/tick-internal.h2
-rw-r--r--kernel/time/timekeeping.c282
-rw-r--r--kernel/trace/Kconfig24
-rw-r--r--kernel/trace/trace.c27
8 files changed, 301 insertions, 93 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 031184e3d872..d6830d5ae730 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -83,6 +83,12 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
83 .get_time = &ktime_get_boottime, 83 .get_time = &ktime_get_boottime,
84 .resolution = KTIME_LOW_RES, 84 .resolution = KTIME_LOW_RES,
85 }, 85 },
86 {
87 .index = HRTIMER_BASE_TAI,
88 .clockid = CLOCK_TAI,
89 .get_time = &ktime_get_clocktai,
90 .resolution = KTIME_LOW_RES,
91 },
86 } 92 }
87}; 93};
88 94
@@ -90,6 +96,7 @@ static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = {
90 [CLOCK_REALTIME] = HRTIMER_BASE_REALTIME, 96 [CLOCK_REALTIME] = HRTIMER_BASE_REALTIME,
91 [CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC, 97 [CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC,
92 [CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME, 98 [CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME,
99 [CLOCK_TAI] = HRTIMER_BASE_TAI,
93}; 100};
94 101
95static inline int hrtimer_clockid_to_base(clockid_t clock_id) 102static inline int hrtimer_clockid_to_base(clockid_t clock_id)
@@ -106,8 +113,10 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)
106{ 113{
107 ktime_t xtim, mono, boot; 114 ktime_t xtim, mono, boot;
108 struct timespec xts, tom, slp; 115 struct timespec xts, tom, slp;
116 s32 tai_offset;
109 117
110 get_xtime_and_monotonic_and_sleep_offset(&xts, &tom, &slp); 118 get_xtime_and_monotonic_and_sleep_offset(&xts, &tom, &slp);
119 tai_offset = timekeeping_get_tai_offset();
111 120
112 xtim = timespec_to_ktime(xts); 121 xtim = timespec_to_ktime(xts);
113 mono = ktime_add(xtim, timespec_to_ktime(tom)); 122 mono = ktime_add(xtim, timespec_to_ktime(tom));
@@ -115,6 +124,8 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)
115 base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim; 124 base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim;
116 base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono; 125 base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono;
117 base->clock_base[HRTIMER_BASE_BOOTTIME].softirq_time = boot; 126 base->clock_base[HRTIMER_BASE_BOOTTIME].softirq_time = boot;
127 base->clock_base[HRTIMER_BASE_TAI].softirq_time =
128 ktime_add(xtim, ktime_set(tai_offset, 0));
118} 129}
119 130
120/* 131/*
@@ -651,8 +662,9 @@ static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base)
651{ 662{
652 ktime_t *offs_real = &base->clock_base[HRTIMER_BASE_REALTIME].offset; 663 ktime_t *offs_real = &base->clock_base[HRTIMER_BASE_REALTIME].offset;
653 ktime_t *offs_boot = &base->clock_base[HRTIMER_BASE_BOOTTIME].offset; 664 ktime_t *offs_boot = &base->clock_base[HRTIMER_BASE_BOOTTIME].offset;
665 ktime_t *offs_tai = &base->clock_base[HRTIMER_BASE_TAI].offset;
654 666
655 return ktime_get_update_offsets(offs_real, offs_boot); 667 return ktime_get_update_offsets(offs_real, offs_boot, offs_tai);
656} 668}
657 669
658/* 670/*
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 6edbb2c55c22..2a2e173d0a7a 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -221,6 +221,11 @@ static int posix_get_boottime(const clockid_t which_clock, struct timespec *tp)
221 return 0; 221 return 0;
222} 222}
223 223
224static int posix_get_tai(clockid_t which_clock, struct timespec *tp)
225{
226 timekeeping_clocktai(tp);
227 return 0;
228}
224 229
225/* 230/*
226 * Initialize everything, well, just everything in Posix clocks/timers ;) 231 * Initialize everything, well, just everything in Posix clocks/timers ;)
@@ -261,6 +266,16 @@ static __init int init_posix_timers(void)
261 .clock_getres = posix_get_coarse_res, 266 .clock_getres = posix_get_coarse_res,
262 .clock_get = posix_get_monotonic_coarse, 267 .clock_get = posix_get_monotonic_coarse,
263 }; 268 };
269 struct k_clock clock_tai = {
270 .clock_getres = hrtimer_get_res,
271 .clock_get = posix_get_tai,
272 .nsleep = common_nsleep,
273 .nsleep_restart = hrtimer_nanosleep_restart,
274 .timer_create = common_timer_create,
275 .timer_set = common_timer_set,
276 .timer_get = common_timer_get,
277 .timer_del = common_timer_del,
278 };
264 struct k_clock clock_boottime = { 279 struct k_clock clock_boottime = {
265 .clock_getres = hrtimer_get_res, 280 .clock_getres = hrtimer_get_res,
266 .clock_get = posix_get_boottime, 281 .clock_get = posix_get_boottime,
@@ -278,6 +293,7 @@ static __init int init_posix_timers(void)
278 posix_timers_register_clock(CLOCK_REALTIME_COARSE, &clock_realtime_coarse); 293 posix_timers_register_clock(CLOCK_REALTIME_COARSE, &clock_realtime_coarse);
279 posix_timers_register_clock(CLOCK_MONOTONIC_COARSE, &clock_monotonic_coarse); 294 posix_timers_register_clock(CLOCK_MONOTONIC_COARSE, &clock_monotonic_coarse);
280 posix_timers_register_clock(CLOCK_BOOTTIME, &clock_boottime); 295 posix_timers_register_clock(CLOCK_BOOTTIME, &clock_boottime);
296 posix_timers_register_clock(CLOCK_TAI, &clock_tai);
281 297
282 posix_timers_cache = kmem_cache_create("posix_timers_cache", 298 posix_timers_cache = kmem_cache_create("posix_timers_cache",
283 sizeof (struct k_itimer), 0, SLAB_PANIC, 299 sizeof (struct k_itimer), 0, SLAB_PANIC,
diff --git a/kernel/time.c b/kernel/time.c
index f8342a41efa6..d3617dbd3dca 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -138,13 +138,14 @@ int persistent_clock_is_local;
138 */ 138 */
139static inline void warp_clock(void) 139static inline void warp_clock(void)
140{ 140{
141 struct timespec adjust; 141 if (sys_tz.tz_minuteswest != 0) {
142 struct timespec adjust;
142 143
143 adjust = current_kernel_time();
144 if (sys_tz.tz_minuteswest != 0)
145 persistent_clock_is_local = 1; 144 persistent_clock_is_local = 1;
146 adjust.tv_sec += sys_tz.tz_minuteswest * 60; 145 adjust.tv_sec = sys_tz.tz_minuteswest * 60;
147 do_settimeofday(&adjust); 146 adjust.tv_nsec = 0;
147 timekeeping_inject_offset(&adjust);
148 }
148} 149}
149 150
150/* 151/*
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 072bb066bb7d..59e2749be0fa 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -53,9 +53,6 @@ static int time_state = TIME_OK;
53/* clock status bits: */ 53/* clock status bits: */
54static int time_status = STA_UNSYNC; 54static int time_status = STA_UNSYNC;
55 55
56/* TAI offset (secs): */
57static long time_tai;
58
59/* time adjustment (nsecs): */ 56/* time adjustment (nsecs): */
60static s64 time_offset; 57static s64 time_offset;
61 58
@@ -415,7 +412,6 @@ int second_overflow(unsigned long secs)
415 else if (secs % 86400 == 0) { 412 else if (secs % 86400 == 0) {
416 leap = -1; 413 leap = -1;
417 time_state = TIME_OOP; 414 time_state = TIME_OOP;
418 time_tai++;
419 printk(KERN_NOTICE 415 printk(KERN_NOTICE
420 "Clock: inserting leap second 23:59:60 UTC\n"); 416 "Clock: inserting leap second 23:59:60 UTC\n");
421 } 417 }
@@ -425,7 +421,6 @@ int second_overflow(unsigned long secs)
425 time_state = TIME_OK; 421 time_state = TIME_OK;
426 else if ((secs + 1) % 86400 == 0) { 422 else if ((secs + 1) % 86400 == 0) {
427 leap = 1; 423 leap = 1;
428 time_tai--;
429 time_state = TIME_WAIT; 424 time_state = TIME_WAIT;
430 printk(KERN_NOTICE 425 printk(KERN_NOTICE
431 "Clock: deleting leap second 23:59:59 UTC\n"); 426 "Clock: deleting leap second 23:59:59 UTC\n");
@@ -579,7 +574,9 @@ static inline void process_adj_status(struct timex *txc, struct timespec *ts)
579 * Called with ntp_lock held, so we can access and modify 574 * Called with ntp_lock held, so we can access and modify
580 * all the global NTP state: 575 * all the global NTP state:
581 */ 576 */
582static inline void process_adjtimex_modes(struct timex *txc, struct timespec *ts) 577static inline void process_adjtimex_modes(struct timex *txc,
578 struct timespec *ts,
579 s32 *time_tai)
583{ 580{
584 if (txc->modes & ADJ_STATUS) 581 if (txc->modes & ADJ_STATUS)
585 process_adj_status(txc, ts); 582 process_adj_status(txc, ts);
@@ -613,7 +610,7 @@ static inline void process_adjtimex_modes(struct timex *txc, struct timespec *ts
613 } 610 }
614 611
615 if (txc->modes & ADJ_TAI && txc->constant > 0)