QEMU/KVM: dedicated IO thread
RFC 1/1 QEMU/KVM: dedicated IO thread
Avi was concerned that this would cause problems with migration. I haven't specifically tested it yet, but it seems there will be no problems introduced by this change: the IO thread will stop all vcpu's in the same way the vcpu0 thread did before.
QEMU/KVM: separate thread for IO handling
Move IO processing from vcpu0 to a dedicated thread.
This removes load on vcpu0 by allowing better cache locality and also improves latency.
We can now block signal handling for IO events, so sigtimedwait won't race with handlers:
- Currently the SIGALRM handler fails to set CPU_INTERRUPT_EXIT because the "next_cpu" variable is not initialized in the KVM path, meaning that processing of timer expiration might be delayed until the next vcpu0 exit.
- Processing of IO events will not be unnecessarily interrupted.
libkvm/libkvm.c +0 -3
@@ -388,9 +388,6 @@ int kvm_create(kvm_context_t kvm, unsignif (r <0 )return r;kvm_create_irqchip (kvm); - r =kvm_create_vcpu (kvm,0 ); -if (r <0 ) -return r;return 0 ; }
qemu/qemu-kvm.c +77 -48
253 lines not on this page · raw message
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Quoted 5 lines · Marcelo Tosatti
Avi was concerned that this would cause problems with migration. I haven't specifically tested it yet, but it seems there will be no problems introduced by this change: the IO thread will stop all vcpu's in the same way the vcpu0 thread did before.
I believe this is broken for smp_cpus > 1, and will with this change will be broken even for non smp. The pause/resume logic is rotten.
Quoted 7 lines
QEMU/KVM: separate thread for IO handling
Move IO processing from vcpu0 to a dedicated thread.
This removes load on vcpu0 by allowing better cache locality and also improves latency.
Quoted 7 lines
We can now block signal handling for IO events, so sigtimedwait won't race with handlers:
- Currently the SIGALRM handler fails to set
CPU_INTERRUPT_EXITbecause the "next_cpu" variable is not initialized in the KVM path, meaning that processing of timer expiration might be delayed until the next vcpu0 exit.
I think we call main_loop_wait() is called unconditionally after every signal.
Quoted 9 lines
- Processing of IO events will not be unnecessarily interrupted.
Index:
kvm-userspace.io/libkvm/libkvm.c
===================================================================
libkvm/libkvm.c int kvm_create(kvm_context_t kvm, unsign · line 393
Quoted 9 lines
libkvm/libkvm.c +0
-3@@ -388,9 +388,6 @@ int kvm_create(kvm_context_t kvm, unsignif (r <0 )return r;kvm_create_irqchip (kvm); - r =kvm_create_vcpu (kvm,0 ); -if (r <0 ) -return r;return 0 ; }
Please put this and the corresponding qemu change in a separate patch.
[...lots more...]
Looks good.
Signature · 7 lines
error compiling committee.c: too many arguments to function ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Quoted 9 lines · Avi Kivity
Quoted 5 lines · Marcelo Tosatti
Avi was concerned that this would cause problems with migration. I haven't specifically tested it yet, but it seems there will be no problems introduced by this change: the IO thread will stop all vcpu's in the same way the vcpu0 thread did before.
I believe this is broken for
smp_cpus> 1, and will with this change will be broken even for non smp. The pause/resume logic is rotten.
Ok, I'll look into it in more detail.
Quoted 10 lines
Quoted 10 lines
QEMU/KVM: separate thread for IO handling
Move IO processing from vcpu0 to a dedicated thread.
This removes load on vcpu0 by allowing better cache locality and also improves latency.
We can now block signal handling for IO events, so sigtimedwait won't race with handlers:
Quoted 7 lines
Quoted 4 lines
- Currently the SIGALRM handler fails to set
CPU_INTERRUPT_EXITbecause the "next_cpu" variable is not initialized in the KVM path, meaning that processing of timer expiration might be delayed until the next vcpu0 exit.I think we call
main_loop_wait()is called unconditionally after every signal.
We exit the kvm_run() loop if CPU_INTERRUPT_EXIT is detected by pre_kvm_run().
But the SIGALRM handler won't set it:
static void host_alarm_handler(int host_signum)
{
...
CPUState *env = next_cpu;
alarm_timer->flags |= ALARM_FLAG_EXPIRED;
if (env) {
/* stop the currently executing cpu because a timer occured */
cpu_interrupt(env, CPU_INTERRUPT_EXIT);
#ifdef USE_KQEMU
if (env->kqemu_enabled) {
kqemu_cpu_interrupt(env);
}#endif
Because the KVM path does not initialize "next_cpu":
static int main_loop(void)
{
int ret, timeout;
#ifdef CONFIG_PROFILER
int64_t ti;
#endif
CPUState *env;
if (kvm_enabled()) {
kvm_main_loop();
cpu_disable_ticks();
return 0;
}
cur_cpu = first_cpu;
next_cpu = cur_cpu->next_cpu ?: first_cpu;Quoted 22 lines
Quoted 10 lines
- Processing of IO events will not be unnecessarily interrupted.
Index:
kvm-userspace.io/libkvm/libkvm.c
===================================================================libkvm/libkvm.c int kvm_create(kvm_context_t kvm, unsign · line 393
Quoted 9 lines
libkvm/libkvm.c +0
-3@@ -388,9 +388,6 @@ int kvm_create(kvm_context_t kvm, unsignif (r <0 )return r;kvm_create_irqchip (kvm); - r =kvm_create_vcpu (kvm,0 ); -if (r <0 ) -return r;return 0 ; }Please put this and the corresponding qemu change in a separate patch.
Quoted 3 lines
[...lots more...]
Looks good.
Will do.
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
Quoted 16 lines · Marcelo Tosatti
Quoted 16 lines
Quoted 16 lines
QEMU/KVM: separate thread for IO handling
Move IO processing from vcpu0 to a dedicated thread.
This removes load on vcpu0 by allowing better cache locality and also improves latency.
We can now block signal handling for IO events, so sigtimedwait won't race with handlers:
- Currently the SIGALRM handler fails to set
CPU_INTERRUPT_EXITbecause the "next_cpu" variable is not initialized in the KVM path, meaning that processing of timer expiration might be delayed until the next vcpu0 exit.
Quoted 7 lines
Quoted 3 lines
I think we call
main_loop_wait()is called unconditionally after every signal.We exit the
kvm_run()loop ifCPU_INTERRUPT_EXITis detected bypre_kvm_run().
But why do we need to exit the kvm_run() loop? As I understand it, the I/O thread wakes up when the signal is queued and calls main_loop_wait() to process any events (through qemu_run_timers()). If a timer needs to wake up a vcpu, it will raise an interrupt line which will wake the vcpu up, either in the kernel or in userspace depending on -no-kvm-irqchip.
Signature · 8 lines
error compiling committee.c: too many arguments to function ------------------------------------------------------------------------- Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
Quoted 25 lines · Avi Kivity
Quoted 16 lines · Marcelo Tosatti
Quoted 16 lines
Quoted 16 lines
QEMU/KVM: separate thread for IO handling
Move IO processing from vcpu0 to a dedicated thread.
This removes load on vcpu0 by allowing better cache locality and also improves latency.
We can now block signal handling for IO events, so sigtimedwait won't race with handlers:
- Currently the SIGALRM handler fails to set
CPU_INTERRUPT_EXITbecause the "next_cpu" variable is not initialized in the KVM path, meaning that processing of timer expiration might be delayed until the next vcpu0 exit.Quoted 7 lines
Quoted 3 lines
I think we call
main_loop_wait()is called unconditionally after every signal.We exit the
kvm_run()loop ifCPU_INTERRUPT_EXITis detected bypre_kvm_run().
Quoted 5 lines
But why do we need to exit the
kvm_run()loop? As I understand it, the I/O thread wakes up when the signal is queued and callsmain_loop_wait()to process any events (throughqemu_run_timers()). If a timer needs to wake up a vcpu, it will raise an interrupt line which will wake the vcpu up, either in the kernel or in userspace depending on -no-kvm-irqchip.
In the current state of vcpu0 thread handling IO, kvm_run() loop must bail out for main_loop_wait->qemu_run_timers() to run.
If using an userspace timer such as RTC (brought to attention by Dor's patches), the following will happen:
- signal wakes up vcpu0 thread, goes back to userspace.
- host_alarm_handler runs but fails to set CPU_INTERRUPT_EXIT because "next_cpu" is not initialized.
- pre_kvm_run() checks for CPU_INTERRUPT_EXIT and determines its not necessary to exit kvm_run(), so vcpu0 thread goes back into kernel to enter guest mode.
No interrupt was raised even though SIGALRM handler has executed.
AFAICS next_cpu is only initialized here:
static int main_loop(void)
{
...
if (kvm_enabled()) {
kvm_main_loop();
cpu_disable_ticks();
return 0;
}
cur_cpu = first_cpu;
next_cpu = cur_cpu->next_cpu ?: first_cpu;
for(;;) {See ? I pointed this out as it appears to be another factor in unreliable userspace timers.
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
Quoted 38 lines · Marcelo Tosatti
Quoted 25 lines · Avi Kivity
Quoted 16 lines · Marcelo Tosatti
Quoted 16 lines
Quoted 16 lines
QEMU/KVM: separate thread for IO handling
Move IO processing from vcpu0 to a dedicated thread.
This removes load on vcpu0 by allowing better cache locality and also improves latency.
We can now block signal handling for IO events, so sigtimedwait won't race with handlers:
- Currently the SIGALRM handler fails to set
CPU_INTERRUPT_EXITbecause the "next_cpu" variable is not initialized in the KVM path, meaning that processing of timer expiration might be delayed until the next vcpu0 exit.Quoted 7 lines
Quoted 3 lines
I think we call
main_loop_wait()is called unconditionally after every signal.We exit the
kvm_run()loop ifCPU_INTERRUPT_EXITis detected bypre_kvm_run().Quoted 5 lines
But why do we need to exit the
kvm_run()loop? As I understand it, the I/O thread wakes up when the signal is queued and callsmain_loop_wait()to process any events (throughqemu_run_timers()). If a timer needs to wake up a vcpu, it will raise an interrupt line which will wake the vcpu up, either in the kernel or in userspace depending on -no-kvm-irqchip.In the current state of vcpu0 thread handling IO,
kvm_run()loop must bail out formain_loop_wait->qemu_run_timers()to run.If using an userspace timer such as RTC (brought to attention by Dor's patches), the following will happen:
Quoted 9 lines
- signal wakes up vcpu0 thread, goes back to userspace.
-host_alarm_handlerruns but fails to setCPU_INTERRUPT_EXITbecause "next_cpu" is not initialized.
-pre_kvm_run()checks forCPU_INTERRUPT_EXITand determines its not necessary to exitkvm_run(), so vcpu0 thread goes back into kernel to enter guest mode.No interrupt was raised even though SIGALRM handler has executed.
But what if the host_alarm_handler to wake up the sleeping IO thread, then it will run the timers and the irq will be triggered using ioctl. You're right that if the designated vcpu was in userspace at that time it might go back into the kernel but the time to do is decreases + the following:
Every vcpu reads it's irq vector every time before vcpu_run so the guest will receive the irq the next vmenter.
The lapic code sends kvm_vcpu_kick to the destination vcpu in order to cause a vmexit so interrupt would be injected next time.
Quoted 15 lines
AFAICS
next_cpuis only initialized here:static int
main_loop(void)
{
...if (kvm_enabled()) { kvm_main_loop(); cpu_disable_ticks(); return 0; } cur_cpu = first_cpu; next_cpu = cur_cpu->next_cpu ?: first_cpu; for(;;) {
Quoted 3 lines
See ? I pointed this out as it appears to be another factor in unreliable userspace timers.
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace