summary refs log tree commit diff stats
path: root/net.c
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2012-09-17 10:20:48 -0500
committerAnthony Liguori <aliguori@us.ibm.com>2012-09-17 10:20:48 -0500
commitde71bd6f77739cc5addb6d70bf29be59aed41722 (patch)
tree83a53c6fa78028ffbcf4cb9413754d025ad8796b /net.c
parent31e165f1770cd10ee4fabf7ef4c1a48566be3336 (diff)
parent45a7f54a8bb3928ffa58d522e0d61acaee8277bb (diff)
downloadfocaccia-qemu-de71bd6f77739cc5addb6d70bf29be59aed41722.tar.gz
focaccia-qemu-de71bd6f77739cc5addb6d70bf29be59aed41722.zip
Merge remote-tracking branch 'stefanha/net' into staging
* stefanha/net:
  net: EAGAIN handling for net/socket.c TCP
  net: EAGAIN handling for net/socket.c UDP
  net: asynchronous send/receive infrastructure for net/socket.c
  net: broadcast hub packets if at least one port can receive
  net: fix usbnet_receive() packet drops
  net: clean up usbnet_receive()
  net: add -netdev options to man page
  net: do not report queued packets as sent
  net: add receive_disabled logic to iov delivery path
  eepro100: Fix network hang when rx buffers run out
  xen: flush queue when getting an event
  e1000: flush queue whenever can_receive can go from false to true
  net: notify iothread after flushing queue
Diffstat (limited to 'net.c')
-rw-r--r--net.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/net.c b/net.c
index e5d25d4b6d..a187a7b3db 100644
--- a/net.c
+++ b/net.c
@@ -357,7 +357,12 @@ void qemu_flush_queued_packets(NetClientState *nc)
 {
     nc->receive_disabled = 0;
 
-    qemu_net_queue_flush(nc->send_queue);
+    if (qemu_net_queue_flush(nc->send_queue)) {
+        /* We emptied the queue successfully, signal to the IO thread to repoll
+         * the file descriptor (for tap, for example).
+         */
+        qemu_notify_event();
+    }
 }
 
 static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
@@ -418,16 +423,27 @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
                                 void *opaque)
 {
     NetClientState *nc = opaque;
+    int ret;
 
     if (nc->link_down) {
         return iov_size(iov, iovcnt);
     }
 
+    if (nc->receive_disabled) {
+        return 0;
+    }
+
     if (nc->info->receive_iov) {
-        return nc->info->receive_iov(nc, iov, iovcnt);
+        ret = nc->info->receive_iov(nc, iov, iovcnt);
     } else {
-        return nc_sendv_compat(nc, iov, iovcnt);
+        ret = nc_sendv_compat(nc, iov, iovcnt);
     }
+
+    if (ret == 0) {
+        nc->receive_disabled = 1;
+    }
+
+    return ret;
 }
 
 ssize_t qemu_sendv_packet_async(NetClientState *sender,