All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Xu <peterx@redhat.com>
To: Stefan Hajnoczi <stefanha@redhat.com>
Cc: qemu-devel@nongnu.org, "Eric Blake" <eblake@redhat.com>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Dr . David Alan Gilbert" <dgilbert@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v2 2/3] monitor: take mon_lock where proper
Date: Wed, 2 May 2018 15:04:02 +0800	[thread overview]
Message-ID: <20180502070402.GC32728@xz-mi> (raw)
In-Reply-To: <20180430101050.GD4002@stefanha-x1.localdomain>

On Mon, Apr 30, 2018 at 11:10:50AM +0100, Stefan Hajnoczi wrote:
> On Wed, Apr 18, 2018 at 05:02:38PM +0800, Peter Xu wrote:
> > diff --git a/monitor.c b/monitor.c
> > index c93aa4e22b..f4951cafbc 100644
> > --- a/monitor.c
> > +++ b/monitor.c
> > @@ -306,16 +306,20 @@ void monitor_read_command(Monitor *mon, int show_prompt)
> >      if (!mon->rs)
> >          return;
> >  
> > +    qemu_mutex_lock(&mon->mon_lock);
> >      readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL);
> >      if (show_prompt)
> >          readline_show_prompt(mon->rs);
> > +    qemu_mutex_unlock(&mon->mon_lock);
> >  }
> >  
> >  int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
> >                            void *opaque)
> >  {
> >      if (mon->rs) {
> > +        qemu_mutex_lock(&mon->mon_lock);
> >          readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
> > +        qemu_mutex_unlock(&mon->mon_lock);
> >          /* prompt is printed on return from the command handler */
> >          return 0;
> >      } else {
> 
> I'm not sure why the lock is being used around readline_start() and
> readline_show_prompt().  There are other readline_*() callers who do not
> take the lock, which is suspicious.
> 
> Can you explain the purpose of this?
> 
> > @@ -1308,8 +1312,7 @@ void qmp_qmp_capabilities(bool has_enable, QMPCapabilityList *enable,
> >      cur_mon->qmp.commands = &qmp_commands;
> >  }
> >  
> > -/* set the current CPU defined by the user */
> > -int monitor_set_cpu(int cpu_index)
> > +static int monitor_set_cpu_locked(Monitor *mon, int cpu_index)
> 
> This function requires the BQL since qemu_get_cpu() accesses the cpus
> list without acquiring qemu_cpu_list_lock.
> 
> Two options:
> 1. Document that monitor_set_cpu() must be called with the BQL held.
> 2. Audit qemu_cpu_list_lock to check that it meets the out-of-band
>    monitor code requirements, document that qemu_cpu_list_lock code must
>    follow out-of-band monitor code requirements, and then take the lock.
> 
> #1 is more practical since we will probably never need to call
> monitor_set_cpu() from out-of-band monitor code.  Anyway, in that case
> mon_lock is not needed unless there is a mon field that needs to be
> protected.

You are right.

After a second thought I think readline is not needed to be protected.
IMHO it's only used in parsing phase, so actually we don't have
multi-threading issue with that (parsing is either happening in main
thread only, or monitor iothread only).

So I'll drop all the readline_* protections, and add a comment for
monitor_set_cpu() on BQL.

> 
> >  {
> >      CPUState *cpu;
> >  
> > @@ -1317,15 +1320,28 @@ int monitor_set_cpu(int cpu_index)
> >      if (cpu == NULL) {
> >          return -1;
> >      }
> > -    g_free(cur_mon->mon_cpu_path);
> > -    cur_mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
> > +    g_free(mon->mon_cpu_path);
> > +    mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
> >      return 0;
> >  }
> >  
> > +/* set the current CPU defined by the user */
> > +int monitor_set_cpu(int cpu_index)
> > +{
> > +    int ret;
> > +
> > +    qemu_mutex_lock(&cur_mon->mon_lock);
> > +    ret = monitor_set_cpu_locked(cur_mon, cpu_index);
> > +    qemu_mutex_unlock(&cur_mon->mon_lock);
> > +
> > +    return ret;
> > +}
> > +
> >  static CPUState *mon_get_cpu_sync(bool synchronize)
> >  {
> 
> This function calls monitor_set_cpu() so it must be called from the BQL.
> The locking changes are probably not needed.  This function just needs
> to be documented as BQL-only.

Yes.  Will do.

> 
> > @@ -2239,6 +2258,7 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
> >  {
> >      mon_fd_t *monfd;
> >  
> > +    qemu_mutex_lock(&mon->mon_lock);
> >      QLIST_FOREACH(monfd, &mon->fds, next) {
> >          int fd;
> >  
> > @@ -2252,9 +2272,10 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
> >          QLIST_REMOVE(monfd, next);
> >          g_free(monfd->name);
> >          g_free(monfd);
> > -
> > +        qemu_mutex_unlock(&mon->mon_lock);
> >          return fd;
> >      }
> > +    qemu_mutex_unlock(&mon->mon_lock);
> 
> What about all the other mon->fds users?  They need to lock too,
> otherwise we will QLIST_REMOVE() an fd while they are accessing the
> list!

Indeed!  I think I'll drop most of this patch, only add protection for
mon->fds, and add those comments that you suggested.  They make sense
to me.  Thanks,

-- 
Peter Xu

  reply	other threads:[~2018-05-02  7:04 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-18  9:02 [Qemu-devel] [PATCH v2 0/3] monitor: let Monitor be thread safe Peter Xu
2018-04-18  9:02 ` [Qemu-devel] [PATCH v2 1/3] monitor: rename out_lock to mon_lock Peter Xu
2018-04-30  9:56   ` Stefan Hajnoczi
2018-05-02  6:33     ` Peter Xu
2018-04-18  9:02 ` [Qemu-devel] [PATCH v2 2/3] monitor: take mon_lock where proper Peter Xu
2018-04-30 10:10   ` Stefan Hajnoczi
2018-05-02  7:04     ` Peter Xu [this message]
2018-04-18  9:02 ` [Qemu-devel] [PATCH v2 3/3] monitor: add lock to protect mon_fdsets Peter Xu
2018-04-30 10:21   ` Stefan Hajnoczi
2018-05-02  7:22     ` Peter Xu

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=20180502070402.GC32728@xz-mi \
    --to=peterx@redhat.com \
    --cc=armbru@redhat.com \
    --cc=dgilbert@redhat.com \
    --cc=eblake@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --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.