1d482c497SMarcelo Tosatti /*
2d482c497SMarcelo Tosatti * qemu command line | grep latency | cut -f 2 -d ":" > latency
3d482c497SMarcelo Tosatti *
4d482c497SMarcelo Tosatti * In octave:
5d482c497SMarcelo Tosatti * load latency
66d7f1387SMarcelo Tosatti * min(latency)
76d7f1387SMarcelo Tosatti * max(latency)
86d7f1387SMarcelo Tosatti * mean(latency)
9d482c497SMarcelo Tosatti * hist(latency, 50)
10d482c497SMarcelo Tosatti */
11d482c497SMarcelo Tosatti
1224ce2536SMarcelo Tosatti /*
1324ce2536SMarcelo Tosatti * for host tracing of breakmax option:
1424ce2536SMarcelo Tosatti *
1524ce2536SMarcelo Tosatti * # cd /sys/kernel/debug/tracing/
1624ce2536SMarcelo Tosatti * # echo x86-tsc > trace_clock
1724ce2536SMarcelo Tosatti * # echo "kvm_exit kvm_entry kvm_msr" > set_event
1824ce2536SMarcelo Tosatti * # echo "sched_switch $extratracepoints" >> set_event
1924ce2536SMarcelo Tosatti * # echo apic_timer_fn > set_ftrace_filter
2024ce2536SMarcelo Tosatti * # echo "function" > current_tracer
2124ce2536SMarcelo Tosatti */
2224ce2536SMarcelo Tosatti
23d482c497SMarcelo Tosatti #include "libcflat.h"
24d482c497SMarcelo Tosatti #include "apic.h"
25d482c497SMarcelo Tosatti #include "vm.h"
26d482c497SMarcelo Tosatti #include "smp.h"
27d482c497SMarcelo Tosatti #include "desc.h"
28d482c497SMarcelo Tosatti #include "isr.h"
29d482c497SMarcelo Tosatti #include "msr.h"
30d482c497SMarcelo Tosatti
test_lapic_existence(void)31d482c497SMarcelo Tosatti static void test_lapic_existence(void)
32d482c497SMarcelo Tosatti {
33d482c497SMarcelo Tosatti u32 lvr;
34d482c497SMarcelo Tosatti
35d482c497SMarcelo Tosatti lvr = apic_read(APIC_LVR);
36d482c497SMarcelo Tosatti printf("apic version: %x\n", lvr);
37a299895bSThomas Huth report((u16)lvr == 0x14, "apic existence");
38d482c497SMarcelo Tosatti }
39d482c497SMarcelo Tosatti
40d482c497SMarcelo Tosatti #define TSC_DEADLINE_TIMER_VECTOR 0xef
41d482c497SMarcelo Tosatti
42d482c497SMarcelo Tosatti static int tdt_count;
43d482c497SMarcelo Tosatti u64 exptime;
44d482c497SMarcelo Tosatti int delta;
45d482c497SMarcelo Tosatti #define TABLE_SIZE 10000
46d482c497SMarcelo Tosatti u64 table[TABLE_SIZE];
47d482c497SMarcelo Tosatti volatile int table_idx;
4824ce2536SMarcelo Tosatti volatile int hitmax = 0;
4924ce2536SMarcelo Tosatti int breakmax = 0;
50d482c497SMarcelo Tosatti
tsc_deadline_timer_isr(isr_regs_t * regs)51d482c497SMarcelo Tosatti static void tsc_deadline_timer_isr(isr_regs_t *regs)
52d482c497SMarcelo Tosatti {
53d482c497SMarcelo Tosatti u64 now = rdtsc();
54d482c497SMarcelo Tosatti ++tdt_count;
55d482c497SMarcelo Tosatti
56d482c497SMarcelo Tosatti if (table_idx < TABLE_SIZE && tdt_count > 1)
57d482c497SMarcelo Tosatti table[table_idx++] = now - exptime;
58d482c497SMarcelo Tosatti
5924ce2536SMarcelo Tosatti if (breakmax && tdt_count > 1 && (now - exptime) > breakmax) {
6024ce2536SMarcelo Tosatti hitmax = 1;
6124ce2536SMarcelo Tosatti apic_write(APIC_EOI, 0);
6224ce2536SMarcelo Tosatti return;
6324ce2536SMarcelo Tosatti }
6424ce2536SMarcelo Tosatti
65d482c497SMarcelo Tosatti exptime = now+delta;
66d482c497SMarcelo Tosatti wrmsr(MSR_IA32_TSCDEADLINE, now+delta);
67d482c497SMarcelo Tosatti apic_write(APIC_EOI, 0);
68d482c497SMarcelo Tosatti }
69d482c497SMarcelo Tosatti
start_tsc_deadline_timer(void)70d482c497SMarcelo Tosatti static void start_tsc_deadline_timer(void)
71d482c497SMarcelo Tosatti {
72d482c497SMarcelo Tosatti handle_irq(TSC_DEADLINE_TIMER_VECTOR, tsc_deadline_timer_isr);
73*787f0aebSMaxim Levitsky sti();
74d482c497SMarcelo Tosatti
75d482c497SMarcelo Tosatti wrmsr(MSR_IA32_TSCDEADLINE, rdmsr(MSR_IA32_TSC)+delta);
76d482c497SMarcelo Tosatti asm volatile ("nop");
77d482c497SMarcelo Tosatti }
78d482c497SMarcelo Tosatti
enable_tsc_deadline_timer(void)79d482c497SMarcelo Tosatti static int enable_tsc_deadline_timer(void)
80d482c497SMarcelo Tosatti {
81d482c497SMarcelo Tosatti uint32_t lvtt;
82d482c497SMarcelo Tosatti
83badc98caSKrish Sadhukhan if (this_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) {
849111ccabSRadim Krčmář lvtt = APIC_LVT_TIMER_TSCDEADLINE | TSC_DEADLINE_TIMER_VECTOR;
85d482c497SMarcelo Tosatti apic_write(APIC_LVTT, lvtt);
86d482c497SMarcelo Tosatti start_tsc_deadline_timer();
87d482c497SMarcelo Tosatti return 1;
88d482c497SMarcelo Tosatti } else {
89d482c497SMarcelo Tosatti return 0;
90d482c497SMarcelo Tosatti }
91d482c497SMarcelo Tosatti }
92d482c497SMarcelo Tosatti
test_tsc_deadline_timer(void)93d482c497SMarcelo Tosatti static void test_tsc_deadline_timer(void)
94d482c497SMarcelo Tosatti {
95d482c497SMarcelo Tosatti if(enable_tsc_deadline_timer()) {
96d482c497SMarcelo Tosatti printf("tsc deadline timer enabled\n");
97d482c497SMarcelo Tosatti } else {
98a2b7c499SAndrew Jones printf("tsc deadline timer not detected, aborting\n");
99a2b7c499SAndrew Jones abort();
100d482c497SMarcelo Tosatti }
101d482c497SMarcelo Tosatti }
102d482c497SMarcelo Tosatti
main(int argc,char ** argv)1033dea272fSPaolo Bonzini int main(int argc, char **argv)
104d482c497SMarcelo Tosatti {
1053dea272fSPaolo Bonzini int i, size;
106d482c497SMarcelo Tosatti
107d482c497SMarcelo Tosatti setup_vm();
108d482c497SMarcelo Tosatti
109d482c497SMarcelo Tosatti test_lapic_existence();
110d482c497SMarcelo Tosatti
111d482c497SMarcelo Tosatti mask_pic_interrupts();
112d482c497SMarcelo Tosatti
1133dea272fSPaolo Bonzini delta = argc <= 1 ? 200000 : atol(argv[1]);
11424ce2536SMarcelo Tosatti size = argc <= 2 ? TABLE_SIZE : atol(argv[2]);
11524ce2536SMarcelo Tosatti breakmax = argc <= 3 ? 0 : atol(argv[3]);
11624ce2536SMarcelo Tosatti printf("breakmax=%d\n", breakmax);
117d482c497SMarcelo Tosatti test_tsc_deadline_timer();
118*787f0aebSMaxim Levitsky sti();
119d482c497SMarcelo Tosatti
1202130fd41SPeter Xu /* The condition might have triggered already, so check before HLT. */
1212130fd41SPeter Xu while (!hitmax && table_idx < size)
122d482c497SMarcelo Tosatti asm volatile("hlt");
123d482c497SMarcelo Tosatti
12424ce2536SMarcelo Tosatti for (i = 0; i < table_idx; i++) {
12524ce2536SMarcelo Tosatti if (hitmax && i == table_idx-1)
12624ce2536SMarcelo Tosatti printf("hit max: %d < ", breakmax);
127b006d7ebSAndrew Jones printf("latency: %" PRId64 "\n", table[i]);
12824ce2536SMarcelo Tosatti }
129d482c497SMarcelo Tosatti
130d482c497SMarcelo Tosatti return report_summary();
131d482c497SMarcelo Tosatti }
132