aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/hrtimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r--kernel/hrtimer.c59
1 files changed, 24 insertions, 35 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index f580dd9db286..efff9496b2fa 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -66,6 +66,12 @@ EXPORT_SYMBOL_GPL(ktime_get_real);
66 66
67/* 67/*
68 * The timer bases: 68 * The timer bases:
69 *
70 * Note: If we want to add new timer bases, we have to skip the two
71 * clock ids captured by the cpu-timers. We do this by holding empty
72 * entries rather than doing math adjustment of the clock ids.
73 * This ensures that we capture erroneous accesses to these clock ids
74 * rather than moving them into the range of valid clock id's.
69 */ 75 */
70 76
71#define MAX_HRTIMER_BASES 2 77#define MAX_HRTIMER_BASES 2
@@ -483,29 +489,25 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
483} 489}
484 490
485/** 491/**
486 * hrtimer_rebase - rebase an initialized hrtimer to a different base 492 * hrtimer_init - initialize a timer to the given clock
487 * 493 *
488 * @timer: the timer to be rebased 494 * @timer: the timer to be initialized
489 * @clock_id: the clock to be used 495 * @clock_id: the clock to be used
496 * @mode: timer mode abs/rel
490 */ 497 */
491void hrtimer_rebase(struct hrtimer *timer, const clockid_t clock_id) 498void hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
499 enum hrtimer_mode mode)
492{ 500{
493 struct hrtimer_base *bases; 501 struct hrtimer_base *bases;
494 502
503 memset(timer, 0, sizeof(struct hrtimer));
504
495 bases = per_cpu(hrtimer_bases, raw_smp_processor_id()); 505 bases = per_cpu(hrtimer_bases, raw_smp_processor_id());
496 timer->base = &bases[clock_id];
497}
498 506
499/** 507 if (clock_id == CLOCK_REALTIME && mode != HRTIMER_ABS)
500 * hrtimer_init - initialize a timer to the given clock 508 clock_id = CLOCK_MONOTONIC;
501 * 509
502 * @timer: the timer to be initialized 510 timer->base = &bases[clock_id];
503 * @clock_id: the clock to be used
504 */
505void hrtimer_init(struct hrtimer *timer, const clockid_t clock_id)
506{
507 memset(timer, 0, sizeof(struct hrtimer));
508 hrtimer_rebase(timer, clock_id);
509} 511}
510 512
511/** 513/**
@@ -643,8 +645,7 @@ schedule_hrtimer_interruptible(struct hrtimer *timer,
643 return schedule_hrtimer(timer, mode); 645 return schedule_hrtimer(timer, mode);
644} 646}
645 647
646static long __sched 648static long __sched nanosleep_restart(struct restart_block *restart)
647nanosleep_restart(struct restart_block *restart, clockid_t clockid)
648{ 649{
649 struct timespec __user *rmtp; 650 struct timespec __user *rmtp;
650 struct timespec tu; 651 struct timespec tu;
@@ -654,7 +655,7 @@ nanosleep_restart(struct restart_block *restart, clockid_t clockid)
654 655
655 restart->fn = do_no_restart_syscall; 656 restart->fn = do_no_restart_syscall;
656 657
657 hrtimer_init(&timer, clockid); 658 hrtimer_init(&timer, (clockid_t) restart->arg3, HRTIMER_ABS);
658 659
659 timer.expires.tv64 = ((u64)restart->arg1 << 32) | (u64) restart->arg0; 660 timer.expires.tv64 = ((u64)restart->arg1 << 32) | (u64) restart->arg0;
660 661
@@ -674,16 +675,6 @@ nanosleep_restart(struct restart_block *restart, clockid_t clockid)
674 return -ERESTART_RESTARTBLOCK; 675 return -ERESTART_RESTARTBLOCK;
675} 676}
676 677
677static long __sched nanosleep_restart_mono(struct restart_block *restart)
678{
679 return nanosleep_restart(restart, CLOCK_MONOTONIC);
680}
681
682static long __sched nanosleep_restart_real(struct restart_block *restart)
683{
684 return nanosleep_restart(restart, CLOCK_REALTIME);
685}
686
687long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, 678long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
688 const enum hrtimer_mode mode, const clockid_t clockid) 679 const enum hrtimer_mode mode, const clockid_t clockid)
689{ 680{
@@ -692,7 +683,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
692 struct timespec tu; 683 struct timespec tu;
693 ktime_t rem; 684 ktime_t rem;
694 685
695 hrtimer_init(&timer, clockid); 686 hrtimer_init(&timer, clockid, mode);
696 687
697 timer.expires = timespec_to_ktime(*rqtp); 688 timer.expires = timespec_to_ktime(*rqtp);
698 689
@@ -700,7 +691,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
700 if (rem.tv64 <= 0) 691 if (rem.tv64 <= 0)
701 return 0; 692 return 0;
702 693
703 /* Absolute timers do not update the rmtp value: */ 694 /* Absolute timers do not update the rmtp value and restart: */
704 if (mode == HRTIMER_ABS) 695 if (mode == HRTIMER_ABS)
705 return -ERESTARTNOHAND; 696 return -ERESTARTNOHAND;
706 697
@@ -710,11 +701,11 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
710 return -EFAULT; 701 return -EFAULT;
711 702
712 restart = &current_thread_info()->restart_block; 703 restart = &current_thread_info()->restart_block;
713 restart->fn = (clockid == CLOCK_MONOTONIC) ? 704 restart->fn = nanosleep_restart;
714 nanosleep_restart_mono : nanosleep_restart_real;
715 restart->arg0 = timer.expires.tv64 & 0xFFFFFFFF; 705 restart->arg0 = timer.expires.tv64 & 0xFFFFFFFF;
716 restart->arg1 = timer.expires.tv64 >> 32; 706 restart->arg1 = timer.expires.tv64 >> 32;
717 restart->arg2 = (unsigned long) rmtp; 707 restart->arg2 = (unsigned long) rmtp;
708 restart->arg3 = (unsigned long) timer.base->index;
718 709
719 return -ERESTART_RESTARTBLOCK; 710 return -ERESTART_RESTARTBLOCK;
720} 711}
@@ -741,10 +732,8 @@ static void __devinit init_hrtimers_cpu(int cpu)
741 struct hrtimer_base *base = per_cpu(hrtimer_bases, cpu); 732 struct hrtimer_base *base = per_cpu(hrtimer_bases, cpu);
742 int i; 733 int i;
743 734
744 for (i = 0; i < MAX_HRTIMER_BASES; i++) { 735 for (i = 0; i < MAX_HRTIMER_BASES; i++, base++)
745 spin_lock_init(&base->lock); 736 spin_lock_init(&base->lock);
746 base++;
747 }
748} 737}
749 738
750#ifdef CONFIG_HOTPLUG_CPU 739#ifdef CONFIG_HOTPLUG_CPU