Skip to contentSkip to conversation

Modify KVM to update guest time accounting.

PATCH RESEND In review Laurent Vivier 5 participants 33 messages Sep 10, 2007 – Oct 22, 2007 KVM

lore
Share & tools
lore
#0 lore raw

PATCH RESEND 4/4 Modify KVM to update guest time accounting.

[PATCH 4/4] Modify KVM to update guest time accounting.

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth
drivers/kvm/kvm.h +13 -0
Index: linux-2.6/drivers/kvm/kvm.h
===================================================================
@@ -625,6 +625,19 @@ void kvm_mmu_unload(struct kvm_vcpu *vcp
 
 int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
+#ifndef PF_VCPU
+#define PF_VCPU	0
+#endif
+
+static inline void kvm_guest_enter(void)
+{
+	current->flags |= PF_VCPU;
+}
+
+static inline void kvm_guest_exit(void)
+{
+}
+
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
 				     u32 error_code)
 {
drivers/kvm/svm.c +2 -0
Index: linux-2.6/drivers/kvm/svm.c
===================================================================
@@ -1494,6 +1494,7 @@ again:
 	clgi();
 
 	vcpu->guest_mode = 1;
+	kvm_guest_enter();
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    svm_flush_tlb(vcpu);
@@ -1629,6 +1630,7 @@ again:
 #endif
 		: "cc", "memory" );
 
+	kvm_guest_exit();
 	vcpu->guest_mode = 0;
 
 	if (vcpu->fpu_active) {
drivers/kvm/vmx.c +2 -0
Index: linux-2.6/drivers/kvm/vmx.c
===================================================================
@@ -2018,6 +2018,7 @@ again:
 	local_irq_disable();
 
 	vcpu->guest_mode = 1;
+	kvm_guest_enter();
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    vmx_flush_tlb(vcpu);
@@ -2138,6 +2139,7 @@ again:
 		[cr2]"i"(offsetof(struct kvm_vcpu, cr2))
 	      : "cc", "memory" );
 
+	kvm_guest_exit();
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 
Acked-by Avi Kivity on v1 4/4
#1 lore raw
Quoted 1 line · Laurent Vivier

[PATCH 4/4] Modify KVM to update guest time accounting.

FYI, KVM abstracted its guest-mode entry code recently so this did not apply - find below the reworked patch.

Ingo

------------------->
Subject: sched: guest CPU accounting: maintain guest state in KVM
From: Laurent Vivier <[email protected]>

Modify KVM to update guest time accounting.

[ [email protected]: ported to 2.6.24 KVM. ]

---
 drivers/kvm/kvm.h      |   16 ++++++++++++++++
 drivers/kvm/kvm_main.c |    2 ++
 2 files changed, 18 insertions(+)
drivers/kvm/kvm.h +16 -0
Index: linux/drivers/kvm/kvm.h
===================================================================
@@ -624,6 +624,22 @@ void kvm_mmu_unload(struct kvm_vcpu *vcp
 
 int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
+/*
+ * Compatibility define - PF_VCPU is only available in v2.6.24+ kernels:
+ */
+#ifndef PF_VCPU
+# define PF_VCPU	0
+#endif
+
+static inline void kvm_guest_enter(void)
+{
+	current->flags |= PF_VCPU;
+}
+
+static inline void kvm_guest_exit(void)
+{
+}
+
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
 				     u32 error_code)
 {
drivers/kvm/kvm_main.c +2 -0
Index: linux/drivers/kvm/kvm_main.c
===================================================================
@@ -2046,6 +2046,7 @@ again:
 		kvm_x86_ops->inject_pending_vectors(vcpu, kvm_run);
 
 	vcpu->guest_mode = 1;
+	kvm_guest_enter();
 
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
@@ -2053,6 +2054,7 @@ again:
 
 	kvm_x86_ops->run(vcpu, kvm_run);
 
+	kvm_guest_exit();
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 
#2 lore raw

drivers/kvm/kvm.h void kvm_mmu_unload(struct kvm_vcpu *vcp · line 633

Quoted 10 lines · Ingo Molnar

int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);

drivers/kvm/kvm.h +7 -0
+/*
+ * Compatibility define - PF_VCPU is only available in v2.6.24+ kernels:
+ */
+#ifndef PF_VCPU
+# define PF_VCPU	0
+#endif
+

This bit can go; for the external module I can add it back in external-module-compat.h. No need to pollute mainline with backward compatibility stuff.

Signature · 1 line
error compiling committee.c: too many arguments to function
#3 lore raw
Quoted 15 lines · Avi Kivity

drivers/kvm/kvm.h void kvm_mmu_unload(struct kvm_vcpu *vcp · line 633

Quoted 10 lines · Ingo Molnar

int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);

drivers/kvm/kvm.h +7 -0
+/*
+ * Compatibility define - PF_VCPU is only available in v2.6.24+ kernels:
+ */
+#ifndef PF_VCPU
+# define PF_VCPU	0
+#endif
+

This bit can go; for the external module I can add it back in external-module-compat.h. No need to pollute mainline with backward compatibility stuff.

thx - zapped.

Ingo

#4 lore raw
In reply to Avi Kivity
Quoted 3 lines · Avi Kivity

This bit can go; for the external module I can add it back in external-module-compat.h. No need to pollute mainline with backward compatibility stuff.

hm:

static inline void kvm_guest_enter(void)

{
        current->flags |= PF_VCPU;
}

static inline void kvm_guest_exit(void)
{
}

shouldnt PF_VCPU be cleared in kvm_guest_exit()?

Ingo

#5 lore raw
Quoted 13 lines · Ingo Molnar
Quoted 2 lines · Avi Kivity

This bit can go; for the external module I can add it back in external-module-compat.h. No need to pollute mainline with backward compatibility stuff.

hm:

static inline void kvm_guest_enter(void)

{
        current->flags |= PF_VCPU;
}
Quoted 6 lines

static inline void kvm_guest_exit(void)
{
}

shouldnt PF_VCPU be cleared in kvm_guest_exit()?

IIRC the accounting code clears it, but yes, it may not have been called at all, so clearing it here is needed.

Signature · 1 line
error compiling committee.c: too many arguments to function
#6 lore raw
Quoted 20 lines · Avi Kivity
Quoted 19 lines · Ingo Molnar
Quoted 4 lines · Avi Kivity

This bit can go; for the external module I can add it back in external-module-compat.h. No need to pollute mainline with backward compatibility stuff.

hm:

static inline void kvm_guest_enter(void)

{
        current->flags |= PF_VCPU;
}

static inline void kvm_guest_exit(void)
{
}

Quoted 6 lines
Quoted 2 lines

shouldnt PF_VCPU be cleared in kvm_guest_exit()?

IIRC the accounting code clears it, but yes, it may not have been called at all, so clearing it here is needed.

No, It must not be cleared here because we can't enter in the accounting code between kvm_guest_enter(void) and kvm_guest_exit(void).

This is why the accounting code clears it.

I put a kvm_guest_exit() only for symmetry.

Laurent

Signature · 2 lines
---------------- [email protected]  -----------------
"Given enough eyeballs, all bugs are shallow" E. S. Raymond
#7 lore raw
Quoted 27 lines · Laurent Vivier
Quoted 25 lines · Avi Kivity
Quoted 23 lines · Ingo Molnar
Quoted 5 lines · Avi Kivity

This bit can go; for the external module I can add it back in external-module-compat.h. No need to pollute mainline with backward compatibility stuff.

hm:

static inline void kvm_guest_enter(void)

{
        current->flags |= PF_VCPU;
}

static inline void kvm_guest_exit(void)
{
}

shouldnt PF_VCPU be cleared in kvm_guest_exit()?

Quoted 9 lines
Quoted 4 lines

IIRC the accounting code clears it, but yes, it may not have been called at all, so clearing it here is needed.

No, It must not be cleared here because we can't enter in the accounting code between kvm_guest_enter(void) and kvm_guest_exit(void).

Right.

Quoted 2 lines

This is why the accounting code clears it.

But if we didn't get an interrupt in that time?

We can clear it a bit later, after local_irq_enable() in __vcpu_run(). However we need a nop instruction first because "sti" keeps interrupts disabled for one more instruction.

Signature · 1 line
error compiling committee.c: too many arguments to function
#8 lore raw

Am Montag, 15. Oktober 2007 schrieb Avi Kivity:

Quoted 3 lines

We can clear it a bit later, after local_irq_enable() in __vcpu_run(). However we need a nop instruction first because "sti" keeps interrupts disabled for one more instruction.

Ah, I see. The host interrupt behaves different and instead of running the interrupt handler, it exits the vmrun on x86? The interrupt handler will be called some cycles after the sti?
That is different to s390. We can run the guest code for a long time and the host instruction pointer stays on the sie instruction. That means, we can interrupt sie and continue by simply setting the instrution pointer (PSW) back to the sie instruction.

Any idea how to make this proper on all architectures? I will have a look.

Christian

#9 lore raw
Quoted 13 lines · Christian Borntraeger

Am Montag, 15. Oktober 2007 schrieb Avi Kivity:

Quoted 3 lines

We can clear it a bit later, after local_irq_enable() in __vcpu_run(). However we need a nop instruction first because "sti" keeps interrupts disabled for one more instruction.

Ah, I see. The host interrupt behaves different and instead of running the interrupt handler, it exits the vmrun on x86? The interrupt handler will be called some cycles after the sti?
That is different to s390. We can run the guest code for a long time and the host instruction pointer stays on the sie instruction. That means, we can interrupt sie and continue by simply setting the instrution pointer (PSW) back to the sie instruction.

Quoted 1 line

Any idea how to make this proper on all architectures? I will have a look.

I think the solution is to have an arch dependent kvm_guest_exit(): empty for x86, clearing the bit for s390.

Regards,
Laurent

Signature · 2 lines
---------------- [email protected]  -----------------
"Given enough eyeballs, all bugs are shallow" E. S. Raymond
#10 lore raw

Am Montag, 15. Oktober 2007 schrieb Laurent Vivier:

Quoted 4 lines
Quoted 1 line

Any idea how to make this proper on all architectures? I will have a look.

I think the solution is to have an arch dependent kvm_guest_exit(): empty for x86, clearing the bit for s390.

I think we can merge your patches, as the userspace interface seems fine. To make the accounting work for virtual cpu accounting found on ppc and s390 we can later add an additional patch that also deals with interruptible guest contexts.
So something like this should work:

---
 drivers/kvm/kvm.h |    8 ++++++++
 kernel/sched.c    |    2 ++
 2 files changed, 10 insertions(+)
drivers/kvm/kvm.h +8 -0
Index: kvm/drivers/kvm/kvm.h
===================================================================
@@ -18,6 +18,7 @@
 
 #include <linux/kvm.h>
 #include <linux/kvm_para.h>
+#include <asm/system.h>
 
 #define CR3_PAE_RESERVED_BITS ((X86_CR3_PWT | X86_CR3_PCD) - 1)
 #define CR3_NONPAE_RESERVED_BITS ((PAGE_SIZE-1) & ~(X86_CR3_PWT | X86_CR3_PCD))
@@ -675,11 +676,18 @@ __init void kvm_arch_init(void);
 
 static inline void kvm_guest_enter(void)
 {
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	account_system_vtime(current);
+#endif
 	current->flags |= PF_VCPU;
 }
 
 static inline void kvm_guest_exit(void)
 {
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	account_system_vtime(current);
+	current->flags &= ~PF_VCPU;
+#endif
 }
 
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
kernel/sched.c +2 -0
Index: kvm/kernel/sched.c
===================================================================
@@ -3312,7 +3312,9 @@ void account_system_time(struct task_str
 
 	if (p->flags & PF_VCPU) {
 		account_guest_time(p, cputime);
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
 		p->flags &= ~PF_VCPU;
+#endif
 		return;
 	}
 
#11 lore raw
Quoted 5 lines · Christian Borntraeger

Am Montag, 15. Oktober 2007 schrieb Laurent Vivier:

Quoted 3 lines
Quoted 1 line

Any idea how to make this proper on all architectures? I will have a look.

I think the solution is to have an arch dependent kvm_guest_exit(): empty for x86, clearing the bit for s390.

Quoted 8 lines

I think we can merge your patches, as the userspace interface seems fine. To make the accounting work for virtual cpu accounting found on ppc and s390 we can later add an additional patch that also deals with interruptible guest contexts.
So something like this should work:

It's fine for me.

Laurent

Signature · 2 lines
---------------- [email protected]  -----------------
"Given enough eyeballs, all bugs are shallow" E. S. Raymond
#12 lore raw
In reply to Avi Kivity
Quoted 39 lines · Avi Kivity
Quoted 25 lines · Laurent Vivier
Quoted 23 lines · Avi Kivity
Quoted 21 lines · Ingo Molnar
Quoted 4 lines · Avi Kivity

This bit can go; for the external module I can add it back in external-module-compat.h. No need to pollute mainline with backward compatibility stuff.

hm:

static inline void kvm_guest_enter(void)

{
        current->flags |= PF_VCPU;
}

static inline void kvm_guest_exit(void)
{
}

shouldnt PF_VCPU be cleared in kvm_guest_exit()?

Quoted 10 lines
Quoted 4 lines

IIRC the accounting code clears it, but yes, it may not have been called at all, so clearing it here is needed.

No, It must not be cleared here because we can't enter in the accounting code
between kvm_guest_enter(void) and kvm_guest_exit(void).

Right.

Quoted 8 lines
Quoted 2 lines

This is why the accounting code clears it.

But if we didn't get an interrupt in that time?

We can clear it a bit later, after local_irq_enable() in __vcpu_run(). However we need a nop instruction first because "sti" keeps interrupts disabled for one more instruction.

IMHO, I think it is better to let kvm_guest_exit() empty (you can remove it, if you want):

1st case:
- unset PF_VCPU in kvm_guest_exit(), all the tick is always for system time. Guest time is always 0.

1st case and half:

- like 1st case but we move kvm_guest_exit() as you propose and the reason of the interrupt is the tick interrupt. The tick is for guest time only. I think the probability is very low.

2nd case:
- don't unset PF_VCPU in kvm_guest_exit(), all the tick is for guest time.

I proposed a patch allowing to be more accurate, but it introduces more complexity and system and user time accounting are not very accurate too (the tick if for system if it appears whereas we are in system, for user if it appears whereas we are in user).

Laurent

Signature · 2 lines
---------------- [email protected]  -----------------
"Given enough eyeballs, all bugs are shallow" E. S. Raymond
#13 lore raw
Quoted 13 lines · Laurent Vivier
Quoted 5 lines

But if we didn't get an interrupt in that time?

We can clear it a bit later, after local_irq_enable() in __vcpu_run(). However we need a nop instruction first because "sti" keeps interrupts disabled for one more instruction.

IMHO, I think it is better to let kvm_guest_exit() empty (you can remove it, if you want):

1st case:
- unset PF_VCPU in kvm_guest_exit(), all the tick is always for system time. Guest time is always 0.

Quoted 6 lines

1st case and half:

- like 1st case but we move kvm_guest_exit() as you propose and the reason of the interrupt is the tick interrupt. The tick is for guest time only. I think the probability is very low.

If the guest is executing for 10% of the time, the probability is exactly 10%, no?

Quoted 3 lines

2nd case:
- don't unset PF_VCPU in kvm_guest_exit(), all the tick is for guest time.

But then even execution in ->handle_exit() is accounted as guest time, which is wrong.

Signature · 1 line
error compiling committee.c: too many arguments to function
#14 lore raw
Quoted 30 lines · Avi Kivity
Quoted 17 lines · Laurent Vivier
Quoted 7 lines

But if we didn't get an interrupt in that time?

We can clear it a bit later, after local_irq_enable() in __vcpu_run(). However we need a nop instruction first because "sti" keeps interrupts
disabled for one more instruction.

IMHO, I think it is better to let kvm_guest_exit() empty (you can remove it, if
you want):

1st case:
- unset PF_VCPU in kvm_guest_exit(), all the tick is always for system time.
Guest time is always 0.

Quoted 8 lines

1st case and half:

- like 1st case but we move kvm_guest_exit() as you propose and the reason of
the interrupt is the tick interrupt. The tick is for guest time only. I think
the probability is very low.

Quoted 2 lines

If the guest is executing for 10% of the time, the probability is exactly 10%, no?

I think you know that better than me.

But is there homogeneity in probability ?

I mean, if the guest has a lot I/O, it is interrupted by them and the probability to be interrupted by a tick is lower than the time passed in the VCPU ?

Quoted 7 lines
Quoted 4 lines

2nd case:
- don't unset PF_VCPU in kvm_guest_exit(), all the tick is for guest time.

But then even execution in ->handle_exit() is accounted as guest time, which is wrong.

System time and User time are wrong too as the tick is accounted to the side where it appears, even if CPU has executed code from the other side in a sub-part of the tick. It's not a good argument.

Laurent

Signature · 2 lines
---------------- [email protected]  -----------------
"Given enough eyeballs, all bugs are shallow" E. S. Raymond
#15 lore raw
Quoted 33 lines · Laurent Vivier
Quoted 31 lines · Avi Kivity
Quoted 26 lines · Laurent Vivier
Quoted 8 lines

But if we didn't get an interrupt in that time?

We can clear it a bit later, after local_irq_enable() in __vcpu_run(). However we need a nop instruction first because "sti" keeps interrupts
disabled for one more instruction.

IMHO, I think it is better to let kvm_guest_exit() empty (you can remove it, if
you want):

1st case:
- unset PF_VCPU in kvm_guest_exit(), all the tick is always for system time.
Guest time is always 0.

1st case and half:

- like 1st case but we move kvm_guest_exit() as you propose and the reason of
the interrupt is the tick interrupt. The tick is for guest time only. I think
the probability is very low.

Quoted 8 lines
Quoted 3 lines

If the guest is executing for 10% of the time, the probability is exactly 10%, no?

I think you know that better than me.

But is there homogeneity in probability ?

It's exactly the same issue as with systime and usertime. The interrupt samples the program counter at various points at a fairly low frequency (milliseconds) while syscalls last a few dozens of microseconds. Probability makes it average out correctly in the end.

[Ingo, what about dyntick? suppose you have just one process that calls read() from /dev/zero repeatedly. There'd be very few (or no) interrupts -- what happens to accounting accuracy?]

Quoted 3 lines

I mean, if the guest has a lot I/O, it is interrupted by them and the probability to be interrupted by a tick is lower than the time passed in the VCPU ?

Suppose the time to service the I/O is exactly equal to the amount running in guest mode. Then the probability of the interrupt happening in guest mode is equal to it happening outside guest mode and you'd get 50% guest, 50% system/user, which is what you want.

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

2nd case:
- don't unset PF_VCPU in kvm_guest_exit(), all the tick is for guest time.

Quoted 8 lines
Quoted 3 lines

But then even execution in ->handle_exit() is accounted as guest time, which is wrong.

System time and User time are wrong too as the tick is accounted to the side where it appears, even if CPU has executed code from the other side in a sub-part of the tick. It's not a good argument.

It's at least consistent... the same errors for everyone, so it averages out in the end.

Signature · 1 line
error compiling committee.c: too many arguments to function
#16 lore raw

No more comments: I agree.

We can move the "&= ~PF_VCPU" to kvm_guest_exit() and remove it from account_system_time(). Moreover it will simplify the code for s390...

Regards,
Laurent

Quoted 68 lines · Avi Kivity
Quoted 31 lines · Laurent Vivier
Quoted 29 lines · Avi Kivity
Quoted 24 lines · Laurent Vivier
Quoted 7 lines

But if we didn't get an interrupt in that time?

We can clear it a bit later, after local_irq_enable() in __vcpu_run(). However we need a nop instruction first because "sti" keeps interrupts
disabled for one more instruction.

IMHO, I think it is better to let kvm_guest_exit() empty (you can remove it, if
you want):

1st case:
- unset PF_VCPU in kvm_guest_exit(), all the tick is always for system time.
Guest time is always 0.

1st case and half:

- like 1st case but we move kvm_guest_exit() as you propose and the reason of
the interrupt is the tick interrupt. The tick is for guest time only. I think
the probability is very low.

Quoted 8 lines
Quoted 3 lines

If the guest is executing for 10% of the time, the probability is exactly 10%, no?

I think you know that better than me.

But is there homogeneity in probability ?

It's exactly the same issue as with systime and usertime. The interrupt samples the program counter at various points at a fairly low frequency (milliseconds) while syscalls last a few dozens of microseconds. Probability makes it average out correctly in the end.

[Ingo, what about dyntick? suppose you have just one process that calls read() from /dev/zero repeatedly. There'd be very few (or no) interrupts -- what happens to accounting accuracy?]

Quoted 3 lines

I mean, if the guest has a lot I/O, it is interrupted by them and the probability to be interrupted by a tick is lower than the time passed in the VCPU ?

Suppose the time to service the I/O is exactly equal to the amount running in guest mode. Then the probability of the interrupt happening in guest mode is equal to it happening outside guest mode and you'd get 50% guest, 50% system/user, which is what you want.

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

2nd case:
- don't unset PF_VCPU in kvm_guest_exit(), all the tick is for guest time.

Quoted 8 lines
Quoted 3 lines

But then even execution in ->handle_exit() is accounted as guest time, which is wrong.

System time and User time are wrong too as the tick is accounted to the side where it appears, even if CPU has executed code from the other side in a sub-part of the tick. It's not a good argument.

It's at least consistent... the same errors for everyone, so it averages out in the end.

#17 lore raw

PATCH 1/1 clear PF_VCPU in kvm_guest_exit()

In reply to Laurent Vivier

clear PF_VCPU in kvm_guest_exit() and move kvm_guest_exit() after local_irq_enable().

According comments from Avi, we can clear PF_VCPU in kvm_guest_exit if we move it after local_irq_enable().

http://lkml.org/lkml/2007/10/15/114

To simplify s390 port, we don't clear it in account_system_time().

http://lkml.org/lkml/2007/10/15/183

---
 drivers/kvm/kvm.h      |    1 +
 drivers/kvm/kvm_main.c |    3 ++-
 kernel/sched.c         |    1 -
 3 files changed, 3 insertions(+), 2 deletions(-)
drivers/kvm/kvm.h +1 -0
index e9dbf67..e8b4902 100644
@@ -677,6 +677,7 @@ static inline void kvm_guest_enter(void)
 
 static inline void kvm_guest_exit(void)
 {
+	current->flags &= ~PF_VCPU;
 }
 
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
drivers/kvm/kvm_main.c +2 -1
index 87275be..a9db477 100644
@@ -2194,12 +2194,13 @@ again:
 
 	kvm_x86_ops->run(vcpu, kvm_run);
 
-	kvm_guest_exit();
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 
 	++vcpu->stat.exits;
 
+	kvm_guest_exit();
+
 	preempt_enable();
 
 	/*
kernel/sched.c +0 -1
index b27ab3e..57fac22 100644
@@ -3315,7 +3315,6 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
 #ifdef CONFIG_GUEST_ACCOUNTING
 	if (p->flags & PF_VCPU) {
 		account_guest_time(p, cputime);
-		p->flags &= ~PF_VCPU;
 		return;
 	}
 #endif
Signature · 1 line
1.5.2.4
Acked-by on v1 1/1
#18 lore raw

Re: [PATCH] clear PF_VCPU in kvm_guest_exit()

Am Mittwoch, 17. Oktober 2007 schrieb Laurent Vivier:

Quoted 2 lines

clear PF_VCPU in kvm_guest_exit() and move kvm_guest_exit() after local_irq_enable().

Looks good. In the next days I will sent a patch for precise guest time accounting with CONFIG_VIRT_CPU_ACCOUNTING on top of this patch.

#19 lore raw

Re: [PATCH] clear PF_VCPU in kvm_guest_exit()

In reply to Laurent Vivier
Quoted 24 lines · Laurent Vivier

clear PF_VCPU in kvm_guest_exit() and move kvm_guest_exit() after local_irq_enable().

According comments from Avi, we can clear PF_VCPU in kvm_guest_exit if we move it after local_irq_enable().

http://lkml.org/lkml/2007/10/15/114

To simplify s390 port, we don't clear it in account_system_time().

http://lkml.org/lkml/2007/10/15/183

---
 drivers/kvm/kvm.h      |    1 +
 drivers/kvm/kvm_main.c |    3 ++-
 kernel/sched.c         |    1 -
 3 files changed, 3 insertions(+), 2 deletions(-)
drivers/kvm/kvm.h +0 -0
index e9dbf67..e8b4902 100644

drivers/kvm/kvm.h static inline void kvm_guest_enter(void) · line 682

Quoted 6 lines
drivers/kvm/kvm.h +1 -0
@@ -677,6 +677,7 @@ static inline void kvm_guest_enter(void)
 
 static inline void kvm_guest_exit(void)
 {
+	current->flags &= ~PF_VCPU;
 }
 

Ingo already added this.

Quoted 7 lines
drivers/kvm/kvm.h +0 -0
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
drivers/kvm/kvm_main.c +0 -0
index 87275be..a9db477 100644

drivers/kvm/kvm_main.c again: · line 2202

Quoted 10 lines
drivers/kvm/kvm_main.c +0 -1
@@ -2194,12 +2194,13 @@ again:
 
 	kvm_x86_ops->run(vcpu, kvm_run);
 
-	kvm_guest_exit();
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 
 	++vcpu->stat.exits;
 
 

Need a barrier() here. Otherwise the compiler may reorder "kvm_guest_exit();" and "++vcpu->stats.exits;", making kvm_guest_exit() right after local_irq_enable(). If it inlines kvm_guest_exit(), and further encodes it in one instruction (both likely) we get:

sti
andl $something, (something_else)

The andl executes in interrupt shadow (that is, interrupts are still disabled) and the timer tick won't see PF_VCPU.

Quoted 6 lines
drivers/kvm/kvm_main.c +2 -0
+	kvm_guest_exit();
+
 	preempt_enable();
 

/*

Please copy kvm-devel on kvm patches.

Signature · 1 line
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
#20 lore raw

Re: [PATCH] clear PF_VCPU in kvm_guest_exit()

Quoted 58 lines · Avi Kivity
Quoted 24 lines · Laurent Vivier

clear PF_VCPU in kvm_guest_exit() and move kvm_guest_exit() after local_irq_enable().

According comments from Avi, we can clear PF_VCPU in kvm_guest_exit if we move it after local_irq_enable().

http://lkml.org/lkml/2007/10/15/114

To simplify s390 port, we don't clear it in account_system_time().

http://lkml.org/lkml/2007/10/15/183

---
 drivers/kvm/kvm.h      |    1 +
 drivers/kvm/kvm_main.c |    3 ++-
 kernel/sched.c         |    1 -
 3 files changed, 3 insertions(+), 2 deletions(-)
drivers/kvm/kvm.h +0 -0
index e9dbf67..e8b4902 100644

drivers/kvm/kvm.h static inline void kvm_guest_enter(void) · line 682

Quoted 6 lines
drivers/kvm/kvm.h +1 -0
@@ -677,6 +677,7 @@ static inline void kvm_guest_enter(void)
 
 static inline void kvm_guest_exit(void)
 {
+	current->flags &= ~PF_VCPU;
 }
 

Ingo already added this.

Quoted 7 lines
drivers/kvm/kvm.h +0 -0
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
drivers/kvm/kvm_main.c +0 -0
index 87275be..a9db477 100644

drivers/kvm/kvm_main.c again: · line 2202

Quoted 10 lines
drivers/kvm/kvm_main.c +0 -1
@@ -2194,12 +2194,13 @@ again:
 
 	kvm_x86_ops->run(vcpu, kvm_run);
 
-	kvm_guest_exit();
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 
 	++vcpu->stat.exits;
 
 

Need a barrier() here. Otherwise the compiler may reorder "kvm_guest_exit();" and "++vcpu->stats.exits;", making kvm_guest_exit() right after local_irq_enable(). If it inlines kvm_guest_exit(), and further encodes it in one instruction (both likely) we get:

Quoted 2 lines

sti
andl $something, (something_else)

For the moment it is:

    5676:       fb                      sti
    5677:       48 8b 85 f8 fe ff ff    mov    0xfffffffffffffef8(%rbp),%rax
    567e:       8b 80 10 0c 00 00       mov    0xc10(%rax),%eax
    5684:       8d 50 01                lea    0x1(%rax),%edx
    5687:       48 8b 85 f8 fe ff ff    mov    0xfffffffffffffef8(%rbp),%rax
    568e:       89 90 10 0c 00 00       mov    %edx,0xc10(%rax)
    5694:       65 48 8b 04 25 00 00    mov    %gs:0x0,%rax
    569b:       00 00
    569d:       48 89 45 a8             mov    %rax,0xffffffffffffffa8(%rbp)
    56a1:       48 8b 45 a8             mov    0xffffffffffffffa8(%rbp),%rax
    56a5:       48 89 45 b0             mov    %rax,0xffffffffffffffb0(%rbp)
    56a9:       48 8b 45 b0             mov    0xffffffffffffffb0(%rbp),%rax
    56ad:       48 89 c2                mov    %rax,%rdx
    56b0:       8b 42 14                mov    0x14(%rdx),%eax
    56b3:       83 e0 ef                and    $0xffffffffffffffef,%eax
    56b6:       89 42 14                mov    %eax,0x14(%rdx)

So I think it is out of the interrupt shadow... but you're right I will resend the patch adding barrier() (because in futur gcc can behave differently), removing the part already added by Ingo and copying kvm-devel.

Quoted 7 lines

The andl executes in interrupt shadow (that is, interrupts are still disabled) and the timer tick won't see PF_VCPU.

Quoted 4 lines
drivers/kvm/kvm_main.c +2 -0
+	kvm_guest_exit();
+
 	preempt_enable();
 
Quoted 6 lines
Quoted 2 lines

/*

Please copy kvm-devel on kvm patches.

Laurent

Signature · 2 lines
---------------- [email protected]  -----------------
"Given enough eyeballs, all bugs are shallow" E. S. Raymond
#21 lore raw

Use virtual cpu accounting if available for guest times.

In reply to Laurent Vivier

Avi,

ppc and s390 offer the possibility to track process times precisely by looking at cpu timer on every context switch, irq, softirq etc. We can use that infrastructure as well for guest time accounting. We need to account the used time before we change the state. This patch adds a call to account_system_vtime to kvm_guest_enter and kvm_guest exit. If CONFIG_VIRT_CPU_ACCOUNTING is not set, account_system_vtime is defined in hardirq.h as an empty function, which means this patch does not change the behaviour on other platforms.

I compile tested this patch on x86 and function tested the patch on s390.

Avi, please apply.

---
 drivers/kvm/kvm.h |    3 +++
 1 file changed, 3 insertions(+)
drivers/kvm/kvm.h +3 -0
Index: kvm/drivers/kvm/kvm.h
===================================================================
@@ -7,6 +7,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/hardirq.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
@@ -669,11 +670,13 @@ __init void kvm_arch_init(void);
 
 static inline void kvm_guest_enter(void)
 {
+	account_system_vtime(current);
 	current->flags |= PF_VCPU;
 }
 
 static inline void kvm_guest_exit(void)
 {
+	account_system_vtime(current);
 	current->flags &= ~PF_VCPU;
 }
 

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

#22 lore raw

Re: Use virtual cpu accounting if available for guest times.

Quoted 10 lines · Christian Borntraeger

ppc and s390 offer the possibility to track process times precisely by looking at cpu timer on every context switch, irq, softirq etc. We can use that infrastructure as well for guest time accounting. We need to account the used time before we change the state. This patch adds a call to account_system_vtime to kvm_guest_enter and kvm_guest exit. If CONFIG_VIRT_CPU_ACCOUNTING is not set, account_system_vtime is defined in hardirq.h as an empty function, which means this patch does not change the behaviour on other platforms.

Quoted 6 lines

I compile tested this patch on x86 and function tested the patch on s390.

Avi, please apply.

Done. Thanks!

Signature · 8 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
#23 lore raw

Re: [kvm-devel] Use virtual cpu accounting if available for guest times.

In reply to Christian Borntraeger
Quoted 39 lines · Christian Borntraeger

Avi,

ppc and s390 offer the possibility to track process times precisely by looking at cpu timer on every context switch, irq, softirq etc. We can use that infrastructure as well for guest time accounting. We need to account the used time before we change the state. This patch adds a call to account_system_vtime to kvm_guest_enter and kvm_guest exit. If CONFIG_VIRT_CPU_ACCOUNTING is not set, account_system_vtime is defined in hardirq.h as an empty function, which means this patch does not change the behaviour on other platforms.

I compile tested this patch on x86 and function tested the patch on s390.

Avi, please apply.

---
 drivers/kvm/kvm.h |    3 +++
 1 file changed, 3 insertions(+)

Index: kvm/drivers/kvm/kvm.h
===================================================================

drivers/kvm/kvm.h +1 -0
@@ -7,6 +7,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/hardirq.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
@@ -669,11 +670,13 @@ __init void kvm_arch_init(void);
 
 static inline void kvm_guest_enter(void)

drivers/kvm/kvm.h __init void kvm_arch_init(void); · line 681

Quoted 10 lines
drivers/kvm/kvm.h +2 -0
 {
+	account_system_vtime(current);
 	current->flags |= PF_VCPU;
 }
 
 static inline void kvm_guest_exit(void)
 {
+	account_system_vtime(current);
 	current->flags &= ~PF_VCPU;
 }

I don't understand. Should kvm_guest_exit() be calling account_user_vtime() (instead of account_system_vtime())?

Signature · 2 lines
Hollis Blanchard
IBM Linux Technology Center
#24 lore raw

Re: [kvm-devel] Use virtual cpu accounting if available for guest times.

Quoted 8 lines · Hollis Blanchard
Quoted 8 lines
drivers/kvm/kvm.h +1 -0
@@ -669,11 +670,13 @@ __init void kvm_arch_init(void);
 
 static inline void kvm_guest_enter(void)
 {
+	account_system_vtime(current);
 	current->flags |= PF_VCPU;
 }
 
Quoted 8 lines

drivers/kvm/kvm.h __init void kvm_arch_init(void); · line 681

Quoted 5 lines
drivers/kvm/kvm.h +1 -0
 static inline void kvm_guest_exit(void)
 {
+	account_system_vtime(current);
 	current->flags &= ~PF_VCPU;
 }

I don't understand. Should kvm_guest_exit() be calling account_user_vtime() (instead of account_system_vtime())?

Never mind; the tree I was looking at didn't have the account_guest_time() stuff in account_system_time().

Signature · 9 lines
Hollis Blanchard
IBM Linux Technology Center


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
#25 lore raw

PATCH 1/1 move kvm_guest_exit() after local_irq_enable()

In reply to Laurent Vivier

According comments from Avi, we can clear PF_VCPU in kvm_guest_exit if we move it after local_irq_enable().

http://lkml.org/lkml/2007/10/15/114

To simplify s390 port, we don't clear it in account_system_time().

http://lkml.org/lkml/2007/10/15/183

---
 drivers/kvm/kvm_main.c |    5 ++++-
 kernel/sched.c         |    1 -
 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/kvm/kvm_main.c +4 -1
index 87275be..b9cd1f0 100644
@@ -2194,12 +2194,15 @@ again:
 
 	kvm_x86_ops->run(vcpu, kvm_run);
 
-	kvm_guest_exit();
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 
 	++vcpu->stat.exits;
 
+	barrier();
+
+	kvm_guest_exit();
+
 	preempt_enable();
 
 	/*
kernel/sched.c +0 -1
index b27ab3e..57fac22 100644
@@ -3315,7 +3315,6 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
 #ifdef CONFIG_GUEST_ACCOUNTING
 	if (p->flags & PF_VCPU) {
 		account_guest_time(p, cputime);
-		p->flags &= ~PF_VCPU;
 		return;
 	}
 #endif
Signature · 1 line
1.5.2.4
#26 lore raw

Re: [kvm-devel] [PATCH] move kvm_guest_exit() after local_irq_enable()

Quoted 9 lines · Laurent Vivier

According comments from Avi, we can clear PF_VCPU in kvm_guest_exit if we move it after local_irq_enable().

http://lkml.org/lkml/2007/10/15/114

To simplify s390 port, we don't clear it in account_system_time().

http://lkml.org/lkml/2007/10/15/183

Applied (the kvm part), and added a fat comment on the barrier. Can you send a signed-off-by: line?

Signature · 8 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
#27 lore raw

Re: [kvm-devel] [PATCH] move kvm_guest_exit() after local_irq_enable()

Quoted 6 lines · Avi Kivity
Quoted 5 lines · Laurent Vivier

According comments from Avi, we can clear PF_VCPU in kvm_guest_exit if we move it after local_irq_enable().

http://lkml.org/lkml/2007/10/15/114

Quoted 8 lines
Quoted 4 lines

To simplify s390 port, we don't clear it in account_system_time().

http://lkml.org/lkml/2007/10/15/183

Applied (the kvm part), and added a fat comment on the barrier. Can you send a signed-off-by: line?

Sorry, I missed it...

#28 lore raw

Re: [PATCH] move kvm_guest_exit() after local_irq_enable()

In reply to Laurent Vivier
Quoted 8 lines · Laurent Vivier

According comments from Avi, we can clear PF_VCPU in kvm_guest_exit if we move it after local_irq_enable().

http://lkml.org/lkml/2007/10/15/114

To simplify s390 port, we don't clear it in account_system_time().

http://lkml.org/lkml/2007/10/15/183

thanks - i have picked your patch up.

Ingo

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

#29 lore raw

Re: [PATCH] move kvm_guest_exit() after local_irq_enable()

Quoted 6 lines · Ingo Molnar
Quoted 3 lines · Laurent Vivier

According comments from Avi, we can clear PF_VCPU in kvm_guest_exit if we move it after local_irq_enable().

Quoted 10 lines
Quoted 6 lines

http://lkml.org/lkml/2007/10/15/114

To simplify s390 port, we don't clear it in account_system_time().

http://lkml.org/lkml/2007/10/15/183

thanks - i have picked your patch up.

Note the kvm part is already in my 2.6.24 queue.

Signature · 8 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
Acked-by
#30 lore raw

Re: [PATCH] move kvm_guest_exit() after local_irq_enable()

Quoted 11 lines · Avi Kivity
Quoted 10 lines · Ingo Molnar
Quoted 7 lines · Laurent Vivier

According comments from Avi, we can clear PF_VCPU in kvm_guest_exit if we move it after local_irq_enable().

http://lkml.org/lkml/2007/10/15/114

To simplify s390 port, we don't clear it in account_system_time().

Quoted 8 lines
Quoted 6 lines
Quoted 2 lines

http://lkml.org/lkml/2007/10/15/183

thanks - i have picked your patch up.

Note the kvm part is already in my 2.6.24 queue.

ok, then please push the whole patch to Linus, the scheduler bits are:

Ingo

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

#31 lore raw

Re: [kvm-devel] [PATCH] move kvm_guest_exit() after local_irq_enable()

Quoted 8 lines · Ingo Molnar
Quoted 3 lines

Note the kvm part is already in my 2.6.24 queue.

ok, then please push the whole patch to Linus, the scheduler bits are:

Sure, thanks.

Signature · 8 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
#32 lore raw
In reply to Laurent Vivier

forgot to CC everybody besides Laurent:

Am Montag, 15. Oktober 2007 schrieben Sie:

Quoted 6 lines

No, It must not be cleared here because we can't enter in the accounting code between kvm_guest_enter(void) and kvm_guest_exit(void).

This is why the accounting code clears it.

I put a kvm_guest_exit() only for symmetry.

Why cant we enter the accounting code?
Dont know about x86, but on s390 we can get host interrupts and reschedules even when we run a guest (if preemption is on).

If the timer tick happens  while the guest is running, we will run the accounting code on x86 as well, no?

Christian

Signature · 5 lines
IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294