aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/hrtimer.h5
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/hrtimer.c59
-rw-r--r--kernel/posix-timers.c37
4 files changed, 36 insertions, 67 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index c657f3d4924a..6361544bb6ae 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -101,9 +101,8 @@ struct hrtimer_base {
101/* Exported timer functions: */ 101/* Exported timer functions: */
102 102
103/* Initialize timers: */ 103/* Initialize timers: */
104extern void hrtimer_init(struct hrtimer *timer, const clockid_t which_clock); 104extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock,
105extern void hrtimer_rebase(struct hrtimer *timer, const clockid_t which_clock); 105 enum hrtimer_mode mode);
106
107 106
108/* Basic timer operations: */ 107/* Basic timer operations: */
109extern int hrtimer_start(struct hrtimer *timer, ktime_t tim, 108extern int hrtimer_start(struct hrtimer *timer, ktime_t tim,
diff --git a/kernel/fork.c b/kernel/fork.c
index 4ae8cfc1c89c..7f0ab5ee948c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -802,7 +802,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
802 init_sigpending(&sig->shared_pending); 802 init_sigpending(&sig->shared_pending);
803 INIT_LIST_HEAD(&sig->posix_timers); 803 INIT_LIST_HEAD(&sig->posix_timers);
804 804
805 hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC); 805 hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_REL);
806 sig->it_real_incr.tv64 = 0; 806 sig->it_real_incr.tv64 = 0;
807 sig->real_timer.function = it_real_fn; 807 sig->real_timer.function = it_real_fn;
808 sig->real_timer.data = tsk; 808 sig->real_timer.data = tsk;
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
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 3b606d361b52..28e72fd0029f 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -194,9 +194,7 @@ static inline int common_clock_set(const clockid_t which_clock,
194 194
195static int common_timer_create(struct k_itimer *new_timer) 195static int common_timer_create(struct k_itimer *new_timer)
196{ 196{
197 hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock); 197 hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0);
198 new_timer->it.real.timer.data = new_timer;
199 new_timer->it.real.timer.function = posix_timer_fn;
200 return 0; 198 return 0;
201} 199}
202 200
@@ -693,6 +691,7 @@ common_timer_set(struct k_itimer *timr, int flags,
693 struct itimerspec *new_setting, struct itimerspec *old_setting) 691 struct itimerspec *new_setting, struct itimerspec *old_setting)
694{ 692{
695 struct hrtimer *timer = &timr->it.real.timer; 693 struct hrtimer *timer = &timr->it.real.timer;
694 enum hrtimer_mode mode;
696 695
697 if (old_setting) 696 if (old_setting)
698 common_timer_get(timr, old_setting); 697 common_timer_get(timr, old_setting);
@@ -714,14 +713,10 @@ common_timer_set(struct k_itimer *timr, int flags,
714 if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec) 713 if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec)
715 return 0; 714 return 0;
716 715
717 /* Posix madness. Only absolute CLOCK_REALTIME timers 716 mode = flags & TIMER_ABSTIME ? HRTIMER_ABS : HRTIMER_REL;
718 * are affected by clock sets. So we must reiniatilize 717 hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
719 * the timer. 718 timr->it.real.timer.data = timr;
720 */ 719 timr->it.real.timer.function = posix_timer_fn;
721 if (timr->it_clock == CLOCK_REALTIME && (flags & TIMER_ABSTIME))
722 hrtimer_rebase(timer, CLOCK_REALTIME);
723 else
724 hrtimer_rebase(timer, CLOCK_MONOTONIC);
725 720
726 timer->expires = timespec_to_ktime(new_setting->it_value); 721 timer->expires = timespec_to_ktime(new_setting->it_value);
727 722
@@ -732,8 +727,7 @@ common_timer_set(struct k_itimer *timr, int flags,
732 if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) 727 if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
733 return 0; 728 return 0;
734 729
735 hrtimer_start(timer, timer->expires, (flags & TIMER_ABSTIME) ? 730 hrtimer_start(timer, timer->expires, mode);
736 HRTIMER_ABS : HRTIMER_REL);
737 return 0; 731 return 0;
738} 732}
739 733
@@ -948,21 +942,8 @@ sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp)
948static int common_nsleep(const clockid_t which_clock, int flags, 942static int common_nsleep(const clockid_t which_clock, int flags,
949 struct timespec *tsave, struct timespec __user *rmtp) 943 struct timespec *tsave, struct timespec __user *rmtp)
950{ 944{
951 int mode = flags & TIMER_ABSTIME ? HRTIMER_ABS : HRTIMER_REL; 945 return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
952 int clockid = which_clock; 946 HRTIMER_ABS : HRTIMER_REL, which_clock);
953
954 switch (which_clock) {
955 case CLOCK_REALTIME:
956 /* Posix madness. Only absolute timers on clock realtime
957 are affected by clock set. */
958 if (mode != HRTIMER_ABS)
959 clockid = CLOCK_MONOTONIC;
960 case CLOCK_MONOTONIC:
961 break;
962 default:
963 return -EINVAL;
964 }
965 return hrtimer_nanosleep(tsave, rmtp, mode, clockid);
966} 947}
967 948
968asmlinkage long 949asmlinkage long