mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-27 23:25:11 +07:00
0c5f81dad4
Dedicated instances are currently disturbed by unnecessary jitter due to the emulated lapic timers firing on the same pCPUs where the vCPUs reside. There is no hardware virtual timer on Intel for guest like ARM, so both programming timer in guest and the emulated timer fires incur vmexits. This patch tries to avoid vmexit when the emulated timer fires, at least in dedicated instance scenario when nohz_full is enabled. In that case, the emulated timers can be offload to the nearest busy housekeeping cpus since APICv has been found for several years in server processors. The guest timer interrupt can then be injected via posted interrupts, which are delivered by the housekeeping cpu once the emulated timer fires. The host should tuned so that vCPUs are placed on isolated physical processors, and with several pCPUs surplus for busy housekeeping. If disabled mwait/hlt/pause vmexits keep the vCPUs in non-root mode, ~3% redis performance benefit can be observed on Skylake server, and the number of external interrupt vmexits drops substantially. Without patch VM-EXIT Samples Samples% Time% Min Time Max Time Avg time EXTERNAL_INTERRUPT 42916 49.43% 39.30% 0.47us 106.09us 0.71us ( +- 1.09% ) While with patch: VM-EXIT Samples Samples% Time% Min Time Max Time Avg time EXTERNAL_INTERRUPT 6871 9.29% 2.96% 0.44us 57.88us 0.72us ( +- 4.02% ) Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Radim Krčmář <rkrcmar@redhat.com> Cc: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Wanpeng Li <wanpengli@tencent.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
59 lines
1.5 KiB
C
59 lines
1.5 KiB
C
#ifndef _LINUX_SCHED_ISOLATION_H
|
|
#define _LINUX_SCHED_ISOLATION_H
|
|
|
|
#include <linux/cpumask.h>
|
|
#include <linux/init.h>
|
|
#include <linux/tick.h>
|
|
|
|
enum hk_flags {
|
|
HK_FLAG_TIMER = 1,
|
|
HK_FLAG_RCU = (1 << 1),
|
|
HK_FLAG_MISC = (1 << 2),
|
|
HK_FLAG_SCHED = (1 << 3),
|
|
HK_FLAG_TICK = (1 << 4),
|
|
HK_FLAG_DOMAIN = (1 << 5),
|
|
HK_FLAG_WQ = (1 << 6),
|
|
};
|
|
|
|
#ifdef CONFIG_CPU_ISOLATION
|
|
DECLARE_STATIC_KEY_FALSE(housekeeping_overridden);
|
|
extern int housekeeping_any_cpu(enum hk_flags flags);
|
|
extern const struct cpumask *housekeeping_cpumask(enum hk_flags flags);
|
|
extern bool housekeeping_enabled(enum hk_flags flags);
|
|
extern void housekeeping_affine(struct task_struct *t, enum hk_flags flags);
|
|
extern bool housekeeping_test_cpu(int cpu, enum hk_flags flags);
|
|
extern void __init housekeeping_init(void);
|
|
|
|
#else
|
|
|
|
static inline int housekeeping_any_cpu(enum hk_flags flags)
|
|
{
|
|
return smp_processor_id();
|
|
}
|
|
|
|
static inline const struct cpumask *housekeeping_cpumask(enum hk_flags flags)
|
|
{
|
|
return cpu_possible_mask;
|
|
}
|
|
|
|
static inline bool housekeeping_enabled(enum hk_flags flags)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline void housekeeping_affine(struct task_struct *t,
|
|
enum hk_flags flags) { }
|
|
static inline void housekeeping_init(void) { }
|
|
#endif /* CONFIG_CPU_ISOLATION */
|
|
|
|
static inline bool housekeeping_cpu(int cpu, enum hk_flags flags)
|
|
{
|
|
#ifdef CONFIG_CPU_ISOLATION
|
|
if (static_branch_unlikely(&housekeeping_overridden))
|
|
return housekeeping_test_cpu(cpu, flags);
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
#endif /* _LINUX_SCHED_ISOLATION_H */
|