diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/acct.c | 2 | ||||
-rw-r--r-- | kernel/hrtimer.c | 6 | ||||
-rw-r--r-- | kernel/time.c | 16 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 38 | ||||
-rw-r--r-- | kernel/tsacct.c | 2 |
5 files changed, 40 insertions, 24 deletions
diff --git a/kernel/acct.c b/kernel/acct.c index 70d0d88e5554..24f0f8b2ba72 100644 --- a/kernel/acct.c +++ b/kernel/acct.c | |||
@@ -468,7 +468,7 @@ static void do_acct_process(struct file *file) | |||
468 | } | 468 | } |
469 | #endif | 469 | #endif |
470 | do_div(elapsed, AHZ); | 470 | do_div(elapsed, AHZ); |
471 | ac.ac_btime = xtime.tv_sec - elapsed; | 471 | ac.ac_btime = get_seconds() - elapsed; |
472 | /* we really need to bite the bullet and change layout */ | 472 | /* we really need to bite the bullet and change layout */ |
473 | ac.ac_uid = current->uid; | 473 | ac.ac_uid = current->uid; |
474 | ac.ac_gid = current->gid; | 474 | ac.ac_gid = current->gid; |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index eb1ddebd2c04..c21ca6bfaa66 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -141,11 +141,7 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) | |||
141 | 141 | ||
142 | do { | 142 | do { |
143 | seq = read_seqbegin(&xtime_lock); | 143 | seq = read_seqbegin(&xtime_lock); |
144 | #ifdef CONFIG_NO_HZ | 144 | xts = current_kernel_time(); |
145 | getnstimeofday(&xts); | ||
146 | #else | ||
147 | xts = xtime; | ||
148 | #endif | ||
149 | tom = wall_to_monotonic; | 145 | tom = wall_to_monotonic; |
150 | } while (read_seqretry(&xtime_lock, seq)); | 146 | } while (read_seqretry(&xtime_lock, seq)); |
151 | 147 | ||
diff --git a/kernel/time.c b/kernel/time.c index 5b81da08bbdb..2289a8d68314 100644 --- a/kernel/time.c +++ b/kernel/time.c | |||
@@ -215,22 +215,6 @@ asmlinkage long sys_adjtimex(struct timex __user *txc_p) | |||
215 | return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret; | 215 | return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret; |
216 | } | 216 | } |
217 | 217 | ||
218 | inline struct timespec current_kernel_time(void) | ||
219 | { | ||
220 | struct timespec now; | ||
221 | unsigned long seq; | ||
222 | |||
223 | do { | ||
224 | seq = read_seqbegin(&xtime_lock); | ||
225 | |||
226 | now = xtime; | ||
227 | } while (read_seqretry(&xtime_lock, seq)); | ||
228 | |||
229 | return now; | ||
230 | } | ||
231 | |||
232 | EXPORT_SYMBOL(current_kernel_time); | ||
233 | |||
234 | /** | 218 | /** |
235 | * current_fs_time - Return FS time | 219 | * current_fs_time - Return FS time |
236 | * @sb: Superblock. | 220 | * @sb: Superblock. |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 88c81026e003..acc417b5a9b7 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -47,10 +47,22 @@ EXPORT_SYMBOL(xtime_lock); | |||
47 | struct timespec xtime __attribute__ ((aligned (16))); | 47 | struct timespec xtime __attribute__ ((aligned (16))); |
48 | struct timespec wall_to_monotonic __attribute__ ((aligned (16))); | 48 | struct timespec wall_to_monotonic __attribute__ ((aligned (16))); |
49 | static unsigned long total_sleep_time; /* seconds */ | 49 | static unsigned long total_sleep_time; /* seconds */ |
50 | |||
51 | EXPORT_SYMBOL(xtime); | 50 | EXPORT_SYMBOL(xtime); |
52 | 51 | ||
53 | 52 | ||
53 | #ifdef CONFIG_NO_HZ | ||
54 | static struct timespec xtime_cache __attribute__ ((aligned (16))); | ||
55 | static inline void update_xtime_cache(u64 nsec) | ||
56 | { | ||
57 | xtime_cache = xtime; | ||
58 | timespec_add_ns(&xtime_cache, nsec); | ||
59 | } | ||
60 | #else | ||
61 | #define xtime_cache xtime | ||
62 | /* We do *not* want to evaluate the argument for this case */ | ||
63 | #define update_xtime_cache(n) do { } while (0) | ||
64 | #endif | ||
65 | |||
54 | static struct clocksource *clock; /* pointer to current clocksource */ | 66 | static struct clocksource *clock; /* pointer to current clocksource */ |
55 | 67 | ||
56 | 68 | ||
@@ -478,6 +490,8 @@ void update_wall_time(void) | |||
478 | xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift; | 490 | xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift; |
479 | clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift; | 491 | clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift; |
480 | 492 | ||
493 | update_xtime_cache(cyc2ns(clock, offset)); | ||
494 | |||
481 | /* check to see if there is a new clocksource to use */ | 495 | /* check to see if there is a new clocksource to use */ |
482 | change_clocksource(); | 496 | change_clocksource(); |
483 | update_vsyscall(&xtime, clock); | 497 | update_vsyscall(&xtime, clock); |
@@ -509,3 +523,25 @@ void monotonic_to_bootbased(struct timespec *ts) | |||
509 | { | 523 | { |
510 | ts->tv_sec += total_sleep_time; | 524 | ts->tv_sec += total_sleep_time; |
511 | } | 525 | } |
526 | |||
527 | unsigned long get_seconds(void) | ||
528 | { | ||
529 | return xtime_cache.tv_sec; | ||
530 | } | ||
531 | EXPORT_SYMBOL(get_seconds); | ||
532 | |||
533 | |||
534 | struct timespec current_kernel_time(void) | ||
535 | { | ||
536 | struct timespec now; | ||
537 | unsigned long seq; | ||
538 | |||
539 | do { | ||
540 | seq = read_seqbegin(&xtime_lock); | ||
541 | |||
542 | now = xtime_cache; | ||
543 | } while (read_seqretry(&xtime_lock, seq)); | ||
544 | |||
545 | return now; | ||
546 | } | ||
547 | EXPORT_SYMBOL(current_kernel_time); | ||
diff --git a/kernel/tsacct.c b/kernel/tsacct.c index 658f638c402c..c122131a122f 100644 --- a/kernel/tsacct.c +++ b/kernel/tsacct.c | |||
@@ -39,7 +39,7 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) | |||
39 | ac_etime = timespec_to_ns(&ts); | 39 | ac_etime = timespec_to_ns(&ts); |
40 | do_div(ac_etime, NSEC_PER_USEC); | 40 | do_div(ac_etime, NSEC_PER_USEC); |
41 | stats->ac_etime = ac_etime; | 41 | stats->ac_etime = ac_etime; |
42 | stats->ac_btime = xtime.tv_sec - ts.tv_sec; | 42 | stats->ac_btime = get_seconds() - ts.tv_sec; |
43 | if (thread_group_leader(tsk)) { | 43 | if (thread_group_leader(tsk)) { |
44 | stats->ac_exitcode = tsk->exit_code; | 44 | stats->ac_exitcode = tsk->exit_code; |
45 | if (tsk->flags & PF_FORKNOEXEC) | 45 | if (tsk->flags & PF_FORKNOEXEC) |