Patchwork [Bug,1181796] Re: Qemu locks up when incoming serial fills up

login
register
mail settings
Submitter Evan Green
Date May 22, 2013, 6:02 a.m.
Message ID <20130522060208.605.21539.malone@soybean.canonical.com>
Download mbox | patch
Permalink /patch/245548/
State New
Headers show

Comments

Evan Green - May 22, 2013, 6:02 a.m.
The following patch gets things moving again for me. It only reports
that the poll was satisfied if there was data that could be written to
the destination. While it successfully opens up a window where the I/O
thread is unlocked (previously there was no such window, hence the
hang), it's far from ideal.

Someone with more familiarity than me could consider an approach where
descriptors that have responded to the poll but are unable to be acted
on are temporarily disabled or removed from the list. This would allow
the main thread to quiet back down, rather than aggressively spinning
locking and unlocking the global mutex, which puts a drag on the VCPU
threads that need to acquire the same lock and do real work.

The line numbers here might not line up, but you get the idea.

Patch

--- qemu-char.c.orig2   2013-05-19 22:27:16 -0700
+++ qemu-char.c 2013-05-19 23:49:38 -0700
@@ -1650,6 +1650,7 @@ 

 static int win_chr_poll(void *opaque)
 {
+    int available;
     CharDriverState *chr = opaque;
     WinCharState *s = chr->opaque;
     COMSTAT status;
@@ -1658,9 +1659,9 @@ 
     ClearCommError(s->hcom, &comerr, &status);
     if (status.cbInQue > 0) {
         s->len = status.cbInQue;
-        win_chr_read_poll(chr);
+        available = win_chr_read_poll(chr);
         win_chr_read(chr);
-        return 1;
+        return available != 0;
     }
     return 0;
 }
@@ -1692,6 +1693,7 @@ 

 static int win_chr_pipe_poll(void *opaque)
 {
+    int available;
     CharDriverState *chr = opaque;
     WinCharState *s = chr->opaque;
     DWORD size;
@@ -1699,9 +1701,9 @@ 
     PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
     if (size > 0) {
         s->len = size;
-        win_chr_read_poll(chr);
+        available = win_chr_read_poll(chr);
         win_chr_read(chr);
-        return 1;
+        return available != 0;
     }
     return 0;
 }