All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hailiang Zhang <zhang.zhanghailiang@huawei.com>
To: "Marc-André Lureau" <marcandre.lureau@redhat.com>
Cc: pbonzini@redhat.com, qemu-devel@nongnu.org,
	zhangchen fnst <zhangchen.fnst@cn.fujitsu.com>
Subject: Re: [Qemu-devel] [PATCH] char: Fix removing wrong GSource that be found by fd_in_tag
Date: Fri, 14 Apr 2017 18:43:26 +0800	[thread overview]
Message-ID: <58F0A7CE.50501@huawei.com> (raw)
In-Reply-To: <1167061760.27389486.1492164610590.JavaMail.zimbra@redhat.com>

Hi,

On 2017/4/14 18:10, Marc-André Lureau wrote:
> Hi
>
> ----- Original Message -----
>> We use fd_in_tag to find a GSource, fd_in_tag is return value of
>> g_source_attach(GSource *source, GMainContext *context), the return
>> value is unique only in the same context, so we may get the same
>> values with different 'context' parameters.
>>
>> It is no problem to find the right fd_in_tag by using
>>   g_main_context_find_source_by_id(GMainContext *context, guint source_id)
>> while there is only one default main context.
>>
>> But colo-compare tries to create/use its own context, and if we pass wrong
>> 'context' parameter with right fd_in_tag, we will find a wrong GSource
>> to handle. We tied to fix the related codes in commit b43dec, but it didn't
> tied->tried
>
> Please use a bit longer commit sha1, or full sha1, it will likely conflict otherwise in the future.

OK, I'll replace it with the full sha1.
>> fix the bug completely, because we still have some codes didn't pass *right*
>> context parameter for remove_fd_in_watch().
> Mixing contexts sounds like a colo-compare bug, did you fix it there too?

Yes, we don't have to change any other codes in colo-compare,
We just call qemu_chr_fe_set_handlers() in colo-compare to detach the old GSource
from main default context, and attach the new GSource to the new context.

>> Let's fix it by record the GSource directly instead of fd_in_tag.
> Make sense to me, and even simplify a bit the code. We should be more careful with pointers though (the reason why tag existed in the first place I imagine).

Agreed.

>> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
>> ---
>>   chardev/char-fd.c     |  8 ++++----
>>   chardev/char-io.c     | 23 ++++++++---------------
>>   chardev/char-io.h     |  4 ++--
>>   chardev/char-pty.c    |  6 +++---
>>   chardev/char-socket.c |  8 ++++----
>>   chardev/char-udp.c    |  8 ++++----
>>   chardev/char.c        |  2 +-
>>   include/sysemu/char.h |  2 +-
>>   8 files changed, 27 insertions(+), 34 deletions(-)
>>
>> diff --git a/chardev/char-fd.c b/chardev/char-fd.c
>> index 548dd4c..7f0169d 100644
>> --- a/chardev/char-fd.c
>> +++ b/chardev/char-fd.c
>> @@ -58,7 +58,7 @@ static gboolean fd_chr_read(QIOChannel *chan, GIOCondition
>> cond, void *opaque)
>>       ret = qio_channel_read(
>>           chan, (gchar *)buf, len, NULL);
>>       if (ret == 0) {
>> -        remove_fd_in_watch(chr, NULL);
>> +        remove_fd_in_watch(chr);
>>           qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
>>           return FALSE;
>>       }
>> @@ -89,9 +89,9 @@ static void fd_chr_update_read_handler(Chardev *chr,
>>   {
>>       FDChardev *s = FD_CHARDEV(chr);
>>   
>> -    remove_fd_in_watch(chr, NULL);
>> +    remove_fd_in_watch(chr);
>>       if (s->ioc_in) {
>> -        chr->fd_in_tag = io_add_watch_poll(chr, s->ioc_in,
>> +        chr->chr_gsource = io_add_watch_poll(chr, s->ioc_in,
>>                                              fd_chr_read_poll,
>>                                              fd_chr_read, chr,
>>                                              context);
>> @@ -103,7 +103,7 @@ static void char_fd_finalize(Object *obj)
>>       Chardev *chr = CHARDEV(obj);
>>       FDChardev *s = FD_CHARDEV(obj);
>>   
>> -    remove_fd_in_watch(chr, NULL);
>> +    remove_fd_in_watch(chr);
>>       if (s->ioc_in) {
>>           object_unref(OBJECT(s->ioc_in));
>>       }
>> diff --git a/chardev/char-io.c b/chardev/char-io.c
>> index b4bb094..6deb193 100644
>> --- a/chardev/char-io.c
>> +++ b/chardev/char-io.c
>> @@ -98,7 +98,7 @@ static GSourceFuncs io_watch_poll_funcs = {
>>       .finalize = io_watch_poll_finalize,
>>   };
>>   
>> -guint io_add_watch_poll(Chardev *chr,
>> +GSource *io_add_watch_poll(Chardev *chr,
>>                           QIOChannel *ioc,
>>                           IOCanReadHandler *fd_can_read,
>>                           QIOChannelFunc fd_read,
>> @@ -106,7 +106,6 @@ guint io_add_watch_poll(Chardev *chr,
>>                           GMainContext *context)
>>   {
>>       IOWatchPoll *iwp;
>> -    int tag;
>>       char *name;
>>   
>>       iwp = (IOWatchPoll *) g_source_new(&io_watch_poll_funcs,
>> @@ -122,21 +121,15 @@ guint io_add_watch_poll(Chardev *chr,
>>       g_source_set_name((GSource *)iwp, name);
>>       g_free(name);
>>   
>> -    tag = g_source_attach(&iwp->parent, context);
>> +    g_source_attach(&iwp->parent, context);
>>       g_source_unref(&iwp->parent);
>> -    return tag;
>> +    return (GSource *)iwp;
>>   }
>>   
>> -static void io_remove_watch_poll(guint tag, GMainContext *context)
>> +static void io_remove_watch_poll(GSource *source)
>>   {
>> -    GSource *source;
>>       IOWatchPoll *iwp;
>>   
>> -    g_return_if_fail(tag > 0);
>> -
>> -    source = g_main_context_find_source_by_id(context, tag);
>> -    g_return_if_fail(source != NULL);
>> -
>>       iwp = io_watch_poll_from_source(source);
>>       if (iwp->src) {
>>           g_source_destroy(iwp->src);
>> @@ -146,11 +139,11 @@ static void io_remove_watch_poll(guint tag,
>> GMainContext *context)
>>       g_source_destroy(&iwp->parent);
>>   }
>>   
>> -void remove_fd_in_watch(Chardev *chr, GMainContext *context)
>> +void remove_fd_in_watch(Chardev *chr)
>>   {
>> -    if (chr->fd_in_tag) {
>> -        io_remove_watch_poll(chr->fd_in_tag, context);
>> -        chr->fd_in_tag = 0;
>> +    if (chr->chr_gsource) {
>> +        io_remove_watch_poll(chr->chr_gsource);
>> +        chr->chr_gsource = 0;
> It's a pointer, let's use NULL.

OK. Will fix in next version.

Thanks,
Hailiang
>>       }
>>   }
>>   
>> diff --git a/chardev/char-io.h b/chardev/char-io.h
>> index 842be56..55973a7 100644
>> --- a/chardev/char-io.h
>> +++ b/chardev/char-io.h
>> @@ -29,14 +29,14 @@
>>   #include "sysemu/char.h"
>>   
>>   /* Can only be used for read */
>> -guint io_add_watch_poll(Chardev *chr,
>> +GSource *io_add_watch_poll(Chardev *chr,
>>                           QIOChannel *ioc,
>>                           IOCanReadHandler *fd_can_read,
>>                           QIOChannelFunc fd_read,
>>                           gpointer user_data,
>>                           GMainContext *context);
>>   
>> -void remove_fd_in_watch(Chardev *chr, GMainContext *context);
>> +void remove_fd_in_watch(Chardev *chr);
>>   
>>   int io_channel_send(QIOChannel *ioc, const void *buf, size_t len);
>>   
>> diff --git a/chardev/char-pty.c b/chardev/char-pty.c
>> index a6337be..561926f 100644
>> --- a/chardev/char-pty.c
>> +++ b/chardev/char-pty.c
>> @@ -199,7 +199,7 @@ static void pty_chr_state(Chardev *chr, int connected)
>>               g_source_remove(s->open_tag);
>>               s->open_tag = 0;
>>           }
>> -        remove_fd_in_watch(chr, NULL);
>> +        remove_fd_in_watch(chr);
>>           s->connected = 0;
>>           /* (re-)connect poll interval for idle guests: once per second.
>>            * We check more frequently in case the guests sends data to
>> @@ -215,8 +215,8 @@ static void pty_chr_state(Chardev *chr, int connected)
>>               s->connected = 1;
>>               s->open_tag = g_idle_add(qemu_chr_be_generic_open_func, chr);
>>           }
>> -        if (!chr->fd_in_tag) {
>> -            chr->fd_in_tag = io_add_watch_poll(chr, s->ioc,
>> +        if (!chr->chr_gsource) {
>> +            chr->chr_gsource = io_add_watch_poll(chr, s->ioc,
>>                                                  pty_chr_read_poll,
>>                                                  pty_chr_read,
>>                                                  chr, NULL);
>> diff --git a/chardev/char-socket.c b/chardev/char-socket.c
>> index 36ab0d6..376a70b 100644
>> --- a/chardev/char-socket.c
>> +++ b/chardev/char-socket.c
>> @@ -327,7 +327,7 @@ static void tcp_chr_free_connection(Chardev *chr)
>>       }
>>   
>>       tcp_set_msgfds(chr, NULL, 0);
>> -    remove_fd_in_watch(chr, NULL);
>> +    remove_fd_in_watch(chr);
>>       object_unref(OBJECT(s->sioc));
>>       s->sioc = NULL;
>>       object_unref(OBJECT(s->ioc));
>> @@ -484,7 +484,7 @@ static void tcp_chr_connect(void *opaque)
>>   
>>       s->connected = 1;
>>       if (s->ioc) {
>> -        chr->fd_in_tag = io_add_watch_poll(chr, s->ioc,
>> +        chr->chr_gsource = io_add_watch_poll(chr, s->ioc,
>>                                              tcp_chr_read_poll,
>>                                              tcp_chr_read,
>>                                              chr, NULL);
>> @@ -501,9 +501,9 @@ static void tcp_chr_update_read_handler(Chardev *chr,
>>           return;
>>       }
>>   
>> -    remove_fd_in_watch(chr, NULL);
>> +    remove_fd_in_watch(chr);
>>       if (s->ioc) {
>> -        chr->fd_in_tag = io_add_watch_poll(chr, s->ioc,
>> +        chr->chr_gsource = io_add_watch_poll(chr, s->ioc,
>>                                              tcp_chr_read_poll,
>>                                              tcp_chr_read, chr,
>>                                              context);
>> diff --git a/chardev/char-udp.c b/chardev/char-udp.c
>> index 804bd22..9d050bc 100644
>> --- a/chardev/char-udp.c
>> +++ b/chardev/char-udp.c
>> @@ -81,7 +81,7 @@ static gboolean udp_chr_read(QIOChannel *chan, GIOCondition
>> cond, void *opaque)
>>       ret = qio_channel_read(
>>           s->ioc, (char *)s->buf, sizeof(s->buf), NULL);
>>       if (ret <= 0) {
>> -        remove_fd_in_watch(chr, NULL);
>> +        remove_fd_in_watch(chr);
>>           return FALSE;
>>       }
>>       s->bufcnt = ret;
>> @@ -101,9 +101,9 @@ static void udp_chr_update_read_handler(Chardev *chr,
>>   {
>>       UdpChardev *s = UDP_CHARDEV(chr);
>>   
>> -    remove_fd_in_watch(chr, NULL);
>> +    remove_fd_in_watch(chr);
>>       if (s->ioc) {
>> -        chr->fd_in_tag = io_add_watch_poll(chr, s->ioc,
>> +        chr->chr_gsource = io_add_watch_poll(chr, s->ioc,
>>                                              udp_chr_read_poll,
>>                                              udp_chr_read, chr,
>>                                              context);
>> @@ -115,7 +115,7 @@ static void char_udp_finalize(Object *obj)
>>       Chardev *chr = CHARDEV(obj);
>>       UdpChardev *s = UDP_CHARDEV(obj);
>>   
>> -    remove_fd_in_watch(chr, NULL);
>> +    remove_fd_in_watch(chr);
>>       if (s->ioc) {
>>           object_unref(OBJECT(s->ioc));
>>       }
>> diff --git a/chardev/char.c b/chardev/char.c
>> index 3df1163..54cd5f4 100644
>> --- a/chardev/char.c
>> +++ b/chardev/char.c
>> @@ -560,7 +560,7 @@ void qemu_chr_fe_set_handlers(CharBackend *b,
>>       cc = CHARDEV_GET_CLASS(s);
>>       if (!opaque && !fd_can_read && !fd_read && !fd_event) {
>>           fe_open = 0;
>> -        remove_fd_in_watch(s, context);
>> +        remove_fd_in_watch(s);
>>       } else {
>>           fe_open = 1;
>>       }
>> diff --git a/include/sysemu/char.h b/include/sysemu/char.h
>> index 450881d..e157f96 100644
>> --- a/include/sysemu/char.h
>> +++ b/include/sysemu/char.h
>> @@ -93,7 +93,7 @@ struct Chardev {
>>       char *filename;
>>       int logfd;
>>       int be_open;
>> -    guint fd_in_tag;
>> +    GSource *chr_gsource;
>>       DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST);
>>       QTAILQ_ENTRY(Chardev) next;
>>   };
>> --
>> 1.8.3.1
>>
>>
>>
> .
>

  reply	other threads:[~2017-04-14 10:44 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-14  3:41 [Qemu-devel] [PATCH] char: Fix removing wrong GSource that be found by fd_in_tag zhanghailiang
2017-04-14 10:10 ` Marc-André Lureau
2017-04-14 10:43   ` Hailiang Zhang [this message]
2017-04-18 13:36   ` Eric Blake
2017-04-19  0:40     ` Hailiang Zhang

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=58F0A7CE.50501@huawei.com \
    --to=zhang.zhanghailiang@huawei.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=zhangchen.fnst@cn.fujitsu.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.