Permalink
Browse files

inmates: x86: Add SMI counter evaluation to apic-demo

This can provide hints why latencies are not as low as expected, even
without any hypervisor exits.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
  • Loading branch information...
jan-kiszka committed Aug 29, 2018
1 parent aa0e944 commit c71d79fd35e63b31fe185b841666edbab0d592f9
Showing with 45 additions and 1 deletion.
  1. +45 −1 inmates/demos/x86/apic-demo.c
@@ -12,24 +12,62 @@
#include <inmate.h>
#define MSR_SMI_COUNT 0x34
#define POLLUTE_CACHE_SIZE (512 * 1024)
#define APIC_TIMER_VECTOR 32
static unsigned long expected_time;
static unsigned long min = -1, max;
static bool has_smi_count;
static u32 initial_smis;
static const unsigned int smi_count_models[] = {
0x37, 0x4a, 0x4d, 0x5a, 0x5d, 0x5c, 0x7a, /* Silvermont */
0x1a, 0x1e, 0x1f, 0x2e, /* Nehalem */
0x2a, 0x2d, /* Sandy Bridge */
0x57, 0x85, /* Xeon Phi */
0
};
static bool cpu_has_smi_count(void)
{
unsigned int family, model, smi_count_model, n = 0;
unsigned long eax;
asm volatile("cpuid" : "=a" (eax) : "a" (1)
: "rbx", "rcx", "rdx", "memory");
family = ((eax & 0xf00) >> 8) | ((eax & 0xff00000) >> 16);
model = ((eax & 0xf0) >> 4) | ((eax & 0xf0000) >> 12);
if (family == 0x6) {
do {
smi_count_model = smi_count_models[n++];
if (model == smi_count_model)
return true;
} while (smi_count_model != 0);
}
return false;
}
static void irq_handler(void)
{
unsigned long delta;
u32 smis;
delta = tsc_read() - expected_time;
if (delta < min)
min = delta;
if (delta > max)
max = delta;
printk("Timer fired, jitter: %6ld ns, min: %6ld ns, max: %6ld ns\n",
printk("Timer fired, jitter: %6ld ns, min: %6ld ns, max: %6ld ns",
delta, min, max);
if (has_smi_count) {
smis = (u32)read_msr(MSR_SMI_COUNT);
if (smis != initial_smis)
printk(", SMIs: %d", smis - initial_smis);
}
printk("\n");
expected_time += 100 * NS_PER_MSEC;
apic_timer_set(expected_time - tsc_read());
@@ -80,6 +118,12 @@ void inmate_main(void)
printk("Cache pollution enabled\n");
}
has_smi_count = cpu_has_smi_count();
if (has_smi_count) {
initial_smis = (u32)read_msr(MSR_SMI_COUNT);
printk("Initial number of SMIs: %d\n", initial_smis);
}
tsc_freq = tsc_init();
printk("Calibrated TSC frequency: %lu.%03lu kHz\n", tsc_freq / 1000,
tsc_freq % 1000);

0 comments on commit c71d79f

Please sign in to comment.