All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Amit Shah <amit.shah@redhat.com>
Cc: aliguori@us.ibm.com, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v2] qemu-char: eliminate busy waiting on can_read returning zero
Date: Sun, 07 Apr 2013 20:49:16 +0200	[thread overview]
Message-ID: <5161BFAC.4030403@redhat.com> (raw)
In-Reply-To: <20130406190007.GA7249@amit.redhat.com>

Il 06/04/2013 21:00, Amit Shah ha scritto:
> On (Fri) 05 Apr 2013 [17:59:33], Paolo Bonzini wrote:
>> The character backend refactoring introduced an undesirable busy wait.
>> The busy wait happens if can_read returns zero and there is data available
>> on the character device's file descriptor.  Then, the I/O watch will
>> fire continuously and, with TCG, the CPU thread will never run.
>>
>>     1) Char backend asks front end if it can write
>>     2) Front end says no
>>     3) poll() finds the char backend's descriptor is available
>>     4) Goto (1)
>>
>> What we really want is this (note that step 3 avoids the busy wait):
>>
>>     1) Char backend asks front end if it can write
>>     2) Front end says no
>>     3) poll() goes on without char backend's descriptor
>>     4) Goto (1) until qemu_chr_accept_input() called
>>
>>     5) Char backend asks front end if it can write
>>     6) Front end says yes
>>     7) poll() finds the char backend's descriptor is available
>>     8) Backend handler called
>>
>> After this patch, the IOWatchPoll source and the watch source are
>> separated.  The IOWatchPoll is simply a hook that runs during the prepare
>> phase on each main loop iteration.  The hook adds/removes the actual
>> source depending on the return value from can_read.
>>
>> A simple reproducer is
>>
>>     qemu-system-i386 -serial mon:stdio
>>
>> ... followed by banging on the terminal as much as you can. :)  Without
>> this patch, emulation will hang.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>         v1->v2: use g_source_get_context to find if the watch was active
> 
>>  static gboolean io_watch_poll_prepare(GSource *source, gint *timeout_)
>>  {
>>      IOWatchPoll *iwp = io_watch_poll_from_source(source);
>> -
>> -    iwp->max_size = iwp->fd_can_read(iwp->opaque);
>> -    if (iwp->max_size == 0) {
>> +    bool now_active = iwp->fd_can_read(iwp->opaque) > 0;
>> +    bool was_active = g_source_get_context(iwp->src) != NULL;
> 
> This gives me a bunch of
> 
> (process:30075): GLib-CRITICAL **: g_source_get_context: assertion `!SOURCE_DESTROYED (source)' failed
> 
> messages

This should fix it, but unfortunately Peter reports it is not enough:

diff --git a/qemu-char.c b/qemu-char.c
index 85ebcf9..c2fb985 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -610,8 +610,14 @@ static IOWatchPoll
*io_watch_poll_from_source(GSource *source)
 static gboolean io_watch_poll_prepare(GSource *source, gint *timeout_)
 {
     IOWatchPoll *iwp = io_watch_poll_from_source(source);
-    bool was_active = g_source_get_context(iwp->src) != NULL;
-    bool now_active = iwp->fd_can_read(iwp->opaque) > 0;
+    bool was_active, now_active;
+
+    if (g_source_is_destroyed(iwp->src)) {
+        return FALSE;
+    }
+
+    was_active = g_source_get_context(iwp->src) != NULL;
+    now_active = iwp->fd_can_read(iwp->opaque) > 0;
     if (was_active == now_active) {
         return FALSE;
     }


I'm not sure what is different between the microblaze and x86 cases.
Peter, please send us reproduction instructions.

Paolo

  reply	other threads:[~2013-04-07 18:49 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-05 15:59 [Qemu-devel] [PATCH v2] qemu-char: eliminate busy waiting on can_read returning zero Paolo Bonzini
2013-04-06 19:00 ` Amit Shah
2013-04-07 18:49   ` Paolo Bonzini [this message]
2013-04-07 22:43     ` Peter Crosthwaite
2013-04-07  5:09 ` Peter Crosthwaite
2013-04-08 21:55 ` Anthony Liguori

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=5161BFAC.4030403@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=aliguori@us.ibm.com \
    --cc=amit.shah@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /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.