aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-05 20:46:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-05 20:46:42 -0400
commite7fda6c4c3c1a7d6996dd75fd84670fa0b5d448f (patch)
treedaa51c16462c318b890acf7f01fba5827275dd74 /fs
parent08d69a25714429850cf9ef71f22d8cdc9189d93f (diff)
parent953dec21aed4038464fec02f96a2f1b8701a5bce (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.c4
-rw-r--r--fs/proc/array.c7
-rw-r--r--fs/timerfd.c77
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)
306static void nsm_init_private(struct nsm_handle *nsm) 306static 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 */
93void timerfd_clock_was_set(void) 94void 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
291static 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
319static 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
287static const struct file_operations timerfd_fops = { 354static 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
294static int timerfd_fget(int fd, struct fd *p) 363static 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));