Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1524b745 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'nohz/guest' of...

Merge branch 'nohz/guest' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks

 into timers/nohz

Pull full dynticks support for virt guests from Frederic Weisbecker:

 "Some measurements showed that disabling the tick on the host while the
  guest is running can be interesting on some workloads. Indeed the
  host tick is irrelevant while a vcpu runs, it consumes CPU time and cache
  footprint for no good reasons.

  Full dynticks already works in every context, but RCU prevents it to
  be effective outside userspace, because the CPU needs to take part of
  RCU grace period completion as long as RCU may be used on it, which is
  the case in kernel context.

  However guest is similar to userspace and idle in that we know RCU is
  unused on such context. Therefore a CPU in guest/userspace/idle context
  can let other CPUs report its own RCU quiescent state on its behalf
  and shut down the tick safely, provided it isn't needed for other
  reasons than RCU. This is called RCU extended quiescent state.

  This was already implemented for idle and userspace. This patchset now
  brings it for guest contexts through the following steps:

  - Generalize the context tracking APIs to also track guest state
  - Rename/sanitize a few CPP symbols accordingly
  - Report guest entry/exit to RCU and define this context area as an RCU
    extended quiescent state."

Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents fba9e072 126a6a54
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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. */
	}

	/*
+12 −3
Original line number Diff line number Diff line
@@ -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
+6 −3
Original line number Diff line number Diff line
@@ -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
+2 −1
Original line number Diff line number Diff line
@@ -766,6 +766,7 @@ 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.
	 */
	if (!context_tracking_cpu_is_enabled())
		rcu_virt_note_context_switch(smp_processor_id());
}

Loading