Skip to contentSkip to conversation

NOHZ changes for v4.1

GIT PULL Ingo Molnar 1 participant 1 message Apr 14, 2015

Subsystems (6)
x86 KVM PowerPC Scheduler +2 more subsystems
lore
Share & tools
lore
#0 lore raw

Linus,

Please pull the latest timers-nohz-for-linus git tree from:

git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-nohz-for-linus

# HEAD: 1524b745406a85ba201cb25df72110c1ccac0f72 Merge branch 'nohz/guest' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks into timers/nohz

This tree adds full dynticks support to KVM guests (support the disabling of the timer tick on the guest): the main missing piece was the recognition of guest execution as RCU extended quiescent state and related changes.

Thanks,

Ingo

------------------>
Frederic Weisbecker (2):
ppc: Remove unused cpp symbols in kvm headers
context_tracking: Rename context symbols to prepare for transition state

Rik van Riel (5):
context_tracking: Generalize context tracking APIs to support user and guest
context_tracking: Add stub context_tracking_is_enabled
context_tracking: Run vtime_user_enter/exit only when state == CONTEXT_USER
context_tracking: Export context_tracking_user_enter/exit kvm,rcu,nohz: use RCU extended quiescent state when running KVM guest

 arch/powerpc/include/asm/kvm_book3s.h  |  4 ---
 arch/x86/kernel/traps.c                |  2 +-
 include/linux/context_tracking.h       | 15 +++++++--
 include/linux/context_tracking_state.h |  9 ++++--
 include/linux/kvm_host.h               |  3 +-
 kernel/context_tracking.c              | 59 ++++++++++++++++++++++------------
 kernel/sched/core.c                    |  2 +-
 7 files changed, 61 insertions(+), 33 deletions(-)
arch/powerpc/include/asm/kvm_book3s.h +0 -4
index 942c7b1678e3..993090422690 100644
@@ -106,10 +106,6 @@ struct kvmppc_vcpu_book3s {
 	spinlock_t mmu_lock;
 };
 
-#define CONTEXT_HOST		0
-#define CONTEXT_GUEST		1
-#define CONTEXT_GUEST_END	2
-
 #define VSID_REAL	0x07ffffffffc00000ULL
 #define VSID_BAT	0x07ffffffffb00000ULL
 #define VSID_64K	0x0800000000000000ULL
arch/x86/kernel/traps.c +1 -1
index 9d2073e2ecc9..756f74eed35d 100644
@@ -123,7 +123,7 @@ enum ctx_state ist_enter(struct pt_regs *regs)
 		 * but we need to notify RCU.
 		 */
 		rcu_nmi_enter();
-		prev_state = IN_KERNEL;  /* the value is irrelevant. */
+		prev_state = CONTEXT_KERNEL;  /* the value is irrelevant. */
 	}
 
 	/*
include/linux/context_tracking.h +12 -3
index 37b81bd51ec0..2821838256b4 100644
@@ -10,6 +10,8 @@
 #ifdef CONFIG_CONTEXT_TRACKING
 extern void context_tracking_cpu_set(int cpu);
 
+extern void context_tracking_enter(enum ctx_state state);
+extern void context_tracking_exit(enum ctx_state state);
 extern void context_tracking_user_enter(void);
 extern void context_tracking_user_exit(void);
 extern void __context_tracking_task_switch(struct task_struct *prev,
@@ -35,7 +37,8 @@ static inline enum ctx_state exception_enter(void)
 		return 0;
 
 	prev_ctx = this_cpu_read(context_tracking.state);
-	context_tracking_user_exit();
+	if (prev_ctx != CONTEXT_KERNEL)
+		context_tracking_exit(prev_ctx);
 
 	return prev_ctx;
 }
@@ -43,8 +46,8 @@ static inline enum ctx_state exception_enter(void)
 static inline void exception_exit(enum ctx_state prev_ctx)
 {
 	if (context_tracking_is_enabled()) {
-		if (prev_ctx == IN_USER)
-			context_tracking_user_enter();
+		if (prev_ctx != CONTEXT_KERNEL)
+			context_tracking_enter(prev_ctx);
 	}
 }
 
@@ -78,10 +81,16 @@ static inline void guest_enter(void)
 		vtime_guest_enter(current);
 	else
 		current->flags |= PF_VCPU;
+
+	if (context_tracking_is_enabled())
+		context_tracking_enter(CONTEXT_GUEST);
 }
 
 static inline void guest_exit(void)
 {
+	if (context_tracking_is_enabled())
+		context_tracking_exit(CONTEXT_GUEST);
+
 	if (vtime_accounting_enabled())
 		vtime_guest_exit(current);
 	else
include/linux/context_tracking_state.h +6 -3
index 97a81225d037..6b7b96a32b75 100644
@@ -13,8 +13,9 @@ struct context_tracking {
 	 */
 	bool active;
 	enum ctx_state {
-		IN_KERNEL = 0,
-		IN_USER,
+		CONTEXT_KERNEL = 0,
+		CONTEXT_USER,
+		CONTEXT_GUEST,
 	} state;
 };
 
@@ -34,11 +35,13 @@ static inline bool context_tracking_cpu_is_enabled(void)
 
 static inline bool context_tracking_in_user(void)
 {
-	return __this_cpu_read(context_tracking.state) == IN_USER;
+	return __this_cpu_read(context_tracking.state) == CONTEXT_USER;
 }
 #else
 static inline bool context_tracking_in_user(void) { return false; }
 static inline bool context_tracking_active(void) { return false; }
+static inline bool context_tracking_is_enabled(void) { return false; }
+static inline bool context_tracking_cpu_is_enabled(void) { return false; }
 #endif /* CONFIG_CONTEXT_TRACKING */
 
 #endif
include/linux/kvm_host.h +2 -1
index d12b2104d19b..cc8c61c5459c 100644
@@ -766,7 +766,8 @@ static inline void kvm_guest_enter(void)
 	 * one time slice). Lets treat guest mode as quiescent state, just like
 	 * we do with user-mode execution.
 	 */
-	rcu_virt_note_context_switch(smp_processor_id());
+	if (!context_tracking_cpu_is_enabled())
+		rcu_virt_note_context_switch(smp_processor_id());
 }
 
 static inline void kvm_guest_exit(void)
kernel/context_tracking.c +39 -20

114 lines not on this page · raw message

kernel/sched/core.c +1 -1
index f0f831e8a345..06b9a00871e0 100644
@@ -2818,7 +2818,7 @@ asmlinkage __visible void __sched schedule_user(void)
 	 * we find a better solution.
 	 *
 	 * NB: There are buggy callers of this function.  Ideally we
-	 * should warn if prev_state != IN_USER, but that will trigger
+	 * should warn if prev_state != CONTEXT_USER, but that will trigger
 	 * too frequently to make sense yet.
 	 */
 	enum ctx_state prev_state = exception_enter();