diff mbox

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

Message ID 20130522060208.605.21539.malone@soybean.canonical.com
State New
Headers show

Commit Message

Evan Green May 22, 2013, 6:02 a.m. UTC
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.
diff mbox

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;
 }