From: "Dr. David Alan Gilbert" <dave@treblig.org>
To: Stefan Hajnoczi <stefanha@gmail.com>
Cc: "Stefan Hajnoczi" <stefanha@redhat.com>,
qemu-devel@nongnu.org, "Eduardo Habkost" <eduardo@habkost.net>,
pbonzini@redhat.com, "Markus Armbruster" <armbru@redhat.com>,
"Eric Blake" <eblake@redhat.com>,
kwolf@redhat.com, "Maxim Levitsky" <mlevitsk@redhat.com>,
"Daniel P. Berrangé" <berrange@redhat.com>
Subject: Re: [RFC 1/3] hmp: avoid the nested event loop in handle_hmp_command()
Date: Thu, 7 Sep 2023 20:53:15 +0000 [thread overview]
Message-ID: <ZPo4O3k2ikebJS6Y@gallifrey> (raw)
In-Reply-To: <CAJSP0QWGi4y0aanPKs7S0HuOD=Vp4GZ2YURMZovgO9_zDSucng@mail.gmail.com>
* Stefan Hajnoczi (stefanha@gmail.com) wrote:
> On Thu, 7 Sept 2023 at 10:07, Dr. David Alan Gilbert <dave@treblig.org> wrote:
> >
> > * Stefan Hajnoczi (stefanha@redhat.com) wrote:
> > > On Thu, Sep 07, 2023 at 01:06:39AM +0000, Dr. David Alan Gilbert wrote:
> > > > * Stefan Hajnoczi (stefanha@redhat.com) wrote:
> > > > > Coroutine HMP commands currently run to completion in a nested event
> > > > > loop with the Big QEMU Lock (BQL) held. The call_rcu thread also uses
> > > > > the BQL and cannot process work while the coroutine monitor command is
> > > > > running. A deadlock occurs when monitor commands attempt to wait for
> > > > > call_rcu work to finish.
> > > >
> > > > I hate to think if there's anywhere else that ends up doing that
> > > > other than the monitors.
> > >
> > > Luckily drain_call_rcu() has few callers: just
> > > xen_block_device_destroy() and qmp_device_add(). We only need to worry
> > > about their call stacks.
> > >
> > > I haven't looked at the Xen code.
> > >
> > > >
> > > > But, not knowing the semantics of the rcu code, it looks kind of OK to
> > > > me from the monitor.
> > > >
> > > > (Do you ever get anything like qemu quitting from one of the other
> > > > monitors while this coroutine hasn't been run?)
> > >
> > > Not sure what you mean?
> >
> > Imagine that just after you create your coroutine, a vCPU does a
> > shutdown and qemu is configured to quit, or on another monitor someone
> > does a quit; does your coroutine get executed or not?
>
> I think the answer is that it depends.
>
> A coroutine can run for a while and then yield while waiting for a
> timer, BH, fd handler, etc. If the coroutine has yielded then I think
> QEMU could terminate.
>
> The behavior of entering a coroutine for the first time depends on the
> API that is used (e.g. qemu_coroutine_enter()/aio_co_enter()/etc).
> qemu_coroutine_enter() is immediate but aio_co_enter() contains
> indirect code paths like scheduling a BH.
>
> To summarize: ¯\_(ツ)_/¯
That does mean you leave your g_new'd data and qdict allocated at
exit - meh
I'm not sure if it means you're making any other assumptions about what
happens if the coroutine gets run during the exit path; although I guess
there are plenty of other cases like that.
Dave
> Stefan
>
> >
> > Dave
> >
> > > Stefan
> > >
> > > >
> > > > Dave
> > > >
> > > > > This patch refactors the HMP monitor to use the existing event loop
> > > > > instead of creating a nested event loop. This will allow the next
> > > > > patches to rely on draining call_rcu work.
> > > > >
> > > > > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> > > > > ---
> > > > > monitor/hmp.c | 28 +++++++++++++++-------------
> > > > > 1 file changed, 15 insertions(+), 13 deletions(-)
> > > > >
> > > > > diff --git a/monitor/hmp.c b/monitor/hmp.c
> > > > > index 69c1b7e98a..6cff2810aa 100644
> > > > > --- a/monitor/hmp.c
> > > > > +++ b/monitor/hmp.c
> > > > > @@ -1111,15 +1111,17 @@ typedef struct HandleHmpCommandCo {
> > > > > Monitor *mon;
> > > > > const HMPCommand *cmd;
> > > > > QDict *qdict;
> > > > > - bool done;
> > > > > } HandleHmpCommandCo;
> > > > >
> > > > > -static void handle_hmp_command_co(void *opaque)
> > > > > +static void coroutine_fn handle_hmp_command_co(void *opaque)
> > > > > {
> > > > > HandleHmpCommandCo *data = opaque;
> > > > > +
> > > > > handle_hmp_command_exec(data->mon, data->cmd, data->qdict);
> > > > > monitor_set_cur(qemu_coroutine_self(), NULL);
> > > > > - data->done = true;
> > > > > + qobject_unref(data->qdict);
> > > > > + monitor_resume(data->mon);
> > > > > + g_free(data);
> > > > > }
> > > > >
> > > > > void handle_hmp_command(MonitorHMP *mon, const char *cmdline)
> > > > > @@ -1157,20 +1159,20 @@ void handle_hmp_command(MonitorHMP *mon, const char *cmdline)
> > > > > Monitor *old_mon = monitor_set_cur(qemu_coroutine_self(), &mon->common);
> > > > > handle_hmp_command_exec(&mon->common, cmd, qdict);
> > > > > monitor_set_cur(qemu_coroutine_self(), old_mon);
> > > > > + qobject_unref(qdict);
> > > > > } else {
> > > > > - HandleHmpCommandCo data = {
> > > > > - .mon = &mon->common,
> > > > > - .cmd = cmd,
> > > > > - .qdict = qdict,
> > > > > - .done = false,
> > > > > - };
> > > > > - Coroutine *co = qemu_coroutine_create(handle_hmp_command_co, &data);
> > > > > + HandleHmpCommandCo *data; /* freed by handle_hmp_command_co() */
> > > > > +
> > > > > + data = g_new(HandleHmpCommandCo, 1);
> > > > > + data->mon = &mon->common;
> > > > > + data->cmd = cmd;
> > > > > + data->qdict = qdict; /* freed by handle_hmp_command_co() */
> > > > > +
> > > > > + Coroutine *co = qemu_coroutine_create(handle_hmp_command_co, data);
> > > > > + monitor_suspend(&mon->common); /* resumed by handle_hmp_command_co() */
> > > > > monitor_set_cur(co, &mon->common);
> > > > > aio_co_enter(qemu_get_aio_context(), co);
> > > > > - AIO_WAIT_WHILE_UNLOCKED(NULL, !data.done);
> > > > > }
> > > > > -
> > > > > - qobject_unref(qdict);
> > > > > }
> > > > >
> > > > > static void cmd_completion(MonitorHMP *mon, const char *name, const char *list)
> > > > > --
> > > > > 2.41.0
> > > > >
> > > > >
> > > > --
> > > > -----Open up your eyes, open up your mind, open up your code -------
> > > > / Dr. David Alan Gilbert | Running GNU/Linux | Happy \
> > > > \ dave @ treblig.org | | In Hex /
> > > > \ _________________________|_____ http://www.treblig.org |_______/
> > > >
> >
> >
> > --
> > -----Open up your eyes, open up your mind, open up your code -------
> > / Dr. David Alan Gilbert | Running GNU/Linux | Happy \
> > \ dave @ treblig.org | | In Hex /
> > \ _________________________|_____ http://www.treblig.org |_______/
> >
--
-----Open up your eyes, open up your mind, open up your code -------
/ Dr. David Alan Gilbert | Running GNU/Linux | Happy \
\ dave @ treblig.org | | In Hex /
\ _________________________|_____ http://www.treblig.org |_______/
next prev parent reply other threads:[~2023-09-07 20:54 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-06 19:01 [RFC 0/3] qmp: make qmp_device_add() a coroutine Stefan Hajnoczi
2023-09-06 19:01 ` [RFC 1/3] hmp: avoid the nested event loop in handle_hmp_command() Stefan Hajnoczi
2023-09-07 1:06 ` Dr. David Alan Gilbert
2023-09-07 14:04 ` Stefan Hajnoczi
2023-09-07 14:07 ` Dr. David Alan Gilbert
2023-09-07 15:34 ` Stefan Hajnoczi
2023-09-07 20:53 ` Dr. David Alan Gilbert [this message]
2023-09-07 21:25 ` Stefan Hajnoczi
2023-09-06 19:01 ` [RFC 2/3] rcu: add drain_call_rcu_co() API Stefan Hajnoczi
2023-09-12 16:36 ` Kevin Wolf
2023-09-12 16:52 ` Stefan Hajnoczi
2023-09-06 19:01 ` [RFC 3/3] qmp: make qmp_device_add() a coroutine Stefan Hajnoczi
2023-09-12 16:47 ` Kevin Wolf
2023-09-12 17:04 ` Stefan Hajnoczi
2023-09-07 11:28 ` [RFC 0/3] " Paolo Bonzini
2023-09-07 14:00 ` Stefan Hajnoczi
2023-09-07 14:25 ` Paolo Bonzini
2023-09-07 15:29 ` Stefan Hajnoczi
2023-09-12 17:08 ` Kevin Wolf
2023-09-13 11:38 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZPo4O3k2ikebJS6Y@gallifrey \
--to=dave@treblig.org \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=eblake@redhat.com \
--cc=eduardo@habkost.net \
--cc=kwolf@redhat.com \
--cc=mlevitsk@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@gmail.com \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.