diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-06-20 14:15:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-06-20 14:15:13 -0400 |
commit | 4db88eb4c300333ed37585f75ab9a664ec537d68 (patch) | |
tree | 08b65728c54965970d711131dd83077ebb97b407 | |
parent | 53d5defcfa8c9603554a3174cbe206fb69f6e8ef (diff) | |
parent | f5d00c1f9adb350c24c5301600f7bf2da99b66de (diff) |
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer fixes from Thomas Gleixner:
- Fix inconstinant clock usage in virtual time accounting
- Fix a build error in KVM caused by the NOHZ work
- Remove a pointless timekeeping duty assignment which breaks NOHZ
- Use a proper notifier return value to avoid random behaviour
* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
tick: Remove useless timekeeping duty attribution to broadcast source
nohz: Fix notifier return val that enforce timekeeping
kvm: Move guest entry/exit APIs to context_tracking
vtime: Use consistent clocks among nohz accounting
-rw-r--r-- | include/linux/context_tracking.h | 35 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 37 | ||||
-rw-r--r-- | include/linux/vtime.h | 4 | ||||
-rw-r--r-- | kernel/context_tracking.c | 1 | ||||
-rw-r--r-- | kernel/sched/core.c | 2 | ||||
-rw-r--r-- | kernel/sched/cputime.c | 6 | ||||
-rw-r--r-- | kernel/time/tick-broadcast.c | 4 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 2 |
8 files changed, 43 insertions, 48 deletions
diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h index 365f4a61bf04..fc09d7b0dacf 100644 --- a/include/linux/context_tracking.h +++ b/include/linux/context_tracking.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
5 | #include <linux/percpu.h> | 5 | #include <linux/percpu.h> |
6 | #include <linux/vtime.h> | ||
6 | #include <asm/ptrace.h> | 7 | #include <asm/ptrace.h> |
7 | 8 | ||
8 | struct context_tracking { | 9 | struct context_tracking { |
@@ -19,6 +20,26 @@ struct context_tracking { | |||
19 | } state; | 20 | } state; |
20 | }; | 21 | }; |
21 | 22 | ||
23 | static inline void __guest_enter(void) | ||
24 | { | ||
25 | /* | ||
26 | * This is running in ioctl context so we can avoid | ||
27 | * the call to vtime_account() with its unnecessary idle check. | ||
28 | */ | ||
29 | vtime_account_system(current); | ||
30 | current->flags |= PF_VCPU; | ||
31 | } | ||
32 | |||
33 | static inline void __guest_exit(void) | ||
34 | { | ||
35 | /* | ||
36 | * This is running in ioctl context so we can avoid | ||
37 | * the call to vtime_account() with its unnecessary idle check. | ||
38 | */ | ||
39 | vtime_account_system(current); | ||
40 | current->flags &= ~PF_VCPU; | ||
41 | } | ||
42 | |||
22 | #ifdef CONFIG_CONTEXT_TRACKING | 43 | #ifdef CONFIG_CONTEXT_TRACKING |
23 | DECLARE_PER_CPU(struct context_tracking, context_tracking); | 44 | DECLARE_PER_CPU(struct context_tracking, context_tracking); |
24 | 45 | ||
@@ -35,6 +56,9 @@ static inline bool context_tracking_active(void) | |||
35 | extern void user_enter(void); | 56 | extern void user_enter(void); |
36 | extern void user_exit(void); | 57 | extern void user_exit(void); |
37 | 58 | ||
59 | extern void guest_enter(void); | ||
60 | extern void guest_exit(void); | ||
61 | |||
38 | static inline enum ctx_state exception_enter(void) | 62 | static inline enum ctx_state exception_enter(void) |
39 | { | 63 | { |
40 | enum ctx_state prev_ctx; | 64 | enum ctx_state prev_ctx; |
@@ -57,6 +81,17 @@ extern void context_tracking_task_switch(struct task_struct *prev, | |||
57 | static inline bool context_tracking_in_user(void) { return false; } | 81 | static inline bool context_tracking_in_user(void) { return false; } |
58 | static inline void user_enter(void) { } | 82 | static inline void user_enter(void) { } |
59 | static inline void user_exit(void) { } | 83 | static inline void user_exit(void) { } |
84 | |||
85 | static inline void guest_enter(void) | ||
86 | { | ||
87 | __guest_enter(); | ||
88 | } | ||
89 | |||
90 | static inline void guest_exit(void) | ||
91 | { | ||
92 | __guest_exit(); | ||
93 | } | ||
94 | |||
60 | static inline enum ctx_state exception_enter(void) { return 0; } | 95 | static inline enum ctx_state exception_enter(void) { return 0; } |
61 | static inline void exception_exit(enum ctx_state prev_ctx) { } | 96 | static inline void exception_exit(enum ctx_state prev_ctx) { } |
62 | static inline void context_tracking_task_switch(struct task_struct *prev, | 97 | static inline void context_tracking_task_switch(struct task_struct *prev, |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f0eea07d2c2b..8db53cfaccdb 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/ratelimit.h> | 23 | #include <linux/ratelimit.h> |
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/irqflags.h> | 25 | #include <linux/irqflags.h> |
26 | #include <linux/context_tracking.h> | ||
26 | #include <asm/signal.h> | 27 | #include <asm/signal.h> |
27 | 28 | ||
28 | #include <linux/kvm.h> | 29 | #include <linux/kvm.h> |
@@ -760,42 +761,6 @@ static inline int kvm_iommu_unmap_guest(struct kvm *kvm) | |||
760 | } | 761 | } |
761 | #endif | 762 | #endif |
762 | 763 | ||
763 | static inline void __guest_enter(void) | ||
764 | { | ||
765 | /* | ||
766 | * This is running in ioctl context so we can avoid | ||
767 | * the call to vtime_account() with its unnecessary idle check. | ||
768 | */ | ||
769 | vtime_account_system(current); | ||
770 | current->flags |= PF_VCPU; | ||
771 | } | ||
772 | |||
773 | static inline void __guest_exit(void) | ||
774 | { | ||
775 | /* | ||
776 | * This is running in ioctl context so we can avoid | ||
777 | * the call to vtime_account() with its unnecessary idle check. | ||
778 | */ | ||
779 | vtime_account_system(current); | ||
780 | current->flags &= ~PF_VCPU; | ||
781 | } | ||
782 | |||
783 | #ifdef CONFIG_CONTEXT_TRACKING | ||
784 | extern void guest_enter(void); | ||
785 | extern void guest_exit(void); | ||
786 | |||
787 | #else /* !CONFIG_CONTEXT_TRACKING */ | ||
788 | static inline void guest_enter(void) | ||
789 | { | ||
790 | __guest_enter(); | ||
791 | } | ||
792 | |||
793 | static inline void guest_exit(void) | ||
794 | { | ||
795 | __guest_exit(); | ||
796 | } | ||
797 | #endif /* !CONFIG_CONTEXT_TRACKING */ | ||
798 | |||
799 | static inline void kvm_guest_enter(void) | 764 | static inline void kvm_guest_enter(void) |
800 | { | 765 | { |
801 | unsigned long flags; | 766 | unsigned long flags; |
diff --git a/include/linux/vtime.h b/include/linux/vtime.h index 71a5782d8c59..b1dd2db80076 100644 --- a/include/linux/vtime.h +++ b/include/linux/vtime.h | |||
@@ -34,7 +34,7 @@ static inline void vtime_user_exit(struct task_struct *tsk) | |||
34 | } | 34 | } |
35 | extern void vtime_guest_enter(struct task_struct *tsk); | 35 | extern void vtime_guest_enter(struct task_struct *tsk); |
36 | extern void vtime_guest_exit(struct task_struct *tsk); | 36 | extern void vtime_guest_exit(struct task_struct *tsk); |
37 | extern void vtime_init_idle(struct task_struct *tsk); | 37 | extern void vtime_init_idle(struct task_struct *tsk, int cpu); |
38 | #else | 38 | #else |
39 | static inline void vtime_account_irq_exit(struct task_struct *tsk) | 39 | static inline void vtime_account_irq_exit(struct task_struct *tsk) |
40 | { | 40 | { |
@@ -45,7 +45,7 @@ static inline void vtime_user_enter(struct task_struct *tsk) { } | |||
45 | static inline void vtime_user_exit(struct task_struct *tsk) { } | 45 | static inline void vtime_user_exit(struct task_struct *tsk) { } |
46 | static inline void vtime_guest_enter(struct task_struct *tsk) { } | 46 | static inline void vtime_guest_enter(struct task_struct *tsk) { } |
47 | static inline void vtime_guest_exit(struct task_struct *tsk) { } | 47 | static inline void vtime_guest_exit(struct task_struct *tsk) { } |
48 | static inline void vtime_init_idle(struct task_struct *tsk) { } | 48 | static inline void vtime_init_idle(struct task_struct *tsk, int cpu) { } |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING | 51 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING |
diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c index 65349f07b878..85bdde1137eb 100644 --- a/kernel/context_tracking.c +++ b/kernel/context_tracking.c | |||
@@ -15,7 +15,6 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/context_tracking.h> | 17 | #include <linux/context_tracking.h> |
18 | #include <linux/kvm_host.h> | ||
19 | #include <linux/rcupdate.h> | 18 | #include <linux/rcupdate.h> |
20 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
21 | #include <linux/hardirq.h> | 20 | #include <linux/hardirq.h> |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 58453b8272fd..e1a27f918723 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -4745,7 +4745,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) | |||
4745 | */ | 4745 | */ |
4746 | idle->sched_class = &idle_sched_class; | 4746 | idle->sched_class = &idle_sched_class; |
4747 | ftrace_graph_init_idle_task(idle, cpu); | 4747 | ftrace_graph_init_idle_task(idle, cpu); |
4748 | vtime_init_idle(idle); | 4748 | vtime_init_idle(idle, cpu); |
4749 | #if defined(CONFIG_SMP) | 4749 | #if defined(CONFIG_SMP) |
4750 | sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu); | 4750 | sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu); |
4751 | #endif | 4751 | #endif |
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index cc2dc3eea8a3..b5ccba22603b 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c | |||
@@ -747,17 +747,17 @@ void arch_vtime_task_switch(struct task_struct *prev) | |||
747 | 747 | ||
748 | write_seqlock(¤t->vtime_seqlock); | 748 | write_seqlock(¤t->vtime_seqlock); |
749 | current->vtime_snap_whence = VTIME_SYS; | 749 | current->vtime_snap_whence = VTIME_SYS; |
750 | current->vtime_snap = sched_clock(); | 750 | current->vtime_snap = sched_clock_cpu(smp_processor_id()); |
751 | write_sequnlock(¤t->vtime_seqlock); | 751 | write_sequnlock(¤t->vtime_seqlock); |
752 | } | 752 | } |
753 | 753 | ||
754 | void vtime_init_idle(struct task_struct *t) | 754 | void vtime_init_idle(struct task_struct *t, int cpu) |
755 | { | 755 | { |
756 | unsigned long flags; | 756 | unsigned long flags; |
757 | 757 | ||
758 | write_seqlock_irqsave(&t->vtime_seqlock, flags); | 758 | write_seqlock_irqsave(&t->vtime_seqlock, flags); |
759 | t->vtime_snap_whence = VTIME_SYS; | 759 | t->vtime_snap_whence = VTIME_SYS; |
760 | t->vtime_snap = sched_clock(); | 760 | t->vtime_snap = sched_clock_cpu(cpu); |
761 | write_sequnlock_irqrestore(&t->vtime_seqlock, flags); | 761 | write_sequnlock_irqrestore(&t->vtime_seqlock, flags); |
762 | } | 762 | } |
763 | 763 | ||
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 0c739423b0f9..b4c245580b79 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
@@ -698,10 +698,6 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | |||
698 | 698 | ||
699 | bc->event_handler = tick_handle_oneshot_broadcast; | 699 | bc->event_handler = tick_handle_oneshot_broadcast; |
700 | 700 | ||
701 | /* Take the do_timer update */ | ||
702 | if (!tick_nohz_full_cpu(cpu)) | ||
703 | tick_do_timer_cpu = cpu; | ||
704 | |||
705 | /* | 701 | /* |
706 | * We must be careful here. There might be other CPUs | 702 | * We must be careful here. There might be other CPUs |
707 | * waiting for periodic broadcast. We need to set the | 703 | * waiting for periodic broadcast. We need to set the |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index f4208138fbf4..0cf1c1453181 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -306,7 +306,7 @@ static int __cpuinit tick_nohz_cpu_down_callback(struct notifier_block *nfb, | |||
306 | * we can't safely shutdown that CPU. | 306 | * we can't safely shutdown that CPU. |
307 | */ | 307 | */ |
308 | if (have_nohz_full_mask && tick_do_timer_cpu == cpu) | 308 | if (have_nohz_full_mask && tick_do_timer_cpu == cpu) |
309 | return -EINVAL; | 309 | return NOTIFY_BAD; |
310 | break; | 310 | break; |
311 | } | 311 | } |
312 | return NOTIFY_OK; | 312 | return NOTIFY_OK; |