aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/hrtimer.c
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2006-02-09 04:29:00 -0500
committerJeff Garzik <jgarzik@pobox.com>2006-02-09 04:29:00 -0500
commit9caafa6c8686e319cf4d5f3757b3972c6c522b7c (patch)
treeb38979b835b5d22e681b175d0b98a3c7560d9c59 /kernel/hrtimer.c
parent51e9f2ff83df6b1c81c5c44f4486c68ed87aa20e (diff)
parentcac0e8e8bb2e7a086643bdd00c41d900a79bb4fa (diff)
Merge branch 'upstream-fixes'
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r--kernel/hrtimer.c70
1 files changed, 35 insertions, 35 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index f1c4155b49ac..2b6e1757aedd 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -21,6 +21,12 @@
21 * Credits: 21 * Credits:
22 * based on kernel/timer.c 22 * based on kernel/timer.c
23 * 23 *
24 * Help, testing, suggestions, bugfixes, improvements were
25 * provided by:
26 *
27 * George Anzinger, Andrew Morton, Steven Rostedt, Roman Zippel
28 * et. al.
29 *
24 * For licencing details see kernel-base/COPYING 30 * For licencing details see kernel-base/COPYING
25 */ 31 */
26 32
@@ -66,6 +72,12 @@ EXPORT_SYMBOL_GPL(ktime_get_real);
66 72
67/* 73/*
68 * The timer bases: 74 * The timer bases:
75 *
76 * Note: If we want to add new timer bases, we have to skip the two
77 * clock ids captured by the cpu-timers. We do this by holding empty
78 * entries rather than doing math adjustment of the clock ids.
79 * This ensures that we capture erroneous accesses to these clock ids
80 * rather than moving them into the range of valid clock id's.
69 */ 81 */
70 82
71#define MAX_HRTIMER_BASES 2 83#define MAX_HRTIMER_BASES 2
@@ -483,29 +495,25 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
483} 495}
484 496
485/** 497/**
486 * hrtimer_rebase - rebase an initialized hrtimer to a different base 498 * hrtimer_init - initialize a timer to the given clock
487 * 499 *
488 * @timer: the timer to be rebased 500 * @timer: the timer to be initialized
489 * @clock_id: the clock to be used 501 * @clock_id: the clock to be used
502 * @mode: timer mode abs/rel
490 */ 503 */
491void hrtimer_rebase(struct hrtimer *timer, const clockid_t clock_id) 504void hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
505 enum hrtimer_mode mode)
492{ 506{
493 struct hrtimer_base *bases; 507 struct hrtimer_base *bases;
494 508
509 memset(timer, 0, sizeof(struct hrtimer));
510
495 bases = per_cpu(hrtimer_bases, raw_smp_processor_id()); 511 bases = per_cpu(hrtimer_bases, raw_smp_processor_id());
496 timer->base = &bases[clock_id];
497}
498 512
499/** 513 if (clock_id == CLOCK_REALTIME && mode != HRTIMER_ABS)
500 * hrtimer_init - initialize a timer to the given clock 514 clock_id = CLOCK_MONOTONIC;
501 * 515
502 * @timer: the timer to be initialized 516 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} 517}
510 518
511/** 519/**
@@ -550,6 +558,7 @@ static inline void run_hrtimer_queue(struct hrtimer_base *base)
550 fn = timer->function; 558 fn = timer->function;
551 data = timer->data; 559 data = timer->data;
552 set_curr_timer(base, timer); 560 set_curr_timer(base, timer);
561 timer->state = HRTIMER_RUNNING;
553 __remove_hrtimer(timer, base); 562 __remove_hrtimer(timer, base);
554 spin_unlock_irq(&base->lock); 563 spin_unlock_irq(&base->lock);
555 564
@@ -565,6 +574,10 @@ static inline void run_hrtimer_queue(struct hrtimer_base *base)
565 574
566 spin_lock_irq(&base->lock); 575 spin_lock_irq(&base->lock);
567 576
577 /* Another CPU has added back the timer */
578 if (timer->state != HRTIMER_RUNNING)
579 continue;
580
568 if (restart == HRTIMER_RESTART) 581 if (restart == HRTIMER_RESTART)
569 enqueue_hrtimer(timer, base); 582 enqueue_hrtimer(timer, base);
570 else 583 else
@@ -638,8 +651,7 @@ schedule_hrtimer_interruptible(struct hrtimer *timer,
638 return schedule_hrtimer(timer, mode); 651 return schedule_hrtimer(timer, mode);
639} 652}
640 653
641static long __sched 654static long __sched nanosleep_restart(struct restart_block *restart)
642nanosleep_restart(struct restart_block *restart, clockid_t clockid)
643{ 655{
644 struct timespec __user *rmtp; 656 struct timespec __user *rmtp;
645 struct timespec tu; 657 struct timespec tu;
@@ -649,7 +661,7 @@ nanosleep_restart(struct restart_block *restart, clockid_t clockid)
649 661
650 restart->fn = do_no_restart_syscall; 662 restart->fn = do_no_restart_syscall;
651 663
652 hrtimer_init(&timer, clockid); 664 hrtimer_init(&timer, (clockid_t) restart->arg3, HRTIMER_ABS);
653 665
654 timer.expires.tv64 = ((u64)restart->arg1 << 32) | (u64) restart->arg0; 666 timer.expires.tv64 = ((u64)restart->arg1 << 32) | (u64) restart->arg0;
655 667
@@ -669,16 +681,6 @@ nanosleep_restart(struct restart_block *restart, clockid_t clockid)
669 return -ERESTART_RESTARTBLOCK; 681 return -ERESTART_RESTARTBLOCK;
670} 682}
671 683
672static long __sched nanosleep_restart_mono(struct restart_block *restart)
673{
674 return nanosleep_restart(restart, CLOCK_MONOTONIC);
675}
676
677static long __sched nanosleep_restart_real(struct restart_block *restart)
678{
679 return nanosleep_restart(restart, CLOCK_REALTIME);
680}
681
682long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, 684long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
683 const enum hrtimer_mode mode, const clockid_t clockid) 685 const enum hrtimer_mode mode, const clockid_t clockid)
684{ 686{
@@ -687,7 +689,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
687 struct timespec tu; 689 struct timespec tu;
688 ktime_t rem; 690 ktime_t rem;
689 691
690 hrtimer_init(&timer, clockid); 692 hrtimer_init(&timer, clockid, mode);
691 693
692 timer.expires = timespec_to_ktime(*rqtp); 694 timer.expires = timespec_to_ktime(*rqtp);
693 695
@@ -695,7 +697,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
695 if (rem.tv64 <= 0) 697 if (rem.tv64 <= 0)
696 return 0; 698 return 0;
697 699
698 /* Absolute timers do not update the rmtp value: */ 700 /* Absolute timers do not update the rmtp value and restart: */
699 if (mode == HRTIMER_ABS) 701 if (mode == HRTIMER_ABS)
700 return -ERESTARTNOHAND; 702 return -ERESTARTNOHAND;
701 703
@@ -705,11 +707,11 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
705 return -EFAULT; 707 return -EFAULT;
706 708
707 restart = &current_thread_info()->restart_block; 709 restart = &current_thread_info()->restart_block;
708 restart->fn = (clockid == CLOCK_MONOTONIC) ? 710 restart->fn = nanosleep_restart;
709 nanosleep_restart_mono : nanosleep_restart_real;
710 restart->arg0 = timer.expires.tv64 & 0xFFFFFFFF; 711 restart->arg0 = timer.expires.tv64 & 0xFFFFFFFF;
711 restart->arg1 = timer.expires.tv64 >> 32; 712 restart->arg1 = timer.expires.tv64 >> 32;
712 restart->arg2 = (unsigned long) rmtp; 713 restart->arg2 = (unsigned long) rmtp;
714 restart->arg3 = (unsigned long) timer.base->index;
713 715
714 return -ERESTART_RESTARTBLOCK; 716 return -ERESTART_RESTARTBLOCK;
715} 717}
@@ -736,10 +738,8 @@ static void __devinit init_hrtimers_cpu(int cpu)
736 struct hrtimer_base *base = per_cpu(hrtimer_bases, cpu); 738 struct hrtimer_base *base = per_cpu(hrtimer_bases, cpu);
737 int i; 739 int i;
738 740
739 for (i = 0; i < MAX_HRTIMER_BASES; i++) { 741 for (i = 0; i < MAX_HRTIMER_BASES; i++, base++)
740 spin_lock_init(&base->lock); 742 spin_lock_init(&base->lock);
741 base++;
742 }
743} 743}
744 744
745#ifdef CONFIG_HOTPLUG_CPU 745#ifdef CONFIG_HOTPLUG_CPU