diff options
author | Andrey Smetanin <asmetanin@virtuozzo.com> | 2015-12-28 10:27:20 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-01-08 13:04:40 -0500 |
commit | f808495da56f28e94c6448125158f1175009fcfc (patch) | |
tree | aee959706591136856acbbeb8c29c854018b3491 | |
parent | 019b9781ccd667d4160f3636c8735e3baa085555 (diff) |
kvm/x86: Hyper-V unify stimer_start() and stimer_restart()
This will be used in future to start Hyper-V SynIC timer
in several places by one logic in one function.
Changes v2:
* drop stimer->count == 0 check inside stimer_start()
* comment stimer_start() assumptions
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/hyperv.c | 43 |
1 files changed, 20 insertions, 23 deletions
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 6b2ed930bf18..0dd7d1731c22 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c | |||
@@ -408,6 +408,7 @@ static void stimer_cleanup(struct kvm_vcpu_hv_stimer *stimer) | |||
408 | clear_bit(stimer->index, | 408 | clear_bit(stimer->index, |
409 | vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap); | 409 | vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap); |
410 | stimer->msg_pending = false; | 410 | stimer->msg_pending = false; |
411 | stimer->exp_time = 0; | ||
411 | } | 412 | } |
412 | 413 | ||
413 | static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer) | 414 | static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer) |
@@ -420,24 +421,11 @@ static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer) | |||
420 | return HRTIMER_NORESTART; | 421 | return HRTIMER_NORESTART; |
421 | } | 422 | } |
422 | 423 | ||
423 | static void stimer_restart(struct kvm_vcpu_hv_stimer *stimer) | 424 | /* |
424 | { | 425 | * stimer_start() assumptions: |
425 | u64 time_now; | 426 | * a) stimer->count is not equal to 0 |
426 | ktime_t ktime_now; | 427 | * b) stimer->config has HV_STIMER_ENABLE flag |
427 | u64 remainder; | 428 | */ |
428 | |||
429 | time_now = get_time_ref_counter(stimer_to_vcpu(stimer)->kvm); | ||
430 | ktime_now = ktime_get(); | ||
431 | |||
432 | div64_u64_rem(time_now - stimer->exp_time, stimer->count, &remainder); | ||
433 | stimer->exp_time = time_now + (stimer->count - remainder); | ||
434 | |||
435 | hrtimer_start(&stimer->timer, | ||
436 | ktime_add_ns(ktime_now, | ||
437 | 100 * (stimer->exp_time - time_now)), | ||
438 | HRTIMER_MODE_ABS); | ||
439 | } | ||
440 | |||
441 | static int stimer_start(struct kvm_vcpu_hv_stimer *stimer) | 429 | static int stimer_start(struct kvm_vcpu_hv_stimer *stimer) |
442 | { | 430 | { |
443 | u64 time_now; | 431 | u64 time_now; |
@@ -447,12 +435,21 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer) | |||
447 | ktime_now = ktime_get(); | 435 | ktime_now = ktime_get(); |
448 | 436 | ||
449 | if (stimer->config & HV_STIMER_PERIODIC) { | 437 | if (stimer->config & HV_STIMER_PERIODIC) { |
450 | if (stimer->count == 0) | 438 | if (stimer->exp_time) { |
451 | return -EINVAL; | 439 | if (time_now >= stimer->exp_time) { |
440 | u64 remainder; | ||
441 | |||
442 | div64_u64_rem(time_now - stimer->exp_time, | ||
443 | stimer->count, &remainder); | ||
444 | stimer->exp_time = | ||
445 | time_now + (stimer->count - remainder); | ||
446 | } | ||
447 | } else | ||
448 | stimer->exp_time = time_now + stimer->count; | ||
452 | 449 | ||
453 | stimer->exp_time = time_now + stimer->count; | ||
454 | hrtimer_start(&stimer->timer, | 450 | hrtimer_start(&stimer->timer, |
455 | ktime_add_ns(ktime_now, 100 * stimer->count), | 451 | ktime_add_ns(ktime_now, |
452 | 100 * (stimer->exp_time - time_now)), | ||
456 | HRTIMER_MODE_ABS); | 453 | HRTIMER_MODE_ABS); |
457 | return 0; | 454 | return 0; |
458 | } | 455 | } |
@@ -580,7 +577,7 @@ static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer) | |||
580 | if (!(stimer->config & HV_STIMER_PERIODIC)) | 577 | if (!(stimer->config & HV_STIMER_PERIODIC)) |
581 | stimer->config &= ~HV_STIMER_ENABLE; | 578 | stimer->config &= ~HV_STIMER_ENABLE; |
582 | else | 579 | else |
583 | stimer_restart(stimer); | 580 | stimer_start(stimer); |
584 | } | 581 | } |
585 | 582 | ||
586 | void kvm_hv_process_stimers(struct kvm_vcpu *vcpu) | 583 | void kvm_hv_process_stimers(struct kvm_vcpu *vcpu) |