diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-05 20:46:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-05 20:46:42 -0400 |
commit | e7fda6c4c3c1a7d6996dd75fd84670fa0b5d448f (patch) | |
tree | daa51c16462c318b890acf7f01fba5827275dd74 /fs | |
parent | 08d69a25714429850cf9ef71f22d8cdc9189d93f (diff) | |
parent | 953dec21aed4038464fec02f96a2f1b8701a5bce (diff) |
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer and time updates from Thomas Gleixner:
"A rather large update of timers, timekeeping & co
- Core timekeeping code is year-2038 safe now for 32bit machines.
Now we just need to fix all in kernel users and the gazillion of
user space interfaces which rely on timespec/timeval :)
- Better cache layout for the timekeeping internal data structures.
- Proper nanosecond based interfaces for in kernel users.
- Tree wide cleanup of code which wants nanoseconds but does hoops
and loops to convert back and forth from timespecs. Some of it
definitely belongs into the ugly code museum.
- Consolidation of the timekeeping interface zoo.
- A fast NMI safe accessor to clock monotonic for tracing. This is a
long standing request to support correlated user/kernel space
traces. With proper NTP frequency correction it's also suitable
for correlation of traces accross separate machines.
- Checkpoint/restart support for timerfd.
- A few NOHZ[_FULL] improvements in the [hr]timer code.
- Code move from kernel to kernel/time of all time* related code.
- New clocksource/event drivers from the ARM universe. I'm really
impressed that despite an architected timer in the newer chips SoC
manufacturers insist on inventing new and differently broken SoC
specific timers.
[ Ed. "Impressed"? I don't think that word means what you think it means ]
- Another round of code move from arch to drivers. Looks like most
of the legacy mess in ARM regarding timers is sorted out except for
a few obnoxious strongholds.
- The usual updates and fixlets all over the place"
* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (114 commits)
timekeeping: Fixup typo in update_vsyscall_old definition
clocksource: document some basic timekeeping concepts
timekeeping: Use cached ntp_tick_length when accumulating error
timekeeping: Rework frequency adjustments to work better w/ nohz
timekeeping: Minor fixup for timespec64->timespec assignment
ftrace: Provide trace clocks monotonic
timekeeping: Provide fast and NMI safe access to CLOCK_MONOTONIC
seqcount: Add raw_write_seqcount_latch()
seqcount: Provide raw_read_seqcount()
timekeeping: Use tk_read_base as argument for timekeeping_get_ns()
timekeeping: Create struct tk_read_base and use it in struct timekeeper
timekeeping: Restructure the timekeeper some more
clocksource: Get rid of cycle_last
clocksource: Move cycle_last validation to core code
clocksource: Make delta calculation a function
wireless: ath9k: Get rid of timespec conversions
drm: vmwgfx: Use nsec based interfaces
drm: i915: Use nsec based interfaces
timekeeping: Provide ktime_get_raw()
hangcheck-timer: Use ktime_get_ns()
...
Diffstat (limited to 'fs')
-rw-r--r-- | fs/lockd/mon.c | 4 | ||||
-rw-r--r-- | fs/proc/array.c | 7 | ||||
-rw-r--r-- | fs/timerfd.c | 77 |
3 files changed, 75 insertions, 13 deletions
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 1812f026960c..daa8e7514eae 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
@@ -306,11 +306,9 @@ static struct nsm_handle *nsm_lookup_priv(const struct nsm_private *priv) | |||
306 | static void nsm_init_private(struct nsm_handle *nsm) | 306 | static void nsm_init_private(struct nsm_handle *nsm) |
307 | { | 307 | { |
308 | u64 *p = (u64 *)&nsm->sm_priv.data; | 308 | u64 *p = (u64 *)&nsm->sm_priv.data; |
309 | struct timespec ts; | ||
310 | s64 ns; | 309 | s64 ns; |
311 | 310 | ||
312 | ktime_get_ts(&ts); | 311 | ns = ktime_get_ns(); |
313 | ns = timespec_to_ns(&ts); | ||
314 | put_unaligned(ns, p); | 312 | put_unaligned(ns, p); |
315 | put_unaligned((unsigned long)nsm, p + 1); | 313 | put_unaligned((unsigned long)nsm, p + 1); |
316 | } | 314 | } |
diff --git a/fs/proc/array.c b/fs/proc/array.c index 64db2bceac59..d7f9199217bb 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -473,13 +473,8 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, | |||
473 | priority = task_prio(task); | 473 | priority = task_prio(task); |
474 | nice = task_nice(task); | 474 | nice = task_nice(task); |
475 | 475 | ||
476 | /* Temporary variable needed for gcc-2.96 */ | ||
477 | /* convert timespec -> nsec*/ | ||
478 | start_time = | ||
479 | (unsigned long long)task->real_start_time.tv_sec * NSEC_PER_SEC | ||
480 | + task->real_start_time.tv_nsec; | ||
481 | /* convert nsec -> ticks */ | 476 | /* convert nsec -> ticks */ |
482 | start_time = nsec_to_clock_t(start_time); | 477 | start_time = nsec_to_clock_t(task->real_start_time); |
483 | 478 | ||
484 | seq_printf(m, "%d (%s) %c", pid_nr_ns(pid, ns), tcomm, state); | 479 | seq_printf(m, "%d (%s) %c", pid_nr_ns(pid, ns), tcomm, state); |
485 | seq_put_decimal_ll(m, ' ', ppid); | 480 | seq_put_decimal_ll(m, ' ', ppid); |
diff --git a/fs/timerfd.c b/fs/timerfd.c index 0013142c0475..80c350216ea8 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c | |||
@@ -35,8 +35,9 @@ struct timerfd_ctx { | |||
35 | ktime_t moffs; | 35 | ktime_t moffs; |
36 | wait_queue_head_t wqh; | 36 | wait_queue_head_t wqh; |
37 | u64 ticks; | 37 | u64 ticks; |
38 | int expired; | ||
39 | int clockid; | 38 | int clockid; |
39 | short unsigned expired; | ||
40 | short unsigned settime_flags; /* to show in fdinfo */ | ||
40 | struct rcu_head rcu; | 41 | struct rcu_head rcu; |
41 | struct list_head clist; | 42 | struct list_head clist; |
42 | bool might_cancel; | 43 | bool might_cancel; |
@@ -92,7 +93,7 @@ static enum alarmtimer_restart timerfd_alarmproc(struct alarm *alarm, | |||
92 | */ | 93 | */ |
93 | void timerfd_clock_was_set(void) | 94 | void timerfd_clock_was_set(void) |
94 | { | 95 | { |
95 | ktime_t moffs = ktime_get_monotonic_offset(); | 96 | ktime_t moffs = ktime_mono_to_real((ktime_t){ .tv64 = 0 }); |
96 | struct timerfd_ctx *ctx; | 97 | struct timerfd_ctx *ctx; |
97 | unsigned long flags; | 98 | unsigned long flags; |
98 | 99 | ||
@@ -125,7 +126,7 @@ static bool timerfd_canceled(struct timerfd_ctx *ctx) | |||
125 | { | 126 | { |
126 | if (!ctx->might_cancel || ctx->moffs.tv64 != KTIME_MAX) | 127 | if (!ctx->might_cancel || ctx->moffs.tv64 != KTIME_MAX) |
127 | return false; | 128 | return false; |
128 | ctx->moffs = ktime_get_monotonic_offset(); | 129 | ctx->moffs = ktime_mono_to_real((ktime_t){ .tv64 = 0 }); |
129 | return true; | 130 | return true; |
130 | } | 131 | } |
131 | 132 | ||
@@ -196,6 +197,8 @@ static int timerfd_setup(struct timerfd_ctx *ctx, int flags, | |||
196 | if (timerfd_canceled(ctx)) | 197 | if (timerfd_canceled(ctx)) |
197 | return -ECANCELED; | 198 | return -ECANCELED; |
198 | } | 199 | } |
200 | |||
201 | ctx->settime_flags = flags & TFD_SETTIME_FLAGS; | ||
199 | return 0; | 202 | return 0; |
200 | } | 203 | } |
201 | 204 | ||
@@ -284,11 +287,77 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count, | |||
284 | return res; | 287 | return res; |
285 | } | 288 | } |
286 | 289 | ||
290 | #ifdef CONFIG_PROC_FS | ||
291 | static int timerfd_show(struct seq_file *m, struct file *file) | ||
292 | { | ||
293 | struct timerfd_ctx *ctx = file->private_data; | ||
294 | struct itimerspec t; | ||
295 | |||
296 | spin_lock_irq(&ctx->wqh.lock); | ||
297 | t.it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | ||
298 | t.it_interval = ktime_to_timespec(ctx->tintv); | ||
299 | spin_unlock_irq(&ctx->wqh.lock); | ||
300 | |||
301 | return seq_printf(m, | ||
302 | "clockid: %d\n" | ||
303 | "ticks: %llu\n" | ||
304 | "settime flags: 0%o\n" | ||
305 | "it_value: (%llu, %llu)\n" | ||
306 | "it_interval: (%llu, %llu)\n", | ||
307 | ctx->clockid, (unsigned long long)ctx->ticks, | ||
308 | ctx->settime_flags, | ||
309 | (unsigned long long)t.it_value.tv_sec, | ||
310 | (unsigned long long)t.it_value.tv_nsec, | ||
311 | (unsigned long long)t.it_interval.tv_sec, | ||
312 | (unsigned long long)t.it_interval.tv_nsec); | ||
313 | } | ||
314 | #else | ||
315 | #define timerfd_show NULL | ||
316 | #endif | ||
317 | |||
318 | #ifdef CONFIG_CHECKPOINT_RESTORE | ||
319 | static long timerfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
320 | { | ||
321 | struct timerfd_ctx *ctx = file->private_data; | ||
322 | int ret = 0; | ||
323 | |||
324 | switch (cmd) { | ||
325 | case TFD_IOC_SET_TICKS: { | ||
326 | u64 ticks; | ||
327 | |||
328 | if (copy_from_user(&ticks, (u64 __user *)arg, sizeof(ticks))) | ||
329 | return -EFAULT; | ||
330 | if (!ticks) | ||
331 | return -EINVAL; | ||
332 | |||
333 | spin_lock_irq(&ctx->wqh.lock); | ||
334 | if (!timerfd_canceled(ctx)) { | ||
335 | ctx->ticks = ticks; | ||
336 | if (ticks) | ||
337 | wake_up_locked(&ctx->wqh); | ||
338 | } else | ||
339 | ret = -ECANCELED; | ||
340 | spin_unlock_irq(&ctx->wqh.lock); | ||
341 | break; | ||
342 | } | ||
343 | default: | ||
344 | ret = -ENOTTY; | ||
345 | break; | ||
346 | } | ||
347 | |||
348 | return ret; | ||
349 | } | ||
350 | #else | ||
351 | #define timerfd_ioctl NULL | ||
352 | #endif | ||
353 | |||
287 | static const struct file_operations timerfd_fops = { | 354 | static const struct file_operations timerfd_fops = { |
288 | .release = timerfd_release, | 355 | .release = timerfd_release, |
289 | .poll = timerfd_poll, | 356 | .poll = timerfd_poll, |
290 | .read = timerfd_read, | 357 | .read = timerfd_read, |
291 | .llseek = noop_llseek, | 358 | .llseek = noop_llseek, |
359 | .show_fdinfo = timerfd_show, | ||
360 | .unlocked_ioctl = timerfd_ioctl, | ||
292 | }; | 361 | }; |
293 | 362 | ||
294 | static int timerfd_fget(int fd, struct fd *p) | 363 | static int timerfd_fget(int fd, struct fd *p) |
@@ -336,7 +405,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) | |||
336 | else | 405 | else |
337 | hrtimer_init(&ctx->t.tmr, clockid, HRTIMER_MODE_ABS); | 406 | hrtimer_init(&ctx->t.tmr, clockid, HRTIMER_MODE_ABS); |
338 | 407 | ||
339 | ctx->moffs = ktime_get_monotonic_offset(); | 408 | ctx->moffs = ktime_mono_to_real((ktime_t){ .tv64 = 0 }); |
340 | 409 | ||
341 | ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx, | 410 | ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx, |
342 | O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS)); | 411 | O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS)); |