On Mon, Nov 22, 2010 at 05:00:18PM -0600, Anthony Liguori wrote: > qemu-kvm vcpu threads don't response to SIGSTOP/SIGCONT. Instead of teaching > them to respond to these signals, introduce monitor commands that stop and start > individual vcpus. > > The purpose of these commands are to implement CPU hard limits using an external > tool that watches the CPU consumption and stops the CPU as appropriate. > > The monitor commands provide a more elegant solution that signals because it > ensures that a stopped vcpu isn't holding the qemu_mutex. > Do you really want to stop vcpu while it holds guest lock? Does external tool have enough info to make smart decision about how to limit vcpu runtime. > I'll reply to this note with an example tool. > > Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx> > > diff --git a/hmp-commands.hx b/hmp-commands.hx > index ba6de28..827bd67 100644 > --- a/hmp-commands.hx > +++ b/hmp-commands.hx > @@ -279,6 +279,24 @@ Resume emulation. > ETEXI > > { > + .name = "cpu_start", > + .args_type = "cpu:i", > + .params = "[cpu]", > + .help = "start cpu emulation", > + .user_print = monitor_user_noop, > + .mhandler.cmd_new = do_vcpu_start, > + }, > + > + { > + .name = "cpu_stop", > + .args_type = "cpu:i", > + .params = "[cpu]", > + .help = "stop cpu emulation", > + .user_print = monitor_user_noop, > + .mhandler.cmd_new = do_vcpu_stop, > + }, > + > + { > .name = "gdbserver", > .args_type = "device:s?", > .params = "[device]", > diff --git a/qemu-kvm.c b/qemu-kvm.c > index 471306b..35121ed 100644 > --- a/qemu-kvm.c > +++ b/qemu-kvm.c > @@ -1351,6 +1351,65 @@ static void pause_all_threads(void) > } > } > > +static void vcpu_stop(int cpu) > +{ > + CPUState *env = first_cpu; > + > + for (env = first_cpu; env; env = env->next_cpu) { > + if (env->cpu_index == cpu) { > + break; > + } > + } > + > + if (env) { > + if (env != cpu_single_env) { > + env->stop = 1; > + pthread_kill(env->kvm_cpu_state.thread, SIG_IPI); > + } else { > + env->stop = 0; > + env->stopped = 1; > + cpu_exit(env); > + } > + > + while (!env->stopped) { > + qemu_cond_wait(&qemu_pause_cond); > + } > + } > +} > + > +static void vcpu_start(int cpu) > +{ > + CPUState *env = first_cpu; > + > + assert(!cpu_single_env); > + > + for (env = first_cpu; env; env = env->next_cpu) { > + if (env->cpu_index == cpu) { > + break; > + } > + } > + > + if (env) { > + env->stop = 0; > + env->stopped = 0; > + pthread_kill(env->kvm_cpu_state.thread, SIG_IPI); > + } > +} > + > +int do_vcpu_stop(Monitor *mon, const QDict *qdict, QObject **ret_data) > +{ > + int vcpu = qdict_get_int(qdict, "cpu"); > + vcpu_stop(vcpu); > + return 0; > +} > + > +int do_vcpu_start(Monitor *mon, const QDict *qdict, QObject **ret_data) > +{ > + int vcpu = qdict_get_int(qdict, "cpu"); > + vcpu_start(vcpu); > + return 0; > +} > + > static void resume_all_threads(void) > { > CPUState *penv = first_cpu; > diff --git a/sysemu.h b/sysemu.h > index 849dc8c..3ef68dd 100644 > --- a/sysemu.h > +++ b/sysemu.h > @@ -61,6 +61,9 @@ void qemu_system_reset(void); > void qemu_add_exit_notifier(Notifier *notify); > void qemu_remove_exit_notifier(Notifier *notify); > > +int do_vcpu_stop(Monitor *mon, const QDict *qdict, QObject **ret_data); > +int do_vcpu_start(Monitor *mon, const QDict *qdict, QObject **ret_data); > + > void do_savevm(Monitor *mon, const QDict *qdict); > int load_vmstate(const char *name); > void do_delvm(Monitor *mon, const QDict *qdict); > -- > 1.7.0.4 > > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Gleb. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html