From ac253f8c600db462e15686fe0a3a4c6ffa72e0f8 Mon Sep 17 00:00:00 2001 From: "Li, Fei1" Date: Wed, 25 Apr 2018 15:14:44 +0800 Subject: [PATCH] hv: timer: add periodic timer setup support and add MIN_TIMER_PERIOD_US for limit periodic timer frequency. Now it's set to 500 us. Signed-off-by: Li, Fei1 --- hypervisor/arch/x86/guest/vlapic.c | 4 ++-- hypervisor/arch/x86/timer.c | 7 +++++++ hypervisor/debug/console.c | 12 +++++------- hypervisor/include/arch/x86/timer.h | 14 +++++++++++++- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index 9843c8d27..6de19efb9 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -1576,7 +1576,7 @@ vlapic_reset(struct vlapic *vlapic) vlapic->svr_last = lapic->svr; - initialize_timer(&vlapic->timer, NULL, NULL, 0); + initialize_timer(&vlapic->timer, NULL, NULL, 0, 0, 0); } void @@ -1974,7 +1974,7 @@ vlapic_wrmsr(struct vcpu *vcpu, uint32_t msr, uint64_t val) initialize_timer(&vlapic->timer, tsc_periodic_time, (void *)vcpu, - val); + val, TICK_MODE_ONESHOT, 0); if (add_timer(&vlapic->timer) != 0) { pr_err("failed to add timer on VM %d", diff --git a/hypervisor/arch/x86/timer.c b/hypervisor/arch/x86/timer.c index 85e36c57c..36ce839eb 100644 --- a/hypervisor/arch/x86/timer.c +++ b/hypervisor/arch/x86/timer.c @@ -37,6 +37,7 @@ #define MAX_TIMER_ACTIONS 32 #define TIMER_IRQ (NR_MAX_IRQS - 1) #define CAL_MS 10 +#define MIN_TIMER_PERIOD_US 500 uint64_t tsc_hz = 1000000000; @@ -228,6 +229,12 @@ int timer_softirq(int pcpu_id) run_timer(timer); + if (timer->mode == TICK_MODE_PERIODIC) { + timer->fire_tsc += max(timer->period_in_cycle, + US_TO_TICKS(MIN_TIMER_PERIOD_US)); + add_timer(timer); + } + /* search next one */ timer = find_expired_timer(cpu_timer, rdtsc()); } diff --git a/hypervisor/debug/console.c b/hypervisor/debug/console.c index 6dce80343..1f1da71cf 100644 --- a/hypervisor/debug/console.c +++ b/hypervisor/debug/console.c @@ -221,23 +221,21 @@ static int console_timer_callback(__unused void *data) /* Kick HV-Shell and Uart-Console tasks */ console_handler(); - /* Restart the timer */ - console_setup_timer(); - return 0; } void console_setup_timer(void) { static struct timer console_timer; - uint64_t fire_tsc; + uint64_t period_in_cycle, fire_tsc; - fire_tsc = rdtsc() + CYCLES_PER_MS * CONSOLE_KICK_TIMER_TIMEOUT; + period_in_cycle = CYCLES_PER_MS * CONSOLE_KICK_TIMER_TIMEOUT; + fire_tsc = rdtsc() + period_in_cycle; initialize_timer(&console_timer, console_timer_callback, NULL, - fire_tsc); + fire_tsc, TICK_MODE_PERIODIC, period_in_cycle); - /* Start an one-shot timer */ + /* Start an periodic timer */ if (add_timer(&console_timer) != 0) pr_err("Failed to add console kick timer"); } diff --git a/hypervisor/include/arch/x86/timer.h b/hypervisor/include/arch/x86/timer.h index b74b9d58a..09582c5a0 100644 --- a/hypervisor/include/arch/x86/timer.h +++ b/hypervisor/include/arch/x86/timer.h @@ -33,9 +33,17 @@ typedef int (*timer_handle_t)(void *); +enum tick_mode { + TICK_MODE_ONESHOT = 0, + TICK_MODE_PERIODIC, +}; + + struct timer { struct list_head node; /* link all timers */ + int mode; /* timer mode: one-shot or periodic */ uint64_t fire_tsc; /* tsc deadline to interrupt */ + uint64_t period_in_cycle; /* period of the periodic timer in unit of TSC cycles */ timer_handle_t func; /* callback if time reached */ void *priv_data; /* func private data */ }; @@ -43,12 +51,16 @@ struct timer { static inline void initialize_timer(struct timer *timer, timer_handle_t func, void *priv_data, - uint64_t fire_tsc) + uint64_t fire_tsc, + int mode, + uint64_t period_in_cycle) { if (timer) { timer->func = func; timer->priv_data = priv_data; timer->fire_tsc = fire_tsc; + timer->mode = mode; + timer->period_in_cycle = period_in_cycle; } }