Skip to content

Commit

Permalink
Use hrtimers for the decrementer
Browse files Browse the repository at this point in the history
Following S390's good example we should use hrtimers for the decrementer too!
This patch converts the timer from the old mechanism to hrtimers.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Alexander Graf authored and Benjamin Herrenschmidt committed Nov 5, 2009
1 parent c8240bd commit 544c676
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 11 deletions.
6 changes: 4 additions & 2 deletions arch/powerpc/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
#define __POWERPC_KVM_HOST_H__

#include <linux/mutex.h>
#include <linux/timer.h>
#include <linux/hrtimer.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/kvm_types.h>
#include <asm/kvm_asm.h>
Expand Down Expand Up @@ -250,7 +251,8 @@ struct kvm_vcpu_arch {

u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */

struct timer_list dec_timer;
struct hrtimer dec_timer;
struct tasklet_struct tasklet;
u64 dec_jiffies;
unsigned long pending_exceptions;

Expand Down
18 changes: 11 additions & 7 deletions arch/powerpc/kvm/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

#include <linux/jiffies.h>
#include <linux/timer.h>
#include <linux/hrtimer.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kvm_host.h>
Expand Down Expand Up @@ -79,12 +79,13 @@ static int kvmppc_dec_enabled(struct kvm_vcpu *vcpu)

void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
{
unsigned long nr_jiffies;
unsigned long dec_nsec;

pr_debug("mtDEC: %x\n", vcpu->arch.dec);
#ifdef CONFIG_PPC64
/* POWER4+ triggers a dec interrupt if the value is < 0 */
if (vcpu->arch.dec & 0x80000000) {
del_timer(&vcpu->arch.dec_timer);
hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
kvmppc_core_queue_dec(vcpu);
return;
}
Expand All @@ -94,12 +95,15 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
* that's how we convert the guest DEC value to the number of
* host ticks. */

hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
dec_nsec = vcpu->arch.dec;
dec_nsec *= 1000;
dec_nsec /= tb_ticks_per_usec;
hrtimer_start(&vcpu->arch.dec_timer, ktime_set(0, dec_nsec),
HRTIMER_MODE_REL);
vcpu->arch.dec_jiffies = get_tb();
nr_jiffies = vcpu->arch.dec / tb_ticks_per_jiffy;
mod_timer(&vcpu->arch.dec_timer,
get_jiffies_64() + nr_jiffies);
} else {
del_timer(&vcpu->arch.dec_timer);
hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
}
}

Expand Down
20 changes: 18 additions & 2 deletions arch/powerpc/kvm/powerpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <linux/kvm_host.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/hrtimer.h>
#include <linux/fs.h>
#include <asm/cputable.h>
#include <asm/uaccess.h>
Expand Down Expand Up @@ -208,10 +209,25 @@ static void kvmppc_decrementer_func(unsigned long data)
}
}

/*
* low level hrtimer wake routine. Because this runs in hardirq context
* we schedule a tasklet to do the real work.
*/
enum hrtimer_restart kvmppc_decrementer_wakeup(struct hrtimer *timer)
{
struct kvm_vcpu *vcpu;

vcpu = container_of(timer, struct kvm_vcpu, arch.dec_timer);
tasklet_schedule(&vcpu->arch.tasklet);

return HRTIMER_NORESTART;
}

int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
{
setup_timer(&vcpu->arch.dec_timer, kvmppc_decrementer_func,
(unsigned long)vcpu);
hrtimer_init(&vcpu->arch.dec_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu);
vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup;

return 0;
}
Expand Down

0 comments on commit 544c676

Please sign in to comment.