qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/13] Add generic packet buffering API
@ 2009-05-19  9:55 Mark McLoughlin
  2009-05-19  9:55 ` [Qemu-devel] [PATCH 01/13] net: factor tap_read_packet() out of tap_send() Mark McLoughlin
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-19  9:55 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel


Hi,
        This patch series works towards two[1] goals:

  1) Merging the code in qemu-kvm which drains the tap file descriptor
     when it is readable and buffers a packet if it fails to add it to
     the NIC receive queue

  2) Using the new TAP_SETSNDBUF ioctl() to put a limit on the number
     of in-flight packets allowed on a tap device; in this case, if a
     NIC pops a packet from its transmit queue, we need to be able to
     buffer said packet if the tap queue is full

        Rather than having each host backend and each NIC implement
packet buffering itself, the idea is to add extend the VLAN send queue
to do buffering.

        The API is fairly simple:

   - A qemu_send_packet() variant which takes a completion callback is
     added; if this returns zero, the sender should stop it's send
     queue until the completion callback is invoked

   - The VLANClientState receive() handler can now return zero,
     indicating that no space is available to receive the packet; when
     space becomes available later, the receiver must call
     qemu_flush_queued_packets() to re-queue any buffered packets
     which, in turn, will also cause the sender to re-start

        Note, these patches depend on two patches sent to the list by
Jan Kiszka:

  [PATCH 01/11] net: Don't deliver to disabled interfaces in qemu_sendv_packet
  [PATCH 02/11] net: Fix and improved ordered packet delivery

Cheers,
Mark.

[1] - Eagle-eyed readers will notice that I've neglected to actually
meet goal (2) with the patch set. Patience, patience :-)

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Qemu-devel] [PATCH 01/13] net: factor tap_read_packet() out of tap_send()
  2009-05-19  9:55 [Qemu-devel] [PATCH 0/13] Add generic packet buffering API Mark McLoughlin
@ 2009-05-19  9:55 ` Mark McLoughlin
  2009-05-19  9:55   ` [Qemu-devel] [PATCH 02/13] net: move the tap buffer into TAPState Mark McLoughlin
  2009-05-19 10:18 ` [Qemu-devel] [PATCH 0/13] Add generic packet buffering API Avi Kivity
  2009-05-22 13:43 ` [Qemu-devel] " Anthony Liguori
  2 siblings, 1 reply; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-19  9:55 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Mark McLoughlin, qemu-devel

Move portability clutter out into its own function.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 net.c |   28 +++++++++++++++++++---------
 1 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/net.c b/net.c
index 671138f..a819043 100644
--- a/net.c
+++ b/net.c
@@ -806,21 +806,31 @@ static void tap_receive(void *opaque, const uint8_t *buf, int size)
     }
 }
 
-static void tap_send(void *opaque)
-{
-    TAPState *s = opaque;
-    uint8_t buf[4096];
-    int size;
-
 #ifdef __sun__
+static ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)
+{
     struct strbuf sbuf;
     int f = 0;
-    sbuf.maxlen = sizeof(buf);
+
+    sbuf.maxlen = maxlen;
     sbuf.buf = (char *)buf;
-    size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
+
+    return getmsg(tapfd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
+}
 #else
-    size = read(s->fd, buf, sizeof(buf));
+static ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)
+{
+    return read(tapfd, buf, maxlen);
+}
 #endif
+
+static void tap_send(void *opaque)
+{
+    TAPState *s = opaque;
+    uint8_t buf[4096];
+    int size;
+
+    size = tap_read_packet(s->fd, buf, sizeof(buf));
     if (size > 0) {
         qemu_send_packet(s->vc, buf, size);
     }
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Qemu-devel] [PATCH 02/13] net: move the tap buffer into TAPState
  2009-05-19  9:55 ` [Qemu-devel] [PATCH 01/13] net: factor tap_read_packet() out of tap_send() Mark McLoughlin
@ 2009-05-19  9:55   ` Mark McLoughlin
  2009-05-19  9:55     ` [Qemu-devel] [PATCH 03/13] net: vlan clients with no fd_can_read() can always receive Mark McLoughlin
  0 siblings, 1 reply; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-19  9:55 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Mark McLoughlin, qemu-devel

KVM uses a 64k buffer for reading from tapfd (for GSO support)
and allocates the buffer with TAPState rather than on the stack.

Not allocating it on the stack probably makes sense for qemu
anyway, so merge it in advance of GSO support.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 net.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/net.c b/net.c
index a819043..3f9062f 100644
--- a/net.c
+++ b/net.c
@@ -776,6 +776,7 @@ typedef struct TAPState {
     int fd;
     char down_script[1024];
     char down_script_arg[128];
+    uint8_t buf[4096];
 } TAPState;
 
 static int launch_script(const char *setup_script, const char *ifname, int fd);
@@ -827,12 +828,11 @@ static ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)
 static void tap_send(void *opaque)
 {
     TAPState *s = opaque;
-    uint8_t buf[4096];
     int size;
 
-    size = tap_read_packet(s->fd, buf, sizeof(buf));
+    size = tap_read_packet(s->fd, s->buf, sizeof(s->buf));
     if (size > 0) {
-        qemu_send_packet(s->vc, buf, size);
+        qemu_send_packet(s->vc, s->buf, size);
     }
 }
 
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Qemu-devel] [PATCH 03/13] net: vlan clients with no fd_can_read() can always receive
  2009-05-19  9:55   ` [Qemu-devel] [PATCH 02/13] net: move the tap buffer into TAPState Mark McLoughlin
@ 2009-05-19  9:55     ` Mark McLoughlin
  2009-05-19  9:55       ` [Qemu-devel] [PATCH 04/13] net: only read from tapfd when we can send Mark McLoughlin
  0 siblings, 1 reply; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-19  9:55 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Mark McLoughlin, qemu-devel

If a vlan client has no fd_can_read(), that means it can
always receive packets. The current code assumes it can *never*
receive packets.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 net.c |   16 ++++++++++------
 1 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/net.c b/net.c
index 3f9062f..a3f4674 100644
--- a/net.c
+++ b/net.c
@@ -389,15 +389,19 @@ VLANClientState *qemu_find_vlan_client(VLANState *vlan, void *opaque)
     return NULL;
 }
 
-int qemu_can_send_packet(VLANClientState *vc1)
+int qemu_can_send_packet(VLANClientState *sender)
 {
-    VLANState *vlan = vc1->vlan;
+    VLANState *vlan = sender->vlan;
     VLANClientState *vc;
 
-    for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
-        if (vc != vc1) {
-            if (vc->fd_can_read && vc->fd_can_read(vc->opaque))
-                return 1;
+    for (vc = vlan->first_client; vc != NULL; vc = vc->next) {
+        if (vc == sender) {
+            continue;
+        }
+
+        /* no fd_can_read() handler, they can always receive */
+        if (!vc->fd_can_read || vc->fd_can_read(vc->opaque)) {
+            return 1;
         }
     }
     return 0;
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Qemu-devel] [PATCH 04/13] net: only read from tapfd when we can send
  2009-05-19  9:55     ` [Qemu-devel] [PATCH 03/13] net: vlan clients with no fd_can_read() can always receive Mark McLoughlin
@ 2009-05-19  9:55       ` Mark McLoughlin
  2009-05-19  9:55         ` [Qemu-devel] [PATCH 05/13] net: add fd_readv() handler to qemu_new_vlan_client() args Mark McLoughlin
  0 siblings, 1 reply; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-19  9:55 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Mark McLoughlin, qemu-devel

Reduce the number of packets dropped under heavy network
traffic by only reading a packet from the tapfd when a
client can actually handle it.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 net.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/net.c b/net.c
index a3f4674..b506ccb 100644
--- a/net.c
+++ b/net.c
@@ -811,6 +811,13 @@ static void tap_receive(void *opaque, const uint8_t *buf, int size)
     }
 }
 
+static int tap_can_send(void *opaque)
+{
+    TAPState *s = opaque;
+
+    return qemu_can_send_packet(s->vc);
+}
+
 #ifdef __sun__
 static ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)
 {
@@ -866,7 +873,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
     s->vc = qemu_new_vlan_client(vlan, model, name, tap_receive,
                                  NULL, tap_cleanup, s);
     s->vc->fd_readv = tap_receive_iov;
-    qemu_set_fd_handler(s->fd, tap_send, NULL, s);
+    qemu_set_fd_handler2(s->fd, tap_can_send, tap_send, NULL, s);
     snprintf(s->vc->info_str, sizeof(s->vc->info_str), "fd=%d", fd);
     return s;
 }
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Qemu-devel] [PATCH 05/13] net: add fd_readv() handler to qemu_new_vlan_client() args
  2009-05-19  9:55       ` [Qemu-devel] [PATCH 04/13] net: only read from tapfd when we can send Mark McLoughlin
@ 2009-05-19  9:55         ` Mark McLoughlin
  2009-05-19  9:55           ` [Qemu-devel] [PATCH 06/13] net: re-name vc->fd_read() to vc->receive() Mark McLoughlin
  0 siblings, 1 reply; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-19  9:55 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Mark McLoughlin, qemu-devel

This, apparently, is the style we prefer - all VLANClientState
should be an argument to qemu_new_vlan_client().

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 hw/dp8393x.c        |    4 ++--
 hw/e1000.c          |    4 ++--
 hw/eepro100.c       |    2 +-
 hw/etraxfs_eth.c    |    2 +-
 hw/mcf_fec.c        |    2 +-
 hw/mipsnet.c        |    2 +-
 hw/musicpal.c       |    2 +-
 hw/ne2000.c         |    4 ++--
 hw/pcnet.c          |    2 +-
 hw/qdev.c           |    7 ++++---
 hw/rtl8139.c        |    2 +-
 hw/smc91c111.c      |    2 +-
 hw/stellaris_enet.c |    2 +-
 hw/usb-net.c        |    3 ++-
 hw/virtio-net.c     |    2 +-
 hw/xen_nic.c        |    4 ++--
 net.c               |   21 +++++++++++----------
 net.h               |    6 ++++--
 tap-win32.c         |    2 +-
 19 files changed, 40 insertions(+), 35 deletions(-)

diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index 4418409..c5efb3c 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -888,8 +888,8 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift,
     s->watchdog = qemu_new_timer(vm_clock, dp8393x_watchdog, s);
     s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
 
-    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
-                                 nic_receive, nic_can_receive, nic_cleanup, s);
+    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, nic_can_receive,
+                                 nic_receive, NULL, nic_cleanup, s);
 
     qemu_format_nic_info_str(s->vc, nd->macaddr);
     qemu_register_reset(nic_reset, s);
diff --git a/hw/e1000.c b/hw/e1000.c
index c5eb546..fd13f64 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1099,8 +1099,8 @@ static void pci_e1000_init(PCIDevice *pci_dev)
     memset(&d->tx, 0, sizeof d->tx);
 
     d->vc = qdev_get_vlan_client(&d->dev.qdev,
-                                 e1000_receive, e1000_can_receive,
-                                 e1000_cleanup, d);
+                                 e1000_can_receive, e1000_receive,
+                                 NULL, e1000_cleanup, d);
     d->vc->link_status_changed = e1000_set_link_status;
 
     qemu_format_nic_info_str(d->vc, macaddr);
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 1689a3a..571ab94 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1766,7 +1766,7 @@ static void nic_init(PCIDevice *pci_dev, uint32_t device)
     nic_reset(s);
 
     s->vc = qdev_get_vlan_client(&d->dev.qdev,
-                                 nic_receive, nic_can_receive,
+                                 nic_can_receive, nic_receive, NULL,
                                  nic_cleanup, s);
 
     qemu_format_nic_info_str(s->vc, s->macaddr);
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 68b8de3..bb61284 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -593,7 +593,7 @@ void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
 	cpu_register_physical_memory (base, 0x5c, eth->ethregs);
 
 	eth->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
-				       eth_receive, eth_can_receive,
+				       eth_can_receive, eth_receive, NULL,
 				       eth_cleanup, eth);
 	eth->vc->opaque = eth;
 	eth->vc->link_status_changed = eth_set_link;
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index 6c0acc5..86b3aaf 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -462,7 +462,7 @@ void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, qemu_irq *irq)
     cpu_register_physical_memory(base, 0x400, s->mmio_index);
 
     s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
-                                 mcf_fec_receive, mcf_fec_can_receive,
+                                 mcf_fec_can_receive, mcf_fec_receive, NULL,
                                  mcf_fec_cleanup, s);
     memcpy(s->macaddr, nd->macaddr, 6);
     qemu_format_nic_info_str(s->vc, s->macaddr);
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index e842984..82a8c93 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -262,7 +262,7 @@ void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
     s->irq = irq;
     if (nd && nd->vlan) {
         s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
-                                     mipsnet_receive, mipsnet_can_receive,
+                                     mipsnet_can_receive, mipsnet_receive, NULL,
                                      mipsnet_cleanup, s);
     } else {
         s->vc = NULL;
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 87dda0c..f3c7f2c 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -753,7 +753,7 @@ static void mv88w8618_eth_init(SysBusDevice *dev)
 
     sysbus_init_irq(dev, &s->irq);
     s->vc = qdev_get_vlan_client(&dev->qdev,
-                                 eth_receive, eth_can_receive,
+                                 eth_can_receive, eth_receive, NULL,
                                  eth_cleanup, s);
     s->mmio_index = cpu_register_io_memory(0, mv88w8618_eth_readfn,
                                            mv88w8618_eth_writefn, s);
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 2af0d10..aea66b7 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -757,7 +757,7 @@ void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd)
     ne2000_reset(s);
 
     s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
-                                 ne2000_receive, ne2000_can_receive,
+                                 ne2000_can_receive, ne2000_receive, NULL,
                                  isa_ne2000_cleanup, s);
 
     qemu_format_nic_info_str(s->vc, s->macaddr);
@@ -821,7 +821,7 @@ static void pci_ne2000_init(PCIDevice *pci_dev)
     qdev_get_macaddr(&d->dev.qdev, s->macaddr);
     ne2000_reset(s);
     s->vc = qdev_get_vlan_client(&d->dev.qdev,
-                                 ne2000_receive, ne2000_can_receive,
+                                 ne2000_can_receive, ne2000_receive, NULL,
                                  ne2000_cleanup, s);
 
     qemu_format_nic_info_str(s->vc, s->macaddr);
diff --git a/hw/pcnet.c b/hw/pcnet.c
index 1f8e04b..848d21b 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -1952,7 +1952,7 @@ static void pcnet_common_init(DeviceState *dev, PCNetState *s,
 
     qdev_get_macaddr(dev, s->macaddr);
     s->vc = qdev_get_vlan_client(dev,
-                                 pcnet_receive, pcnet_can_receive,
+                                 pcnet_can_receive, pcnet_receive, NULL,
                                  cleanup, s);
     pcnet_h_reset(s);
     register_savevm("pcnet", -1, 2, pcnet_save, pcnet_load, s);
diff --git a/hw/qdev.c b/hw/qdev.c
index 9ed6f85..923a08e 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -233,15 +233,16 @@ void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
 }
 
 VLANClientState *qdev_get_vlan_client(DeviceState *dev,
-                                      IOReadHandler *fd_read,
                                       IOCanRWHandler *fd_can_read,
+                                      IOReadHandler *fd_read,
+                                      IOReadvHandler *fd_readv,
                                       NetCleanup *cleanup,
                                       void *opaque)
 {
     NICInfo *nd = dev->nd;
     assert(nd);
-    return qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
-                                fd_read, fd_can_read, cleanup, opaque);
+    return qemu_new_vlan_client(nd->vlan, nd->model, nd->name, fd_can_read,
+                                fd_read, fd_readv, cleanup, opaque);
 }
 
 
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index d99f35c..ab68bda 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3475,7 +3475,7 @@ static void pci_rtl8139_init(PCIDevice *dev)
     qdev_get_macaddr(&dev->qdev, s->macaddr);
     rtl8139_reset(s);
     s->vc = qdev_get_vlan_client(&dev->qdev,
-                                 rtl8139_receive, rtl8139_can_receive,
+                                 rtl8139_can_receive, rtl8139_receive, NULL,
                                  rtl8139_cleanup, s);
 
     qemu_format_nic_info_str(s->vc, s->macaddr);
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index 38cbd01..b20d535 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -711,7 +711,7 @@ static void smc91c111_init1(SysBusDevice *dev)
     smc91c111_reset(s);
 
     s->vc = qdev_get_vlan_client(&dev->qdev,
-                                 smc91c111_receive, smc91c111_can_receive,
+                                 smc91c111_can_receive, smc91c111_receive, NULL,
                                  smc91c111_cleanup, s);
     qemu_format_nic_info_str(s->vc, s->macaddr);
     /* ??? Save/restore.  */
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index 36fabd3..8b7df09 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -405,8 +405,8 @@ static void stellaris_enet_init(SysBusDevice *dev)
     qdev_get_macaddr(&dev->qdev, s->macaddr);
 
     s->vc = qdev_get_vlan_client(&dev->qdev,
-                                 stellaris_enet_receive,
                                  stellaris_enet_can_receive,
+                                 stellaris_enet_receive, NULL,
                                  stellaris_enet_cleanup, s);
     qemu_format_nic_info_str(s->vc, s->macaddr);
 
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 9e64425..fda0aa5 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1458,8 +1458,9 @@ USBDevice *usb_net_init(NICInfo *nd)
     pstrcpy(s->dev.devname, sizeof(s->dev.devname),
                     "QEMU USB Network Interface");
     s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
-                                 usbnet_receive,
                                  usbnet_can_receive,
+                                 usbnet_receive,
+                                 NULL,
                                  usbnet_cleanup, s);
 
     qemu_format_nic_info_str(s->vc, s->mac);
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 60aa6da..5613308 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -606,8 +606,8 @@ VirtIODevice *virtio_net_init(DeviceState *dev)
     qdev_get_macaddr(dev, n->mac);
     n->status = VIRTIO_NET_S_LINK_UP;
     n->vc = qdev_get_vlan_client(dev,
-                                 virtio_net_receive,
                                  virtio_net_can_receive,
+                                 virtio_net_receive, NULL,
                                  virtio_net_cleanup, n);
     n->vc->link_status_changed = virtio_net_set_link_status;
 
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index 2364e82..920b227 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -303,8 +303,8 @@ static int net_init(struct XenDevice *xendev)
 
     vlan = qemu_find_vlan(netdev->xendev.dev);
     netdev->vs = qemu_new_vlan_client(vlan, "xen", NULL,
-                                      net_rx_packet, net_rx_ok, NULL,
-                                      netdev);
+                                      net_rx_ok, net_rx_packet, NULL,
+                                      NULL, netdev);
     snprintf(netdev->vs->info_str, sizeof(netdev->vs->info_str),
              "nic: xenbus vif macaddr=%s", netdev->mac);
 
diff --git a/net.c b/net.c
index b506ccb..409205a 100644
--- a/net.c
+++ b/net.c
@@ -332,8 +332,9 @@ static char *assign_name(VLANClientState *vc1, const char *model)
 VLANClientState *qemu_new_vlan_client(VLANState *vlan,
                                       const char *model,
                                       const char *name,
-                                      IOReadHandler *fd_read,
                                       IOCanRWHandler *fd_can_read,
+                                      IOReadHandler *fd_read,
+                                      IOReadvHandler *fd_readv,
                                       NetCleanup *cleanup,
                                       void *opaque)
 {
@@ -344,8 +345,9 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
         vc->name = strdup(name);
     else
         vc->name = assign_name(vc, model);
-    vc->fd_read = fd_read;
     vc->fd_can_read = fd_can_read;
+    vc->fd_read = fd_read;
+    vc->fd_readv = fd_readv;
     vc->cleanup = cleanup;
     vc->opaque = opaque;
     vc->vlan = vlan;
@@ -592,7 +594,7 @@ static int net_slirp_init(VLANState *vlan, const char *model, const char *name)
         slirp_inited = 1;
         slirp_init(slirp_restrict, slirp_ip);
     }
-    slirp_vc = qemu_new_vlan_client(vlan, model, name,
+    slirp_vc = qemu_new_vlan_client(vlan, model, name, NULL,
                                     slirp_receive, NULL, net_slirp_cleanup, NULL);
     slirp_vc->info_str[0] = '\0';
     slirp_in_use = 1;
@@ -870,9 +872,8 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
 
     s = qemu_mallocz(sizeof(TAPState));
     s->fd = fd;
-    s->vc = qemu_new_vlan_client(vlan, model, name, tap_receive,
-                                 NULL, tap_cleanup, s);
-    s->vc->fd_readv = tap_receive_iov;
+    s->vc = qemu_new_vlan_client(vlan, model, name, NULL, tap_receive,
+                                 tap_receive_iov, tap_cleanup, s);
     qemu_set_fd_handler2(s->fd, tap_can_send, tap_send, NULL, s);
     snprintf(s->vc->info_str, sizeof(s->vc->info_str), "fd=%d", fd);
     return s;
@@ -1198,7 +1199,7 @@ static int net_vde_init(VLANState *vlan, const char *model,
         free(s);
         return -1;
     }
-    s->vc = qemu_new_vlan_client(vlan, model, name, vde_from_qemu,
+    s->vc = qemu_new_vlan_client(vlan, model, name, NULL, vde_from_qemu,
                                  NULL, vde_cleanup, s);
     qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
     snprintf(s->vc->info_str, sizeof(s->vc->info_str), "sock=%s,fd=%d",
@@ -1436,7 +1437,7 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
     s = qemu_mallocz(sizeof(NetSocketState));
     s->fd = fd;
 
-    s->vc = qemu_new_vlan_client(vlan, model, name, net_socket_receive_dgram,
+    s->vc = qemu_new_vlan_client(vlan, model, name, NULL, net_socket_receive_dgram,
                                  NULL, net_socket_cleanup, s);
     qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
 
@@ -1464,7 +1465,7 @@ static NetSocketState *net_socket_fd_init_stream(VLANState *vlan,
     NetSocketState *s;
     s = qemu_mallocz(sizeof(NetSocketState));
     s->fd = fd;
-    s->vc = qemu_new_vlan_client(vlan, model, name, net_socket_receive,
+    s->vc = qemu_new_vlan_client(vlan, model, name, NULL, net_socket_receive,
                                  NULL, net_socket_cleanup, s);
     snprintf(s->vc->info_str, sizeof(s->vc->info_str),
              "socket: fd=%d", fd);
@@ -1743,7 +1744,7 @@ static int net_dump_init(VLANState *vlan, const char *device,
         return -1;
     }
 
-    s->pcap_vc = qemu_new_vlan_client(vlan, device, name, dump_receive, NULL,
+    s->pcap_vc = qemu_new_vlan_client(vlan, device, name, NULL, dump_receive, NULL,
                                       net_dump_cleanup, s);
     snprintf(s->pcap_vc->info_str, sizeof(s->pcap_vc->info_str),
              "dump to %s (len=%d)", filename, len);
diff --git a/net.h b/net.h
index 41a3082..a312ee5 100644
--- a/net.h
+++ b/net.h
@@ -51,8 +51,9 @@ VLANState *qemu_find_vlan(int id);
 VLANClientState *qemu_new_vlan_client(VLANState *vlan,
                                       const char *model,
                                       const char *name,
-                                      IOReadHandler *fd_read,
                                       IOCanRWHandler *fd_can_read,
+                                      IOReadHandler *fd_read,
+                                      IOReadvHandler *fd_readv,
                                       NetCleanup *cleanup,
                                       void *opaque);
 void qemu_del_vlan_client(VLANClientState *vc);
@@ -129,8 +130,9 @@ void net_host_device_remove(Monitor *mon, int vlan_id, const char *device);
 
 void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr);
 VLANClientState *qdev_get_vlan_client(DeviceState *dev,
-                                      IOReadHandler *fd_read,
                                       IOCanRWHandler *fd_can_read,
+                                      IOReadHandler *fd_read,
+                                      IOReadvHandler *fd_readv,
                                       NetCleanup *cleanup,
                                       void *opaque);
 
diff --git a/tap-win32.c b/tap-win32.c
index 3ff957f..008158d 100644
--- a/tap-win32.c
+++ b/tap-win32.c
@@ -684,7 +684,7 @@ int tap_win32_init(VLANState *vlan, const char *model,
         return -1;
     }
 
-    s->vc = qemu_new_vlan_client(vlan, model, name, tap_receive,
+    s->vc = qemu_new_vlan_client(vlan, model, name, NULL, tap_receive,
                                  NULL, tap_cleanup, s);
 
     snprintf(s->vc->info_str, sizeof(s->vc->info_str),
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Qemu-devel] [PATCH 06/13] net: re-name vc->fd_read() to vc->receive()
  2009-05-19  9:55         ` [Qemu-devel] [PATCH 05/13] net: add fd_readv() handler to qemu_new_vlan_client() args Mark McLoughlin
@ 2009-05-19  9:55           ` Mark McLoughlin
  2009-05-19  9:55             ` [Qemu-devel] [PATCH 07/13] net: pass VLANClientState* as first arg to receive handlers Mark McLoughlin
  0 siblings, 1 reply; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-19  9:55 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Mark McLoughlin, qemu-devel

VLANClientState's fd_read() handler doesn't read from file
descriptors, it adds a buffer to the client's receive queue.

Re-name the handlers to make things a little less confusing.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 hw/dp8393x.c        |    4 ++--
 hw/e1000.c          |    6 +++---
 hw/eepro100.c       |    2 +-
 hw/etraxfs_eth.c    |    2 +-
 hw/mcf_fec.c        |    2 +-
 hw/mipsnet.c        |    2 +-
 hw/musicpal.c       |    2 +-
 hw/ne2000.c         |    2 +-
 hw/pcnet.c          |    2 +-
 hw/qdev.c           |   10 +++++-----
 hw/rtl8139.c        |    2 +-
 hw/smc91c111.c      |    2 +-
 hw/stellaris_enet.c |    2 +-
 hw/usb-net.c        |    2 +-
 hw/virtio-net.c     |    2 +-
 hw/xen_nic.c        |    6 +++---
 net.c               |   36 ++++++++++++++++++------------------
 net.h               |   23 ++++++++++++-----------
 savevm.c            |    2 +-
 tap-win32.c         |    2 +-
 20 files changed, 57 insertions(+), 56 deletions(-)

diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index c5efb3c..8327bfb 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -409,7 +409,7 @@ static void do_transmit_packets(dp8393xState *s)
             s->regs[SONIC_TCR] |= SONIC_TCR_CRSL;
             if (s->vc->fd_can_read(s)) {
                 s->loopback_packet = 1;
-                s->vc->fd_read(s, s->tx_buffer, tx_len);
+                s->vc->receive(s, s->tx_buffer, tx_len);
             }
         } else {
             /* Transmit packet */
@@ -725,7 +725,7 @@ static int receive_filter(dp8393xState *s, const uint8_t * buf, int size)
     return -1;
 }
 
-static void nic_receive(void *opaque, const uint8_t * buf, int size)
+static void nic_receive(void *opaque, const uint8_t * buf, size_t size)
 {
     uint16_t data[10];
     dp8393xState *s = opaque;
diff --git a/hw/e1000.c b/hw/e1000.c
index fd13f64..f6f03fe 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -593,7 +593,7 @@ e1000_can_receive(void *opaque)
 }
 
 static void
-e1000_receive(void *opaque, const uint8_t *buf, int size)
+e1000_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     E1000State *s = opaque;
     struct e1000_rx_desc desc;
@@ -607,8 +607,8 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
         return;
 
     if (size > s->rxbuf_size) {
-        DBGOUT(RX, "packet too large for buffers (%d > %d)\n", size,
-               s->rxbuf_size);
+        DBGOUT(RX, "packet too large for buffers (%lu > %d)\n",
+               (unsigned long)size, s->rxbuf_size);
         return;
     }
 
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 571ab94..28af318 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1441,7 +1441,7 @@ static int nic_can_receive(void *opaque)
     //~ return !eepro100_buffer_full(s);
 }
 
-static void nic_receive(void *opaque, const uint8_t * buf, int size)
+static void nic_receive(void *opaque, const uint8_t * buf, size_t size)
 {
     /* TODO:
      * - Magic packets should set bit 30 in power management driver register.
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index bb61284..2446f0d 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -501,7 +501,7 @@ static int eth_can_receive(void *opaque)
 	return 1;
 }
 
-static void eth_receive(void *opaque, const uint8_t *buf, int size)
+static void eth_receive(void *opaque, const uint8_t *buf, size_t size)
 {
 	unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 	struct fs_eth *eth = opaque;
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index 86b3aaf..0b0f17a 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -353,7 +353,7 @@ static int mcf_fec_can_receive(void *opaque)
     return s->rx_enabled;
 }
 
-static void mcf_fec_receive(void *opaque, const uint8_t *buf, int size)
+static void mcf_fec_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     mcf_fec_state *s = (mcf_fec_state *)opaque;
     mcf_fec_bd bd;
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index 82a8c93..a22f49a 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -75,7 +75,7 @@ static int mipsnet_can_receive(void *opaque)
     return !mipsnet_buffer_full(s);
 }
 
-static void mipsnet_receive(void *opaque, const uint8_t *buf, int size)
+static void mipsnet_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     MIPSnetState *s = opaque;
 
diff --git a/hw/musicpal.c b/hw/musicpal.c
index f3c7f2c..14258ec 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -562,7 +562,7 @@ static int eth_can_receive(void *opaque)
     return 1;
 }
 
-static void eth_receive(void *opaque, const uint8_t *buf, int size)
+static void eth_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     mv88w8618_eth_state *s = opaque;
     uint32_t desc_addr;
diff --git a/hw/ne2000.c b/hw/ne2000.c
index aea66b7..502c8ae 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -224,7 +224,7 @@ static int ne2000_can_receive(void *opaque)
 
 #define MIN_BUF_SIZE 60
 
-static void ne2000_receive(void *opaque, const uint8_t *buf, int size)
+static void ne2000_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     NE2000State *s = opaque;
     uint8_t *p;
diff --git a/hw/pcnet.c b/hw/pcnet.c
index 848d21b..ad4ee33 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -1076,7 +1076,7 @@ static int pcnet_can_receive(void *opaque)
 
 #define MIN_BUF_SIZE 60
 
-static void pcnet_receive(void *opaque, const uint8_t *buf, int size)
+static void pcnet_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     PCNetState *s = opaque;
     int is_padr = 0, is_bcast = 0, is_ladr = 0;
diff --git a/hw/qdev.c b/hw/qdev.c
index 923a08e..14b98f0 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -233,16 +233,16 @@ void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
 }
 
 VLANClientState *qdev_get_vlan_client(DeviceState *dev,
-                                      IOCanRWHandler *fd_can_read,
-                                      IOReadHandler *fd_read,
-                                      IOReadvHandler *fd_readv,
+                                      NetCanReceive *can_receive,
+                                      NetReceive *receive,
+                                      NetReceiveIOV *receive_iov,
                                       NetCleanup *cleanup,
                                       void *opaque)
 {
     NICInfo *nd = dev->nd;
     assert(nd);
-    return qemu_new_vlan_client(nd->vlan, nd->model, nd->name, fd_can_read,
-                                fd_read, fd_readv, cleanup, opaque);
+    return qemu_new_vlan_client(nd->vlan, nd->model, nd->name, can_receive,
+                                receive, receive_iov, cleanup, opaque);
 }
 
 
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index ab68bda..14119d4 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -1158,7 +1158,7 @@ static void rtl8139_do_receive(void *opaque, const uint8_t *buf, int size, int d
     }
 }
 
-static void rtl8139_receive(void *opaque, const uint8_t *buf, int size)
+static void rtl8139_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     rtl8139_do_receive(opaque, buf, size, 1);
 }
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index b20d535..6d1fbb3 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -602,7 +602,7 @@ static int smc91c111_can_receive(void *opaque)
     return 1;
 }
 
-static void smc91c111_receive(void *opaque, const uint8_t *buf, int size)
+static void smc91c111_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     smc91c111_state *s = (smc91c111_state *)opaque;
     int status;
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index 8b7df09..3ee9a88 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -78,7 +78,7 @@ static void stellaris_enet_update(stellaris_enet_state *s)
 }
 
 /* TODO: Implement MAC address filtering.  */
-static void stellaris_enet_receive(void *opaque, const uint8_t *buf, int size)
+static void stellaris_enet_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     stellaris_enet_state *s = (stellaris_enet_state *)opaque;
     int n;
diff --git a/hw/usb-net.c b/hw/usb-net.c
index fda0aa5..693e976 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1369,7 +1369,7 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p)
     return ret;
 }
 
-static void usbnet_receive(void *opaque, const uint8_t *buf, int size)
+static void usbnet_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     USBNetState *s = opaque;
     struct rndis_packet_msg_type *msg;
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 5613308..3ca93f5 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -361,7 +361,7 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
     return 0;
 }
 
-static void virtio_net_receive(void *opaque, const uint8_t *buf, int size)
+static void virtio_net_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     VirtIONet *n = opaque;
     struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL;
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index 920b227..a33d163 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -245,7 +245,7 @@ static int net_rx_ok(void *opaque)
     return 1;
 }
 
-static void net_rx_packet(void *opaque, const uint8_t *buf, int size)
+static void net_rx_packet(void *opaque, const uint8_t *buf, size_t size)
 {
     struct XenNetDev *netdev = opaque;
     netif_rx_request_t rxreq;
@@ -264,8 +264,8 @@ static void net_rx_packet(void *opaque, const uint8_t *buf, int size)
 	return;
     }
     if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
-	xen_be_printf(&netdev->xendev, 0, "packet too big (%d > %ld)",
-		      size, XC_PAGE_SIZE - NET_IP_ALIGN);
+	xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
+		      (unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
 	return;
     }
 
diff --git a/net.c b/net.c
index 409205a..ce1bbbf 100644
--- a/net.c
+++ b/net.c
@@ -332,9 +332,9 @@ static char *assign_name(VLANClientState *vc1, const char *model)
 VLANClientState *qemu_new_vlan_client(VLANState *vlan,
                                       const char *model,
                                       const char *name,
-                                      IOCanRWHandler *fd_can_read,
-                                      IOReadHandler *fd_read,
-                                      IOReadvHandler *fd_readv,
+                                      NetCanReceive *can_receive,
+                                      NetReceive *receive,
+                                      NetReceiveIOV *receive_iov,
                                       NetCleanup *cleanup,
                                       void *opaque)
 {
@@ -345,9 +345,9 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
         vc->name = strdup(name);
     else
         vc->name = assign_name(vc, model);
-    vc->fd_can_read = fd_can_read;
-    vc->fd_read = fd_read;
-    vc->fd_readv = fd_readv;
+    vc->can_receive = can_receive;
+    vc->receive = receive;
+    vc->receive_iov = receive_iov;
     vc->cleanup = cleanup;
     vc->opaque = opaque;
     vc->vlan = vlan;
@@ -401,8 +401,8 @@ int qemu_can_send_packet(VLANClientState *sender)
             continue;
         }
 
-        /* no fd_can_read() handler, they can always receive */
-        if (!vc->fd_can_read || vc->fd_can_read(vc->opaque)) {
+        /* no can_receive() handler, they can always receive */
+        if (!vc->can_receive || vc->can_receive(vc->opaque)) {
             return 1;
         }
     }
@@ -416,7 +416,7 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
 
     for (vc = sender->vlan->first_client; vc != NULL; vc = vc->next) {
         if (vc != sender && !vc->link_down) {
-            vc->fd_read(vc->opaque, buf, size);
+            vc->receive(vc->opaque, buf, size);
         }
     }
 }
@@ -467,7 +467,7 @@ static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
         offset += len;
     }
 
-    vc->fd_read(vc->opaque, buffer, offset);
+    vc->receive(vc->opaque, buffer, offset);
 
     return offset;
 }
@@ -519,9 +519,9 @@ ssize_t qemu_sendv_packet(VLANClientState *sender, const struct iovec *iov,
             }
             if (vc->link_down) {
                 len = calc_iov_length(iov, iovcnt);
-            } else if (vc->fd_readv) {
-                len = vc->fd_readv(vc->opaque, iov, iovcnt);
-            } else if (vc->fd_read) {
+            } else if (vc->receive_iov) {
+                len = vc->receive_iov(vc->opaque, iov, iovcnt);
+            } else if (vc->receive) {
                 len = vc_sendv_compat(vc, iov, iovcnt);
             }
             max_len = MAX(max_len, len);
@@ -568,7 +568,7 @@ int slirp_is_inited(void)
     return slirp_inited;
 }
 
-static void slirp_receive(void *opaque, const uint8_t *buf, int size)
+static void slirp_receive(void *opaque, const uint8_t *buf, size_t size)
 {
 #ifdef DEBUG_SLIRP
     printf("slirp input:\n");
@@ -800,7 +800,7 @@ static ssize_t tap_receive_iov(void *opaque, const struct iovec *iov,
     return len;
 }
 
-static void tap_receive(void *opaque, const uint8_t *buf, int size)
+static void tap_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     TAPState *s = opaque;
     int ret;
@@ -1227,7 +1227,7 @@ typedef struct NetSocketListenState {
 } NetSocketListenState;
 
 /* XXX: we consider we can send the whole packet without blocking */
-static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
+static void net_socket_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     NetSocketState *s = opaque;
     uint32_t len;
@@ -1237,7 +1237,7 @@ static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
     send_all(s->fd, buf, size);
 }
 
-static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
+static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, size_t size)
 {
     NetSocketState *s = opaque;
     sendto(s->fd, buf, size, 0,
@@ -1678,7 +1678,7 @@ struct pcap_sf_pkthdr {
     uint32_t len;
 };
 
-static void dump_receive(void *opaque, const uint8_t *buf, int size)
+static void dump_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     DumpState *s = opaque;
     struct pcap_sf_pkthdr hdr;
diff --git a/net.h b/net.h
index a312ee5..d99dc39 100644
--- a/net.h
+++ b/net.h
@@ -5,19 +5,20 @@
 
 /* VLANs support */
 
-typedef ssize_t (IOReadvHandler)(void *, const struct iovec *, int);
-
 typedef struct VLANClientState VLANClientState;
 
+typedef int (NetCanReceive)(void *);
+typedef void (NetReceive)(void *, const uint8_t *, size_t);
+typedef ssize_t (NetReceiveIOV)(void *, const struct iovec *, int);
 typedef void (NetCleanup) (VLANClientState *);
 typedef void (LinkStatusChanged)(VLANClientState *);
 
 struct VLANClientState {
-    IOReadHandler *fd_read;
-    IOReadvHandler *fd_readv;
+    NetReceive *receive;
+    NetReceiveIOV *receive_iov;
     /* Packets may still be sent if this returns zero.  It's used to
        rate-limit the slirp code.  */
-    IOCanRWHandler *fd_can_read;
+    NetCanReceive *can_receive;
     NetCleanup *cleanup;
     LinkStatusChanged *link_status_changed;
     int link_down;
@@ -51,9 +52,9 @@ VLANState *qemu_find_vlan(int id);
 VLANClientState *qemu_new_vlan_client(VLANState *vlan,
                                       const char *model,
                                       const char *name,
-                                      IOCanRWHandler *fd_can_read,
-                                      IOReadHandler *fd_read,
-                                      IOReadvHandler *fd_readv,
+                                      NetCanReceive *can_receive,
+                                      NetReceive *receive,
+                                      NetReceiveIOV *receive_iov,
                                       NetCleanup *cleanup,
                                       void *opaque);
 void qemu_del_vlan_client(VLANClientState *vc);
@@ -130,9 +131,9 @@ void net_host_device_remove(Monitor *mon, int vlan_id, const char *device);
 
 void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr);
 VLANClientState *qdev_get_vlan_client(DeviceState *dev,
-                                      IOCanRWHandler *fd_can_read,
-                                      IOReadHandler *fd_read,
-                                      IOReadvHandler *fd_readv,
+                                      NetCanReceive *can_receive,
+                                      NetReceive *receive,
+                                      NetReceiveIOV *receive_iov,
                                       NetCleanup *cleanup,
                                       void *opaque);
 
diff --git a/savevm.c b/savevm.c
index 8b7909a..f19aa60 100644
--- a/savevm.c
+++ b/savevm.c
@@ -129,7 +129,7 @@ void qemu_announce_self(void)
         vlan = nd_table[i].vlan;
         for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
             for (j=0; j < SELF_ANNOUNCE_ROUNDS; j++)
-                vc->fd_read(vc->opaque, buf, len);
+                vc->receive(vc->opaque, buf, len);
         }
     }
 }
diff --git a/tap-win32.c b/tap-win32.c
index 008158d..ccf7e45 100644
--- a/tap-win32.c
+++ b/tap-win32.c
@@ -650,7 +650,7 @@ static void tap_cleanup(VLANClientState *vc)
     qemu_free(s);
 }
 
-static void tap_receive(void *opaque, const uint8_t *buf, int size)
+static void tap_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     TAPState *s = opaque;
 
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Qemu-devel] [PATCH 07/13] net: pass VLANClientState* as first arg to receive handlers
  2009-05-19  9:55           ` [Qemu-devel] [PATCH 06/13] net: re-name vc->fd_read() to vc->receive() Mark McLoughlin
@ 2009-05-19  9:55             ` Mark McLoughlin
  2009-05-19  9:55               ` [Qemu-devel] [PATCH 08/13] net: add return value to packet receive handler Mark McLoughlin
  0 siblings, 1 reply; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-19  9:55 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Mark McLoughlin, qemu-devel

Give static type checking a chance to catch errors.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 hw/dp8393x.c        |   12 ++++++------
 hw/e1000.c          |    8 ++++----
 hw/eepro100.c       |    8 ++++----
 hw/etraxfs_eth.c    |    6 +++---
 hw/mcf_fec.c        |    8 ++++----
 hw/mipsnet.c        |   10 +++++-----
 hw/musicpal.c       |    6 +++---
 hw/ne2000.c         |    8 ++++----
 hw/pcnet.c          |   10 +++++-----
 hw/rtl8139.c        |   14 +++++++-------
 hw/smc91c111.c      |    8 ++++----
 hw/stellaris_enet.c |   12 ++++++------
 hw/usb-net.c        |    8 ++++----
 hw/virtio-net.c     |    8 ++++----
 hw/xen_nic.c        |    8 ++++----
 net.c               |   36 ++++++++++++++++++------------------
 net.h               |    6 +++---
 savevm.c            |    2 +-
 tap-win32.c         |    2 +-
 19 files changed, 90 insertions(+), 90 deletions(-)

diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index 8327bfb..91850bc 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -407,9 +407,9 @@ static void do_transmit_packets(dp8393xState *s)
         if (s->regs[SONIC_RCR] & (SONIC_RCR_LB1 | SONIC_RCR_LB0)) {
             /* Loopback */
             s->regs[SONIC_TCR] |= SONIC_TCR_CRSL;
-            if (s->vc->fd_can_read(s)) {
+            if (s->vc->can_receive(s->vc)) {
                 s->loopback_packet = 1;
-                s->vc->receive(s, s->tx_buffer, tx_len);
+                s->vc->receive(s->vc, s->tx_buffer, tx_len);
             }
         } else {
             /* Transmit packet */
@@ -676,9 +676,9 @@ static CPUWriteMemoryFunc *dp8393x_write[3] = {
     dp8393x_writel,
 };
 
-static int nic_can_receive(void *opaque)
+static int nic_can_receive(VLANClientState *vc)
 {
-    dp8393xState *s = opaque;
+    dp8393xState *s = vc->opaque;
 
     if (!(s->regs[SONIC_CR] & SONIC_CR_RXEN))
         return 0;
@@ -725,10 +725,10 @@ static int receive_filter(dp8393xState *s, const uint8_t * buf, int size)
     return -1;
 }
 
-static void nic_receive(void *opaque, const uint8_t * buf, size_t size)
+static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
 {
     uint16_t data[10];
-    dp8393xState *s = opaque;
+    dp8393xState *s = vc->opaque;
     int packet_type;
     uint32_t available, address;
     int width, rx_len = size;
diff --git a/hw/e1000.c b/hw/e1000.c
index f6f03fe..689c48e 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -585,17 +585,17 @@ e1000_set_link_status(VLANClientState *vc)
 }
 
 static int
-e1000_can_receive(void *opaque)
+e1000_can_receive(VLANClientState *vc)
 {
-    E1000State *s = opaque;
+    E1000State *s = vc->opaque;
 
     return (s->mac_reg[RCTL] & E1000_RCTL_EN);
 }
 
 static void
-e1000_receive(void *opaque, const uint8_t *buf, size_t size)
+e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    E1000State *s = opaque;
+    E1000State *s = vc->opaque;
     struct e1000_rx_desc desc;
     target_phys_addr_t base;
     unsigned int n, rdt;
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 28af318..ef977a9 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1433,21 +1433,21 @@ static void pci_mmio_map(PCIDevice * pci_dev, int region_num,
     }
 }
 
-static int nic_can_receive(void *opaque)
+static int nic_can_receive(VLANClientState *vc)
 {
-    EEPRO100State *s = opaque;
+    EEPRO100State *s = vc->opaque;
     logout("%p\n", s);
     return get_ru_state(s) == ru_ready;
     //~ return !eepro100_buffer_full(s);
 }
 
-static void nic_receive(void *opaque, const uint8_t * buf, size_t size)
+static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
 {
     /* TODO:
      * - Magic packets should set bit 30 in power management driver register.
      * - Interesting packets should set bit 29 in power management driver register.
      */
-    EEPRO100State *s = opaque;
+    EEPRO100State *s = vc->opaque;
     uint16_t rfd_status = 0xa000;
     static const uint8_t broadcast_macaddr[6] =
         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 2446f0d..78af76b 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -496,15 +496,15 @@ static int eth_match_groupaddr(struct fs_eth *eth, const unsigned char *sa)
 	return match;
 }
 
-static int eth_can_receive(void *opaque)
+static int eth_can_receive(VLANClientState *vc)
 {
 	return 1;
 }
 
-static void eth_receive(void *opaque, const uint8_t *buf, size_t size)
+static void eth_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
 	unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-	struct fs_eth *eth = opaque;
+	struct fs_eth *eth = vc->opaque;
 	int use_ma0 = eth->regs[RW_REC_CTRL] & 1;
 	int use_ma1 = eth->regs[RW_REC_CTRL] & 2;
 	int r_bcast = eth->regs[RW_REC_CTRL] & 8;
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index 0b0f17a..d2534d0 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -347,15 +347,15 @@ static void mcf_fec_write(void *opaque, target_phys_addr_t addr, uint32_t value)
     mcf_fec_update(s);
 }
 
-static int mcf_fec_can_receive(void *opaque)
+static int mcf_fec_can_receive(VLANClientState *vc)
 {
-    mcf_fec_state *s = (mcf_fec_state *)opaque;
+    mcf_fec_state *s = vc->opaque;
     return s->rx_enabled;
 }
 
-static void mcf_fec_receive(void *opaque, const uint8_t *buf, size_t size)
+static void mcf_fec_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    mcf_fec_state *s = (mcf_fec_state *)opaque;
+    mcf_fec_state *s = vc->opaque;
     mcf_fec_bd bd;
     uint32_t flags = 0;
     uint32_t addr;
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index a22f49a..e9128cb 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -66,23 +66,23 @@ static int mipsnet_buffer_full(MIPSnetState *s)
     return 0;
 }
 
-static int mipsnet_can_receive(void *opaque)
+static int mipsnet_can_receive(VLANClientState *vc)
 {
-    MIPSnetState *s = opaque;
+    MIPSnetState *s = vc->opaque;
 
     if (s->busy)
         return 0;
     return !mipsnet_buffer_full(s);
 }
 
-static void mipsnet_receive(void *opaque, const uint8_t *buf, size_t size)
+static void mipsnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    MIPSnetState *s = opaque;
+    MIPSnetState *s = vc->opaque;
 
 #ifdef DEBUG_MIPSNET_RECEIVE
     printf("mipsnet: receiving len=%d\n", size);
 #endif
-    if (!mipsnet_can_receive(opaque))
+    if (!mipsnet_can_receive(vc))
         return;
 
     s->busy = 1;
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 14258ec..943dc6f 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -557,14 +557,14 @@ static void eth_rx_desc_get(uint32_t addr, mv88w8618_rx_desc *desc)
     le32_to_cpus(&desc->next);
 }
 
-static int eth_can_receive(void *opaque)
+static int eth_can_receive(VLANClientState *vc)
 {
     return 1;
 }
 
-static void eth_receive(void *opaque, const uint8_t *buf, size_t size)
+static void eth_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    mv88w8618_eth_state *s = opaque;
+    mv88w8618_eth_state *s = vc->opaque;
     uint32_t desc_addr;
     mv88w8618_rx_desc desc;
     int i;
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 502c8ae..c0fc34c 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -213,9 +213,9 @@ static int ne2000_buffer_full(NE2000State *s)
     return 0;
 }
 
-static int ne2000_can_receive(void *opaque)
+static int ne2000_can_receive(VLANClientState *vc)
 {
-    NE2000State *s = opaque;
+    NE2000State *s = vc->opaque;
 
     if (s->cmd & E8390_STOP)
         return 1;
@@ -224,9 +224,9 @@ static int ne2000_can_receive(void *opaque)
 
 #define MIN_BUF_SIZE 60
 
-static void ne2000_receive(void *opaque, const uint8_t *buf, size_t size)
+static void ne2000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    NE2000State *s = opaque;
+    NE2000State *s = vc->opaque;
     uint8_t *p;
     unsigned int total_len, next, avail, len, index, mcast_idx;
     uint8_t buf1[60];
diff --git a/hw/pcnet.c b/hw/pcnet.c
index ad4ee33..1ab731c 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -1062,9 +1062,9 @@ static int pcnet_tdte_poll(PCNetState *s)
     return !!(CSR_CXST(s) & 0x8000);
 }
 
-static int pcnet_can_receive(void *opaque)
+static int pcnet_can_receive(VLANClientState *vc)
 {
-    PCNetState *s = opaque;
+    PCNetState *s = vc->opaque;
     if (CSR_STOP(s) || CSR_SPND(s))
         return 0;
 
@@ -1076,9 +1076,9 @@ static int pcnet_can_receive(void *opaque)
 
 #define MIN_BUF_SIZE 60
 
-static void pcnet_receive(void *opaque, const uint8_t *buf, size_t size)
+static void pcnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    PCNetState *s = opaque;
+    PCNetState *s = vc->opaque;
     int is_padr = 0, is_bcast = 0, is_ladr = 0;
     uint8_t buf1[60];
     int remaining;
@@ -1302,7 +1302,7 @@ static void pcnet_transmit(PCNetState *s)
                 if (BCR_SWSTYLE(s) == 1)
                     add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
                 s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
-                pcnet_receive(s, s->buffer, s->xmit_pos);
+                pcnet_receive(s->vc, s->buffer, s->xmit_pos);
                 s->looptest = 0;
             } else
                 if (s->vc)
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 14119d4..8626d5e 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -790,9 +790,9 @@ static inline target_phys_addr_t rtl8139_addr64(uint32_t low, uint32_t high)
 #endif
 }
 
-static int rtl8139_can_receive(void *opaque)
+static int rtl8139_can_receive(VLANClientState *vc)
 {
-    RTL8139State *s = opaque;
+    RTL8139State *s = vc->opaque;
     int avail;
 
     /* Receive (drop) packets if card is disabled.  */
@@ -812,9 +812,9 @@ static int rtl8139_can_receive(void *opaque)
     }
 }
 
-static void rtl8139_do_receive(void *opaque, const uint8_t *buf, int size, int do_interrupt)
+static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size, int do_interrupt)
 {
-    RTL8139State *s = opaque;
+    RTL8139State *s = vc->opaque;
 
     uint32_t packet_header = 0;
 
@@ -1158,9 +1158,9 @@ static void rtl8139_do_receive(void *opaque, const uint8_t *buf, int size, int d
     }
 }
 
-static void rtl8139_receive(void *opaque, const uint8_t *buf, size_t size)
+static void rtl8139_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    rtl8139_do_receive(opaque, buf, size, 1);
+    rtl8139_do_receive(vc, buf, size, 1);
 }
 
 static void rtl8139_reset_rxring(RTL8139State *s, uint32_t bufferSize)
@@ -1757,7 +1757,7 @@ static void rtl8139_transfer_frame(RTL8139State *s, const uint8_t *buf, int size
     if (TxLoopBack == (s->TxConfig & TxLoopBack))
     {
         DEBUG_PRINT(("RTL8139: +++ transmit loopback mode\n"));
-        rtl8139_do_receive(s, buf, size, do_interrupt);
+        rtl8139_do_receive(s->vc, buf, size, do_interrupt);
     }
     else
     {
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index 6d1fbb3..383f0b7 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -591,9 +591,9 @@ static uint32_t smc91c111_readl(void *opaque, target_phys_addr_t offset)
     return val;
 }
 
-static int smc91c111_can_receive(void *opaque)
+static int smc91c111_can_receive(VLANClientState *vc)
 {
-    smc91c111_state *s = (smc91c111_state *)opaque;
+    smc91c111_state *s = vc->opaque;
 
     if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
         return 1;
@@ -602,9 +602,9 @@ static int smc91c111_can_receive(void *opaque)
     return 1;
 }
 
-static void smc91c111_receive(void *opaque, const uint8_t *buf, size_t size)
+static void smc91c111_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    smc91c111_state *s = (smc91c111_state *)opaque;
+    smc91c111_state *s = vc->opaque;
     int status;
     int packetsize;
     uint32_t crc;
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index 3ee9a88..7f30829 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -78,9 +78,9 @@ static void stellaris_enet_update(stellaris_enet_state *s)
 }
 
 /* TODO: Implement MAC address filtering.  */
-static void stellaris_enet_receive(void *opaque, const uint8_t *buf, size_t size)
+static void stellaris_enet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    stellaris_enet_state *s = (stellaris_enet_state *)opaque;
+    stellaris_enet_state *s = vc->opaque;
     int n;
     uint8_t *p;
     uint32_t crc;
@@ -118,9 +118,9 @@ static void stellaris_enet_receive(void *opaque, const uint8_t *buf, size_t size
     stellaris_enet_update(s);
 }
 
-static int stellaris_enet_can_receive(void *opaque)
+static int stellaris_enet_can_receive(VLANClientState *vc)
 {
-    stellaris_enet_state *s = (stellaris_enet_state *)opaque;
+    stellaris_enet_state *s = vc->opaque;
 
     if ((s->rctl & SE_RCTL_RXEN) == 0)
         return 1;
@@ -128,9 +128,9 @@ static int stellaris_enet_can_receive(void *opaque)
     return (s->np < 31);
 }
 
-static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset)
+static uint32_t stellaris_enet_read(VLANClientState *vc, target_phys_addr_t offset)
 {
-    stellaris_enet_state *s = (stellaris_enet_state *)opaque;
+    stellaris_enet_state *s = vc->opaque;
     uint32_t val;
 
     switch (offset) {
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 693e976..d8d5e77 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1369,9 +1369,9 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p)
     return ret;
 }
 
-static void usbnet_receive(void *opaque, const uint8_t *buf, size_t size)
+static void usbnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    USBNetState *s = opaque;
+    USBNetState *s = vc->opaque;
     struct rndis_packet_msg_type *msg;
 
     if (s->rndis) {
@@ -1405,9 +1405,9 @@ static void usbnet_receive(void *opaque, const uint8_t *buf, size_t size)
     s->in_ptr = 0;
 }
 
-static int usbnet_can_receive(void *opaque)
+static int usbnet_can_receive(VLANClientState *vc)
 {
-    USBNetState *s = opaque;
+    USBNetState *s = vc->opaque;
 
     if (s->rndis && !s->rndis_state == RNDIS_DATA_INITIALIZED)
         return 1;
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 3ca93f5..1ffebac 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -288,9 +288,9 @@ static int do_virtio_net_can_receive(VirtIONet *n, int bufsize)
     return 1;
 }
 
-static int virtio_net_can_receive(void *opaque)
+static int virtio_net_can_receive(VLANClientState *vc)
 {
-    VirtIONet *n = opaque;
+    VirtIONet *n = vc->opaque;
 
     return do_virtio_net_can_receive(n, VIRTIO_NET_MAX_BUFSIZE);
 }
@@ -361,9 +361,9 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
     return 0;
 }
 
-static void virtio_net_receive(void *opaque, const uint8_t *buf, size_t size)
+static void virtio_net_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    VirtIONet *n = opaque;
+    VirtIONet *n = vc->opaque;
     struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL;
     size_t hdr_len, offset, i;
 
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index a33d163..d2d5a4b 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -225,9 +225,9 @@ static void net_rx_response(struct XenNetDev *netdev,
 
 #define NET_IP_ALIGN 2
 
-static int net_rx_ok(void *opaque)
+static int net_rx_ok(VLANClientState *vc)
 {
-    struct XenNetDev *netdev = opaque;
+    struct XenNetDev *netdev = vc->opaque;
     RING_IDX rc, rp;
 
     if (netdev->xendev.be_state != XenbusStateConnected)
@@ -245,9 +245,9 @@ static int net_rx_ok(void *opaque)
     return 1;
 }
 
-static void net_rx_packet(void *opaque, const uint8_t *buf, size_t size)
+static void net_rx_packet(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    struct XenNetDev *netdev = opaque;
+    struct XenNetDev *netdev = vc->opaque;
     netif_rx_request_t rxreq;
     RING_IDX rc, rp;
     void *page;
diff --git a/net.c b/net.c
index ce1bbbf..a3af42d 100644
--- a/net.c
+++ b/net.c
@@ -402,7 +402,7 @@ int qemu_can_send_packet(VLANClientState *sender)
         }
 
         /* no can_receive() handler, they can always receive */
-        if (!vc->can_receive || vc->can_receive(vc->opaque)) {
+        if (!vc->can_receive || vc->can_receive(vc)) {
             return 1;
         }
     }
@@ -416,7 +416,7 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
 
     for (vc = sender->vlan->first_client; vc != NULL; vc = vc->next) {
         if (vc != sender && !vc->link_down) {
-            vc->receive(vc->opaque, buf, size);
+            vc->receive(vc, buf, size);
         }
     }
 }
@@ -467,7 +467,7 @@ static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
         offset += len;
     }
 
-    vc->receive(vc->opaque, buffer, offset);
+    vc->receive(vc, buffer, offset);
 
     return offset;
 }
@@ -520,7 +520,7 @@ ssize_t qemu_sendv_packet(VLANClientState *sender, const struct iovec *iov,
             if (vc->link_down) {
                 len = calc_iov_length(iov, iovcnt);
             } else if (vc->receive_iov) {
-                len = vc->receive_iov(vc->opaque, iov, iovcnt);
+                len = vc->receive_iov(vc, iov, iovcnt);
             } else if (vc->receive) {
                 len = vc_sendv_compat(vc, iov, iovcnt);
             }
@@ -568,7 +568,7 @@ int slirp_is_inited(void)
     return slirp_inited;
 }
 
-static void slirp_receive(void *opaque, const uint8_t *buf, size_t size)
+static void slirp_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
 #ifdef DEBUG_SLIRP
     printf("slirp input:\n");
@@ -787,10 +787,10 @@ typedef struct TAPState {
 
 static int launch_script(const char *setup_script, const char *ifname, int fd);
 
-static ssize_t tap_receive_iov(void *opaque, const struct iovec *iov,
+static ssize_t tap_receive_iov(VLANClientState *vc, const struct iovec *iov,
                                int iovcnt)
 {
-    TAPState *s = opaque;
+    TAPState *s = vc->opaque;
     ssize_t len;
 
     do {
@@ -800,9 +800,9 @@ static ssize_t tap_receive_iov(void *opaque, const struct iovec *iov,
     return len;
 }
 
-static void tap_receive(void *opaque, const uint8_t *buf, size_t size)
+static void tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    TAPState *s = opaque;
+    TAPState *s = vc->opaque;
     int ret;
     for(;;) {
         ret = write(s->fd, buf, size);
@@ -1158,9 +1158,9 @@ static void vde_to_qemu(void *opaque)
     }
 }
 
-static void vde_from_qemu(void *opaque, const uint8_t *buf, int size)
+static void vde_receive(VLANClientState *vc, const uint8_t *buf, int size)
 {
-    VDEState *s = opaque;
+    VDEState *s = vc->opaque;
     int ret;
     for(;;) {
         ret = vde_send(s->vde, (const char *)buf, size, 0);
@@ -1199,7 +1199,7 @@ static int net_vde_init(VLANState *vlan, const char *model,
         free(s);
         return -1;
     }
-    s->vc = qemu_new_vlan_client(vlan, model, name, NULL, vde_from_qemu,
+    s->vc = qemu_new_vlan_client(vlan, model, name, NULL, vde_receive,
                                  NULL, vde_cleanup, s);
     qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
     snprintf(s->vc->info_str, sizeof(s->vc->info_str), "sock=%s,fd=%d",
@@ -1227,9 +1227,9 @@ typedef struct NetSocketListenState {
 } NetSocketListenState;
 
 /* XXX: we consider we can send the whole packet without blocking */
-static void net_socket_receive(void *opaque, const uint8_t *buf, size_t size)
+static void net_socket_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    NetSocketState *s = opaque;
+    NetSocketState *s = vc->opaque;
     uint32_t len;
     len = htonl(size);
 
@@ -1237,9 +1237,9 @@ static void net_socket_receive(void *opaque, const uint8_t *buf, size_t size)
     send_all(s->fd, buf, size);
 }
 
-static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, size_t size)
+static void net_socket_receive_dgram(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    NetSocketState *s = opaque;
+    NetSocketState *s = vc->opaque;
     sendto(s->fd, buf, size, 0,
            (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
 }
@@ -1678,9 +1678,9 @@ struct pcap_sf_pkthdr {
     uint32_t len;
 };
 
-static void dump_receive(void *opaque, const uint8_t *buf, size_t size)
+static void dump_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    DumpState *s = opaque;
+    DumpState *s = vc->opaque;
     struct pcap_sf_pkthdr hdr;
     int64_t ts;
     int caplen;
diff --git a/net.h b/net.h
index d99dc39..2e308c9 100644
--- a/net.h
+++ b/net.h
@@ -7,9 +7,9 @@
 
 typedef struct VLANClientState VLANClientState;
 
-typedef int (NetCanReceive)(void *);
-typedef void (NetReceive)(void *, const uint8_t *, size_t);
-typedef ssize_t (NetReceiveIOV)(void *, const struct iovec *, int);
+typedef int (NetCanReceive)(VLANClientState *);
+typedef void (NetReceive)(VLANClientState *, const uint8_t *, size_t);
+typedef ssize_t (NetReceiveIOV)(VLANClientState *, const struct iovec *, int);
 typedef void (NetCleanup) (VLANClientState *);
 typedef void (LinkStatusChanged)(VLANClientState *);
 
diff --git a/savevm.c b/savevm.c
index f19aa60..89bdcdc 100644
--- a/savevm.c
+++ b/savevm.c
@@ -129,7 +129,7 @@ void qemu_announce_self(void)
         vlan = nd_table[i].vlan;
         for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
             for (j=0; j < SELF_ANNOUNCE_ROUNDS; j++)
-                vc->receive(vc->opaque, buf, len);
+                vc->receive(vc, buf, len);
         }
     }
 }
diff --git a/tap-win32.c b/tap-win32.c
index ccf7e45..ff1e1ed 100644
--- a/tap-win32.c
+++ b/tap-win32.c
@@ -650,7 +650,7 @@ static void tap_cleanup(VLANClientState *vc)
     qemu_free(s);
 }
 
-static void tap_receive(void *opaque, const uint8_t *buf, size_t size)
+static void tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     TAPState *s = opaque;
 
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Qemu-devel] [PATCH 08/13] net: add return value to packet receive handler
  2009-05-19  9:55             ` [Qemu-devel] [PATCH 07/13] net: pass VLANClientState* as first arg to receive handlers Mark McLoughlin
@ 2009-05-19  9:55               ` Mark McLoughlin
  2009-05-19  9:55                 ` [Qemu-devel] [PATCH 09/13] net: return status from qemu_deliver_packet() Mark McLoughlin
  0 siblings, 1 reply; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-19  9:55 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Mark McLoughlin, qemu-devel

This allows us to handle queue full conditions rather than dropping
the packet on the floor.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 hw/dp8393x.c        |    8 ++++--
 hw/e1000.c          |   14 +++++++-----
 hw/eepro100.c       |   15 +++++++------
 hw/etraxfs_eth.c    |    8 ++++--
 hw/mcf_fec.c        |    3 +-
 hw/mipsnet.c        |    6 +++-
 hw/musicpal.c       |    5 ++-
 hw/ne2000.c         |   15 ++++++++-----
 hw/pcnet.c          |    7 ++++-
 hw/rtl8139.c        |   29 +++++++++++++++------------
 hw/smc91c111.c      |   10 +++++---
 hw/stellaris_enet.c |    8 ++++--
 hw/usb-net.c        |    9 ++++---
 hw/virtio-net.c     |   10 +++++---
 hw/xen_nic.c        |   12 ++++++----
 net.c               |   54 ++++++++++++++++++++++++++------------------------
 net.h               |    2 +-
 tap-win32.c         |    6 ++--
 18 files changed, 126 insertions(+), 95 deletions(-)

diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index 91850bc..563cbad 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -725,7 +725,7 @@ static int receive_filter(dp8393xState *s, const uint8_t * buf, int size)
     return -1;
 }
 
-static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
+static ssize_t nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
 {
     uint16_t data[10];
     dp8393xState *s = vc->opaque;
@@ -742,7 +742,7 @@ static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
     packet_type = receive_filter(s, buf, size);
     if (packet_type < 0) {
         DPRINTF("packet not for netcard\n");
-        return;
+        return -1;
     }
 
     /* XXX: Check byte ordering */
@@ -755,7 +755,7 @@ static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
         s->memory_rw(s->mem_opaque, address, (uint8_t*)data, size, 0);
         if (data[0 * width] & 0x1) {
             /* Still EOL ; stop reception */
-            return;
+            return -1;
         } else {
             s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
         }
@@ -833,6 +833,8 @@ static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
 
     /* Done */
     dp8393x_update_irq(s);
+
+    return size;
 }
 
 static void nic_reset(void *opaque)
diff --git a/hw/e1000.c b/hw/e1000.c
index 689c48e..ef33a4e 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -592,7 +592,7 @@ e1000_can_receive(VLANClientState *vc)
     return (s->mac_reg[RCTL] & E1000_RCTL_EN);
 }
 
-static void
+static ssize_t
 e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     E1000State *s = vc->opaque;
@@ -604,16 +604,16 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
     uint8_t vlan_status = 0, vlan_offset = 0;
 
     if (!(s->mac_reg[RCTL] & E1000_RCTL_EN))
-        return;
+        return -1;
 
     if (size > s->rxbuf_size) {
         DBGOUT(RX, "packet too large for buffers (%lu > %d)\n",
                (unsigned long)size, s->rxbuf_size);
-        return;
+        return -1;
     }
 
     if (!receive_filter(s, buf, size))
-        return;
+        return size;
 
     if (vlan_enabled(s) && is_vlan_packet(s, buf)) {
         vlan_special = cpu_to_le16(be16_to_cpup((uint16_t *)(buf + 14)));
@@ -628,7 +628,7 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
     do {
         if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
             set_ics(s, 0, E1000_ICS_RXO);
-            return;
+            return -1;
         }
         base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +
                sizeof(desc) * s->mac_reg[RDH];
@@ -652,7 +652,7 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
             DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
                    rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
             set_ics(s, 0, E1000_ICS_RXO);
-            return;
+            return -1;
         }
     } while (desc.buffer_addr == 0);
 
@@ -670,6 +670,8 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
         n |= E1000_ICS_RXDMT0;
 
     set_ics(s, 0, n);
+
+    return size;
 }
 
 static uint32_t
diff --git a/hw/eepro100.c b/hw/eepro100.c
index ef977a9..1440d00 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1441,7 +1441,7 @@ static int nic_can_receive(VLANClientState *vc)
     //~ return !eepro100_buffer_full(s);
 }
 
-static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
+static ssize_t nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
 {
     /* TODO:
      * - Magic packets should set bit 30 in power management driver register.
@@ -1458,18 +1458,18 @@ static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
     if (s->configuration[8] & 0x80) {
         /* CSMA is disabled. */
         logout("%p received while CSMA is disabled\n", s);
-        return;
+        return -1;
     } else if (size < 64 && (s->configuration[7] & 1)) {
         /* Short frame and configuration byte 7/0 (discard short receive) set:
          * Short frame is discarded */
         logout("%p received short frame (%d byte)\n", s, size);
         s->statistics.rx_short_frame_errors++;
-        //~ return;
+        //~ return -1;
     } else if ((size > MAX_ETH_FRAME_SIZE + 4) && !(s->configuration[18] & 8)) {
         /* Long frame and configuration byte 18/3 (long receive ok) not set:
          * Long frames are discarded. */
         logout("%p received long frame (%d byte), ignored\n", s, size);
-        return;
+        return -1;
     } else if (memcmp(buf, s->macaddr, 6) == 0) {       // !!!
         /* Frame matches individual address. */
         /* TODO: check configuration byte 15/4 (ignore U/L). */
@@ -1485,7 +1485,7 @@ static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
         assert(!(s->configuration[21] & BIT(3)));
         int mcast_idx = compute_mcast_idx(buf);
         if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) {
-            return;
+            return size;
         }
         rfd_status |= 0x0002;
     } else if (s->configuration[15] & 1) {
@@ -1495,7 +1495,7 @@ static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
     } else {
         logout("%p received frame, ignored, len=%d,%s\n", s, size,
                nic_dump(buf, size));
-        return;
+        return size;
     }
 
     if (get_ru_state(s) != ru_ready) {
@@ -1503,7 +1503,7 @@ static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
         logout("no ressources, state=%u\n", get_ru_state(s));
         s->statistics.rx_resource_errors++;
         //~ assert(!"no ressources");
-        return;
+        return -1;
     }
     //~ !!!
 //~ $3 = {status = 0x0, command = 0xc000, link = 0x2d220, rx_buf_addr = 0x207dc, count = 0x0, size = 0x5f8, packet = {0x0 <repeats 1518 times>}}
@@ -1540,6 +1540,7 @@ static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
         /* S bit is set. */
         set_ru_state(s, ru_suspended);
     }
+    return size;
 }
 
 static int nic_load(QEMUFile * f, void *opaque, int version_id)
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 78af76b..c7df44e 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -501,7 +501,7 @@ static int eth_can_receive(VLANClientState *vc)
 	return 1;
 }
 
-static void eth_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t eth_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
 	unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 	struct fs_eth *eth = vc->opaque;
@@ -510,7 +510,7 @@ static void eth_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 	int r_bcast = eth->regs[RW_REC_CTRL] & 8;
 
 	if (size < 12)
-		return;
+		return -1;
 
 	D(printf("%x.%x.%x.%x.%x.%x ma=%d %d bc=%d\n",
 		 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
@@ -521,10 +521,12 @@ static void eth_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 	    && (!use_ma1 || memcmp(buf, eth->macaddr[1], 6))
 	    && (!r_bcast || memcmp(buf, sa_bcast, 6))
 	    && !eth_match_groupaddr(eth, buf))
-		return;
+		return size;
 
 	/* FIXME: Find another way to pass on the fake csum.  */
 	etraxfs_dmac_input(eth->dma_in, (void *)buf, size + 4, 1);
+
+        return size;
 }
 
 static int eth_tx_push(void *opaque, unsigned char *buf, int len)
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index d2534d0..179ec19 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -353,7 +353,7 @@ static int mcf_fec_can_receive(VLANClientState *vc)
     return s->rx_enabled;
 }
 
-static void mcf_fec_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t mcf_fec_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     mcf_fec_state *s = vc->opaque;
     mcf_fec_bd bd;
@@ -426,6 +426,7 @@ static void mcf_fec_receive(VLANClientState *vc, const uint8_t *buf, size_t size
     s->rx_descriptor = addr;
     mcf_fec_enable_rx(s);
     mcf_fec_update(s);
+    return size;
 }
 
 static CPUReadMemoryFunc *mcf_fec_readfn[] = {
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index e9128cb..8035229 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -75,7 +75,7 @@ static int mipsnet_can_receive(VLANClientState *vc)
     return !mipsnet_buffer_full(s);
 }
 
-static void mipsnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t mipsnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     MIPSnetState *s = vc->opaque;
 
@@ -83,7 +83,7 @@ static void mipsnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size
     printf("mipsnet: receiving len=%d\n", size);
 #endif
     if (!mipsnet_can_receive(vc))
-        return;
+        return -1;
 
     s->busy = 1;
 
@@ -98,6 +98,8 @@ static void mipsnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size
     /* Now we can signal we have received something. */
     s->intctl |= MIPSNET_INTCTL_RXDONE;
     mipsnet_update_irq(s);
+
+    return size;
 }
 
 static uint32_t mipsnet_ioport_read(void *opaque, uint32_t addr)
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 943dc6f..9bc4f3d 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -562,7 +562,7 @@ static int eth_can_receive(VLANClientState *vc)
     return 1;
 }
 
-static void eth_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t eth_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     mv88w8618_eth_state *s = vc->opaque;
     uint32_t desc_addr;
@@ -586,11 +586,12 @@ static void eth_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
                 if (s->icr & s->imr)
                     qemu_irq_raise(s->irq);
                 eth_rx_desc_put(desc_addr, &desc);
-                return;
+                return size;
             }
             desc_addr = desc.next;
         } while (desc_addr != s->rx_queue[i]);
     }
+    return size;
 }
 
 static void eth_tx_desc_put(uint32_t addr, mv88w8618_tx_desc *desc)
diff --git a/hw/ne2000.c b/hw/ne2000.c
index c0fc34c..f5ae9d7 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -224,9 +224,10 @@ static int ne2000_can_receive(VLANClientState *vc)
 
 #define MIN_BUF_SIZE 60
 
-static void ne2000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t ne2000_receive(VLANClientState *vc, const uint8_t *buf, size_t size_)
 {
     NE2000State *s = vc->opaque;
+    int size = size_;
     uint8_t *p;
     unsigned int total_len, next, avail, len, index, mcast_idx;
     uint8_t buf1[60];
@@ -238,7 +239,7 @@ static void ne2000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 #endif
 
     if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
-        return;
+        return -1;
 
     /* XXX: check this */
     if (s->rxcr & 0x10) {
@@ -247,14 +248,14 @@ static void ne2000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
         if (!memcmp(buf,  broadcast_macaddr, 6)) {
             /* broadcast address */
             if (!(s->rxcr & 0x04))
-                return;
+                return size;
         } else if (buf[0] & 0x01) {
             /* multicast */
             if (!(s->rxcr & 0x08))
-                return;
+                return size;
             mcast_idx = compute_mcast_idx(buf);
             if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
-                return;
+                return size;
         } else if (s->mem[0] == buf[0] &&
                    s->mem[2] == buf[1] &&
                    s->mem[4] == buf[2] &&
@@ -263,7 +264,7 @@ static void ne2000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
                    s->mem[10] == buf[5]) {
             /* match */
         } else {
-            return;
+            return size;
         }
     }
 
@@ -316,6 +317,8 @@ static void ne2000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
     /* now we can signal we have received something */
     s->isr |= ENISR_RX;
     ne2000_update_irq(s);
+
+    return size_;
 }
 
 static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
diff --git a/hw/pcnet.c b/hw/pcnet.c
index 1ab731c..4afbc0f 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -1076,16 +1076,17 @@ static int pcnet_can_receive(VLANClientState *vc)
 
 #define MIN_BUF_SIZE 60
 
-static void pcnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t pcnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size_)
 {
     PCNetState *s = vc->opaque;
     int is_padr = 0, is_bcast = 0, is_ladr = 0;
     uint8_t buf1[60];
     int remaining;
     int crc_err = 0;
+    int size = size_;
 
     if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
-        return;
+        return -1;
 
 #ifdef PCNET_DEBUG
     printf("pcnet_receive size=%d\n", size);
@@ -1252,6 +1253,8 @@ static void pcnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 
     pcnet_poll(s);
     pcnet_update_irq(s);
+
+    return size_;
 }
 
 static void pcnet_transmit(PCNetState *s)
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 8626d5e..c86b782 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -812,9 +812,10 @@ static int rtl8139_can_receive(VLANClientState *vc)
     }
 }
 
-static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size, int do_interrupt)
+static ssize_t rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, size_t size_, int do_interrupt)
 {
     RTL8139State *s = vc->opaque;
+    int size = size_;
 
     uint32_t packet_header = 0;
 
@@ -828,7 +829,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
     if (!s->clock_enabled)
     {
         DEBUG_PRINT(("RTL8139: stopped ==========================\n"));
-        return;
+        return -1;
     }
 
     /* first check if receiver is enabled */
@@ -836,7 +837,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
     if (!rtl8139_receiver_enabled(s))
     {
         DEBUG_PRINT(("RTL8139: receiver disabled ================\n"));
-        return;
+        return -1;
     }
 
     /* XXX: check this */
@@ -854,7 +855,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
                 /* update tally counter */
                 ++s->tally_counters.RxERR;
 
-                return;
+                return size;
             }
 
             packet_header |= RxBroadcast;
@@ -873,7 +874,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
                 /* update tally counter */
                 ++s->tally_counters.RxERR;
 
-                return;
+                return size;
             }
 
             int mcast_idx = compute_mcast_idx(buf);
@@ -885,7 +886,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
                 /* update tally counter */
                 ++s->tally_counters.RxERR;
 
-                return;
+                return size;
             }
 
             packet_header |= RxMulticast;
@@ -909,7 +910,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
                 /* update tally counter */
                 ++s->tally_counters.RxERR;
 
-                return;
+                return size;
             }
 
             packet_header |= RxPhysical;
@@ -926,7 +927,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
             /* update tally counter */
             ++s->tally_counters.RxERR;
 
-            return;
+            return size;
         }
     }
 
@@ -993,7 +994,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
             ++s->tally_counters.MissPkt;
 
             rtl8139_update_irq(s);
-            return;
+            return size_;
         }
 
         uint32_t rx_space = rxdw0 & CP_RX_BUFFER_SIZE_MASK;
@@ -1013,7 +1014,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
             ++s->tally_counters.MissPkt;
 
             rtl8139_update_irq(s);
-            return;
+            return size_;
         }
 
         target_phys_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI);
@@ -1118,7 +1119,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
             s->IntrStatus |= RxOverflow;
             ++s->RxMissed;
             rtl8139_update_irq(s);
-            return;
+            return size_;
         }
 
         packet_header |= RxStatusOK;
@@ -1156,11 +1157,13 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
     {
         rtl8139_update_irq(s);
     }
+
+    return size_;
 }
 
-static void rtl8139_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t rtl8139_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    rtl8139_do_receive(vc, buf, size, 1);
+    return rtl8139_do_receive(vc, buf, size, 1);
 }
 
 static void rtl8139_reset_rxring(RTL8139State *s, uint32_t bufferSize)
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index 383f0b7..93a1fae 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -602,7 +602,7 @@ static int smc91c111_can_receive(VLANClientState *vc)
     return 1;
 }
 
-static void smc91c111_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t smc91c111_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     smc91c111_state *s = vc->opaque;
     int status;
@@ -612,7 +612,7 @@ static void smc91c111_receive(VLANClientState *vc, const uint8_t *buf, size_t si
     uint8_t *p;
 
     if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
-        return;
+        return -1;
     /* Short packets are padded with zeros.  Receiving a packet
        < 64 bytes long is considered an error condition.  */
     if (size < 64)
@@ -625,10 +625,10 @@ static void smc91c111_receive(VLANClientState *vc, const uint8_t *buf, size_t si
         packetsize += 4;
     /* TODO: Flag overrun and receive errors.  */
     if (packetsize > 2048)
-        return;
+        return -1;
     packetnum = smc91c111_allocate_packet(s);
     if (packetnum == 0x80)
-        return;
+        return -1;
     s->rx_fifo[s->rx_fifo_len++] = packetnum;
 
     p = &s->data[packetnum][0];
@@ -676,6 +676,8 @@ static void smc91c111_receive(VLANClientState *vc, const uint8_t *buf, size_t si
     /* TODO: Raise early RX interrupt?  */
     s->int_level |= INT_RCV;
     smc91c111_update(s);
+
+    return size;
 }
 
 static CPUReadMemoryFunc *smc91c111_readfn[] = {
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index 7f30829..f5b83e4 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -78,7 +78,7 @@ static void stellaris_enet_update(stellaris_enet_state *s)
 }
 
 /* TODO: Implement MAC address filtering.  */
-static void stellaris_enet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t stellaris_enet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     stellaris_enet_state *s = vc->opaque;
     int n;
@@ -86,10 +86,10 @@ static void stellaris_enet_receive(VLANClientState *vc, const uint8_t *buf, size
     uint32_t crc;
 
     if ((s->rctl & SE_RCTL_RXEN) == 0)
-        return;
+        return -1;
     if (s->np >= 31) {
         DPRINTF("Packet dropped\n");
-        return;
+        return -1;
     }
 
     DPRINTF("Received packet len=%d\n", size);
@@ -116,6 +116,8 @@ static void stellaris_enet_receive(VLANClientState *vc, const uint8_t *buf, size
 
     s->ris |= SE_INT_RX;
     stellaris_enet_update(s);
+
+    return size;
 }
 
 static int stellaris_enet_can_receive(VLANClientState *vc)
diff --git a/hw/usb-net.c b/hw/usb-net.c
index d8d5e77..0e80ca6 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1369,7 +1369,7 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p)
     return ret;
 }
 
-static void usbnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t usbnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     USBNetState *s = vc->opaque;
     struct rndis_packet_msg_type *msg;
@@ -1377,9 +1377,9 @@ static void usbnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
     if (s->rndis) {
         msg = (struct rndis_packet_msg_type *) s->in_buf;
         if (!s->rndis_state == RNDIS_DATA_INITIALIZED)
-            return;
+            return -1;
         if (size + sizeof(struct rndis_packet_msg_type) > sizeof(s->in_buf))
-            return;
+            return -1;
 
         memset(msg, 0, sizeof(struct rndis_packet_msg_type));
         msg->MessageType = cpu_to_le32(RNDIS_PACKET_MSG);
@@ -1398,11 +1398,12 @@ static void usbnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
         s->in_len = size + sizeof(struct rndis_packet_msg_type);
     } else {
         if (size > sizeof(s->in_buf))
-            return;
+            return -1;
         memcpy(s->in_buf, buf, size);
         s->in_len = size;
     }
     s->in_ptr = 0;
+    return size;
 }
 
 static int usbnet_can_receive(VLANClientState *vc)
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 1ffebac..6b34c5a 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -361,17 +361,17 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
     return 0;
 }
 
-static void virtio_net_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t virtio_net_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     VirtIONet *n = vc->opaque;
     struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL;
     size_t hdr_len, offset, i;
 
     if (!do_virtio_net_can_receive(n, size))
-        return;
+        return -1;
 
     if (!receive_filter(n, buf, size))
-        return;
+        return size;
 
     /* hdr_len refers to the header we supply to the guest */
     hdr_len = n->mergeable_rx_bufs ?
@@ -389,7 +389,7 @@ static void virtio_net_receive(VLANClientState *vc, const uint8_t *buf, size_t s
         if ((i != 0 && !n->mergeable_rx_bufs) ||
             virtqueue_pop(n->rx_vq, &elem) == 0) {
             if (i == 0)
-                return;
+                return -1;
             fprintf(stderr, "virtio-net truncating packet\n");
             exit(1);
         }
@@ -431,6 +431,8 @@ static void virtio_net_receive(VLANClientState *vc, const uint8_t *buf, size_t s
 
     virtqueue_flush(n->rx_vq, i);
     virtio_notify(&n->vdev, n->rx_vq);
+
+    return size;
 }
 
 /* TX */
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index d2d5a4b..8a55c29 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -245,7 +245,7 @@ static int net_rx_ok(VLANClientState *vc)
     return 1;
 }
 
-static void net_rx_packet(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t net_rx_packet(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     struct XenNetDev *netdev = vc->opaque;
     netif_rx_request_t rxreq;
@@ -253,7 +253,7 @@ static void net_rx_packet(VLANClientState *vc, const uint8_t *buf, size_t size)
     void *page;
 
     if (netdev->xendev.be_state != XenbusStateConnected)
-	return;
+	return -1;
 
     rc = netdev->rx_ring.req_cons;
     rp = netdev->rx_ring.sring->req_prod;
@@ -261,12 +261,12 @@ static void net_rx_packet(VLANClientState *vc, const uint8_t *buf, size_t size)
 
     if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
 	xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");
-	return;
+	return -1;
     }
     if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
 	xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
 		      (unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
-	return;
+	return -1;
     }
 
     memcpy(&rxreq, RING_GET_REQUEST(&netdev->rx_ring, rc), sizeof(rxreq));
@@ -279,11 +279,13 @@ static void net_rx_packet(VLANClientState *vc, const uint8_t *buf, size_t size)
 	xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n",
                       rxreq.gref);
 	net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
-	return;
+	return -1;
     }
     memcpy(page + NET_IP_ALIGN, buf, size);
     xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
     net_rx_response(netdev, &rxreq, NETIF_RSP_OKAY, NET_IP_ALIGN, size, 0);
+
+    return size;
 }
 
 /* ------------------------------------------------------------- */
diff --git a/net.c b/net.c
index a3af42d..7d0a428 100644
--- a/net.c
+++ b/net.c
@@ -568,13 +568,14 @@ int slirp_is_inited(void)
     return slirp_inited;
 }
 
-static void slirp_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t slirp_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
 #ifdef DEBUG_SLIRP
     printf("slirp input:\n");
     hex_dump(stdout, buf, size);
 #endif
     slirp_input(buf, size);
+    return size;
 }
 
 static int slirp_in_use;
@@ -800,17 +801,16 @@ static ssize_t tap_receive_iov(VLANClientState *vc, const struct iovec *iov,
     return len;
 }
 
-static void tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     TAPState *s = vc->opaque;
-    int ret;
-    for(;;) {
-        ret = write(s->fd, buf, size);
-        if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
-        } else {
-            break;
-        }
-    }
+    ssize_t len;
+
+    do {
+        len = write(s->fd, buf, size);
+    } while (len == -1 && (errno == EINTR || errno == EAGAIN));
+
+    return len;
 }
 
 static int tap_can_send(void *opaque)
@@ -1158,17 +1158,16 @@ static void vde_to_qemu(void *opaque)
     }
 }
 
-static void vde_receive(VLANClientState *vc, const uint8_t *buf, int size)
+static ssize_t vde_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     VDEState *s = vc->opaque;
-    int ret;
-    for(;;) {
-        ret = vde_send(s->vde, (const char *)buf, size, 0);
-        if (ret < 0 && errno == EINTR) {
-        } else {
-            break;
-        }
-    }
+    ssize ret;
+
+    do {
+      ret = vde_send(s->vde, (const char *)buf, size, 0);
+    } while (ret < 0 && errno == EINTR);
+
+    return ret;
 }
 
 static void vde_cleanup(VLANClientState *vc)
@@ -1227,21 +1226,22 @@ typedef struct NetSocketListenState {
 } NetSocketListenState;
 
 /* XXX: we consider we can send the whole packet without blocking */
-static void net_socket_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t net_socket_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     NetSocketState *s = vc->opaque;
     uint32_t len;
     len = htonl(size);
 
     send_all(s->fd, (const uint8_t *)&len, sizeof(len));
-    send_all(s->fd, buf, size);
+    return send_all(s->fd, buf, size);
 }
 
-static void net_socket_receive_dgram(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t net_socket_receive_dgram(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     NetSocketState *s = vc->opaque;
-    sendto(s->fd, buf, size, 0,
-           (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
+
+    return sendto(s->fd, buf, size, 0,
+                  (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
 }
 
 static void net_socket_send(void *opaque)
@@ -1678,7 +1678,7 @@ struct pcap_sf_pkthdr {
     uint32_t len;
 };
 
-static void dump_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t dump_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     DumpState *s = vc->opaque;
     struct pcap_sf_pkthdr hdr;
@@ -1687,7 +1687,7 @@ static void dump_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 
     /* Early return in case of previous error. */
     if (s->fd < 0) {
-        return;
+        return size;
     }
 
     ts = muldiv64 (qemu_get_clock(vm_clock),1000000, ticks_per_sec);
@@ -1703,6 +1703,8 @@ static void dump_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
         close(s->fd);
         s->fd = -1;
     }
+
+    return size;
 }
 
 static void net_dump_cleanup(VLANClientState *vc)
diff --git a/net.h b/net.h
index 2e308c9..766edbe 100644
--- a/net.h
+++ b/net.h
@@ -8,7 +8,7 @@
 typedef struct VLANClientState VLANClientState;
 
 typedef int (NetCanReceive)(VLANClientState *);
-typedef void (NetReceive)(VLANClientState *, const uint8_t *, size_t);
+typedef ssize_t (NetReceive)(VLANClientState *, const uint8_t *, size_t);
 typedef ssize_t (NetReceiveIOV)(VLANClientState *, const struct iovec *, int);
 typedef void (NetCleanup) (VLANClientState *);
 typedef void (LinkStatusChanged)(VLANClientState *);
diff --git a/tap-win32.c b/tap-win32.c
index ff1e1ed..ba93355 100644
--- a/tap-win32.c
+++ b/tap-win32.c
@@ -650,11 +650,11 @@ static void tap_cleanup(VLANClientState *vc)
     qemu_free(s);
 }
 
-static void tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
-    TAPState *s = opaque;
+    TAPState *s = vc->opaque;
 
-    tap_win32_write(s->handle, buf, size);
+    return tap_win32_write(s->handle, buf, size);
 }
 
 static void tap_win32_send(void *opaque)
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Qemu-devel] [PATCH 09/13] net: return status from qemu_deliver_packet()
  2009-05-19  9:55               ` [Qemu-devel] [PATCH 08/13] net: add return value to packet receive handler Mark McLoughlin
@ 2009-05-19  9:55                 ` Mark McLoughlin
  2009-05-22 14:23                   ` [Qemu-devel] [PATCH 10/13] net: split out packet queueing and flushing into separate functions Mark McLoughlin
  0 siblings, 1 reply; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-19  9:55 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Mark McLoughlin, qemu-devel

Will allow qemu_send_packet() handle queue full condition.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 net.c |   20 +++++++++++++++++---
 1 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/net.c b/net.c
index 7d0a428..07bf8d8 100644
--- a/net.c
+++ b/net.c
@@ -409,16 +409,30 @@ int qemu_can_send_packet(VLANClientState *sender)
     return 0;
 }
 
-static void
+static int
 qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
 {
     VLANClientState *vc;
+    int ret = -1;
 
     for (vc = sender->vlan->first_client; vc != NULL; vc = vc->next) {
-        if (vc != sender && !vc->link_down) {
-            vc->receive(vc, buf, size);
+        ssize_t len;
+
+        if (vc == sender) {
+            continue;
+        }
+
+        if (vc->link_down) {
+            ret = size;
+            continue;
         }
+
+        len = vc->receive(vc, buf, size);
+
+        ret = (ret >= 0) ? ret : len;
     }
+
+    return ret;
 }
 
 void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [Qemu-devel] [PATCH 0/13] Add generic packet buffering API
  2009-05-19  9:55 [Qemu-devel] [PATCH 0/13] Add generic packet buffering API Mark McLoughlin
  2009-05-19  9:55 ` [Qemu-devel] [PATCH 01/13] net: factor tap_read_packet() out of tap_send() Mark McLoughlin
@ 2009-05-19 10:18 ` Avi Kivity
  2009-05-19 10:33   ` Mark McLoughlin
  2009-05-22 13:43 ` [Qemu-devel] " Anthony Liguori
  2 siblings, 1 reply; 19+ messages in thread
From: Avi Kivity @ 2009-05-19 10:18 UTC (permalink / raw)
  To: Mark McLoughlin; +Cc: Anthony Liguori, qemu-devel

Mark McLoughlin wrote:
> Hi,
>         This patch series works towards two[1] goals:
>
>   1) Merging the code in qemu-kvm which drains the tap file descriptor
>      when it is readable and buffers a packet if it fails to add it to
>      the NIC receive queue
>
>   2) Using the new TAP_SETSNDBUF ioctl() to put a limit on the number
>      of in-flight packets allowed on a tap device; in this case, if a
>      NIC pops a packet from its transmit queue, we need to be able to
>      buffer said packet if the tap queue is full
>   

Isn't it better instead to unpop the buffer?  The NIC tx ring already is 
a buffer, no need to add another one on top.

It will need adjustments to the device models; for example we'll need 
virtqueue_pop_commit() after we're certain the tap had enough room for 
our packet and virtqueue_pop_cancel() (to unmap the buffers) if we don't.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Qemu-devel] [PATCH 0/13] Add generic packet buffering API
  2009-05-19 10:18 ` [Qemu-devel] [PATCH 0/13] Add generic packet buffering API Avi Kivity
@ 2009-05-19 10:33   ` Mark McLoughlin
  2009-05-19 11:56     ` Avi Kivity
  0 siblings, 1 reply; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-19 10:33 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Anthony Liguori, qemu-devel

On Tue, 2009-05-19 at 13:18 +0300, Avi Kivity wrote:
> Mark McLoughlin wrote:
> > Hi,
> >         This patch series works towards two[1] goals:
> >
> >   1) Merging the code in qemu-kvm which drains the tap file descriptor
> >      when it is readable and buffers a packet if it fails to add it to
> >      the NIC receive queue
> >
> >   2) Using the new TAP_SETSNDBUF ioctl() to put a limit on the number
> >      of in-flight packets allowed on a tap device; in this case, if a
> >      NIC pops a packet from its transmit queue, we need to be able to
> >      buffer said packet if the tap queue is full
> >   
> 
> Isn't it better instead to unpop the buffer?  The NIC tx ring already is 
> a buffer, no need to add another one on top.
> 
> It will need adjustments to the device models; for example we'll need 
> virtqueue_pop_commit() after we're certain the tap had enough room for 
> our packet and virtqueue_pop_cancel() (to unmap the buffers) if we don't.

Yep, it's possible with virtio. However, you can't unpop the buffer from
a tap file descriptor or socket.

The alternative in those cases is to implement buffering for each, or to
always check the receiving side has buffers available before popping. I
choose this option because checking in advance for each packet seems
expensive - i.e. a syscall for tap/socket or a trawl through the ring
for virtio.

Cheers,
Mark.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Qemu-devel] [PATCH 0/13] Add generic packet buffering API
  2009-05-19 10:33   ` Mark McLoughlin
@ 2009-05-19 11:56     ` Avi Kivity
  0 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2009-05-19 11:56 UTC (permalink / raw)
  To: Mark McLoughlin; +Cc: Anthony Liguori, qemu-devel

Mark McLoughlin wrote:
>> It will need adjustments to the device models; for example we'll need 
>> virtqueue_pop_commit() after we're certain the tap had enough room for 
>> our packet and virtqueue_pop_cancel() (to unmap the buffers) if we don't.
>>     
>
> Yep, it's possible with virtio. However, you can't unpop the buffer from
> a tap file descriptor or socket.
>
> The alternative in those cases is to implement buffering for each, or to
> always check the receiving side has buffers available before popping. I
> choose this option because checking in advance for each packet seems
> expensive - i.e. a syscall for tap/socket or a trawl through the ring
> for virtio.
>   

For virtio (or the other emulated devices) the check is pretty cheap; 
furthermore you only need to do it when something changes (notification 
or a pop).

So, with the disadvantage of an asymmetrical API, we have:

transmit():
   conditional pop
   tap->receive()
   commit pop / cancel pop

receive():
   tap->send()
   if (no more room)
       tap->stop()

receive_notify():
    if (more room)
       tap->start()

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Qemu-devel] Re: [PATCH 0/13] Add generic packet buffering API
  2009-05-19  9:55 [Qemu-devel] [PATCH 0/13] Add generic packet buffering API Mark McLoughlin
  2009-05-19  9:55 ` [Qemu-devel] [PATCH 01/13] net: factor tap_read_packet() out of tap_send() Mark McLoughlin
  2009-05-19 10:18 ` [Qemu-devel] [PATCH 0/13] Add generic packet buffering API Avi Kivity
@ 2009-05-22 13:43 ` Anthony Liguori
  2009-05-22 14:23   ` Mark McLoughlin
  2 siblings, 1 reply; 19+ messages in thread
From: Anthony Liguori @ 2009-05-22 13:43 UTC (permalink / raw)
  To: Mark McLoughlin; +Cc: qemu-devel

Mark McLoughlin wrote:
> Hi,
>         This patch series works towards two[1] goals:
>
>   

10-13 seems to have been lost in the ether....

-- 
Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/13] Add generic packet buffering API
  2009-05-22 13:43 ` [Qemu-devel] " Anthony Liguori
@ 2009-05-22 14:23   ` Mark McLoughlin
  0 siblings, 0 replies; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-22 14:23 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On Fri, 2009-05-22 at 08:43 -0500, Anthony Liguori wrote:
> Mark McLoughlin wrote:
> > Hi,
> >         This patch series works towards two[1] goals:
> >
> >   
> 
> 10-13 seems to have been lost in the ether....

Odd. I'll hunt them down.

Cheers,
Mark.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Qemu-devel] [PATCH 10/13] net: split out packet queueing and flushing into separate functions
  2009-05-19  9:55                 ` [Qemu-devel] [PATCH 09/13] net: return status from qemu_deliver_packet() Mark McLoughlin
@ 2009-05-22 14:23                   ` Mark McLoughlin
  2009-05-22 14:24                     ` [Qemu-devel] [PATCH 11/13] net: add qemu_send_packet_async() Mark McLoughlin
  0 siblings, 1 reply; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-22 14:23 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

We'll be doing more packet queueing in later commits.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 net.c |  155 +++++++++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 98 insertions(+), 57 deletions(-)

diff --git a/net.c b/net.c
index 07bf8d8..2f4743e 100644
--- a/net.c
+++ b/net.c
@@ -415,6 +415,8 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
     VLANClientState *vc;
     int ret = -1;
 
+    sender->vlan->delivering = 1;
+
     for (vc = sender->vlan->first_client; vc != NULL; vc = vc->next) {
         ssize_t len;
 
@@ -432,13 +434,38 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
         ret = (ret >= 0) ? ret : len;
     }
 
+    sender->vlan->delivering = 0;
+
     return ret;
 }
 
+static void qemu_flush_queued_packets(VLANClientState *vc)
+{
+    VLANPacket *packet;
+
+    while ((packet = vc->vlan->send_queue) != NULL) {
+        vc->vlan->send_queue = packet->next;
+        qemu_deliver_packet(packet->sender, packet->data, packet->size);
+        qemu_free(packet);
+    }
+}
+
+static void
+qemu_enqueue_packet(VLANClientState *sender, const uint8_t *buf, int size)
+{
+    VLANPacket *packet;
+
+    packet = qemu_malloc(sizeof(VLANPacket) + size);
+    packet->next = sender->vlan->send_queue;
+    packet->sender = sender;
+    packet->size = size;
+    memcpy(packet->data, buf, size);
+    sender->vlan->send_queue = packet;
+}
+
 void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
 {
     VLANState *vlan = vc->vlan;
-    VLANPacket *packet;
 
     if (vc->link_down)
         return;
@@ -448,22 +475,12 @@ void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
     hex_dump(stdout, buf, size);
 #endif
     if (vlan->delivering) {
-        packet = qemu_malloc(sizeof(VLANPacket) + size);
-        packet->next = vlan->send_queue;
-        packet->sender = vc;
-        packet->size = size;
-        memcpy(packet->data, buf, size);
-        vlan->send_queue = packet;
-    } else {
-        vlan->delivering = 1;
-        qemu_deliver_packet(vc, buf, size);
-        while ((packet = vlan->send_queue) != NULL) {
-            vlan->send_queue = packet->next;
-            qemu_deliver_packet(packet->sender, packet->data, packet->size);
-            qemu_free(packet);
-        }
-        vlan->delivering = 0;
+        qemu_enqueue_packet(vc, buf, size);
+        return;
     }
+
+    qemu_deliver_packet(vc, buf, size);
+    qemu_flush_queued_packets(vc);
 }
 
 static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
@@ -496,60 +513,84 @@ static ssize_t calc_iov_length(const struct iovec *iov, int iovcnt)
     return offset;
 }
 
-ssize_t qemu_sendv_packet(VLANClientState *sender, const struct iovec *iov,
-                          int iovcnt)
+static int qemu_deliver_packet_iov(VLANClientState *sender,
+                                   const struct iovec *iov, int iovcnt)
 {
-    VLANState *vlan = sender->vlan;
     VLANClientState *vc;
+    int ret = -1;
+
+    sender->vlan->delivering = 1;
+
+    for (vc = sender->vlan->first_client; vc != NULL; vc = vc->next) {
+        ssize_t len;
+
+        if (vc == sender) {
+            continue;
+        }
+
+        if (vc->link_down) {
+            ret = calc_iov_length(iov, iovcnt);
+            continue;
+        }
+
+        if (vc->receive_iov) {
+            len = vc->receive_iov(vc, iov, iovcnt);
+        } else {
+            len = vc_sendv_compat(vc, iov, iovcnt);
+        }
+
+        ret = (ret >= 0) ? ret : len;
+    }
+
+    sender->vlan->delivering = 0;
+
+    return ret;
+}
+
+static ssize_t qemu_enqueue_packet_iov(VLANClientState *sender,
+                                       const struct iovec *iov, int iovcnt)
+{
     VLANPacket *packet;
-    ssize_t max_len = 0;
+    size_t max_len = 0;
     int i;
 
-    if (sender->link_down)
-        return calc_iov_length(iov, iovcnt);
+    max_len = calc_iov_length(iov, iovcnt);
 
-    if (vlan->delivering) {
-        max_len = calc_iov_length(iov, iovcnt);
+    packet = qemu_malloc(sizeof(VLANPacket) + max_len);
+    packet->next = sender->vlan->send_queue;
+    packet->sender = sender;
+    packet->size = 0;
 
-        packet = qemu_malloc(sizeof(VLANPacket) + max_len);
-        packet->next = vlan->send_queue;
-        packet->sender = sender;
-        packet->size = 0;
-        for (i = 0; i < iovcnt; i++) {
-            size_t len = iov[i].iov_len;
+    for (i = 0; i < iovcnt; i++) {
+        size_t len = iov[i].iov_len;
 
-            memcpy(packet->data + packet->size, iov[i].iov_base, len);
-            packet->size += len;
-        }
-        vlan->send_queue = packet;
-    } else {
-        vlan->delivering = 1;
+        memcpy(packet->data + packet->size, iov[i].iov_base, len);
+        packet->size += len;
+    }
 
-        for (vc = vlan->first_client; vc != NULL; vc = vc->next) {
-            ssize_t len = 0;
+    sender->vlan->send_queue = packet;
 
-            if (vc == sender) {
-                continue;
-            }
-            if (vc->link_down) {
-                len = calc_iov_length(iov, iovcnt);
-            } else if (vc->receive_iov) {
-                len = vc->receive_iov(vc, iov, iovcnt);
-            } else if (vc->receive) {
-                len = vc_sendv_compat(vc, iov, iovcnt);
-            }
-            max_len = MAX(max_len, len);
-        }
+    return packet->size;
+}
 
-        while ((packet = vlan->send_queue) != NULL) {
-            vlan->send_queue = packet->next;
-            qemu_deliver_packet(packet->sender, packet->data, packet->size);
-            qemu_free(packet);
-        }
-        vlan->delivering = 0;
+ssize_t qemu_sendv_packet(VLANClientState *sender, const struct iovec *iov,
+                          int iovcnt)
+{
+    int ret;
+
+    if (sender->link_down) {
+        return calc_iov_length(iov, iovcnt);
+    }
+
+    if (sender->vlan->delivering) {
+        return qemu_enqueue_packet_iov(sender, iov, iovcnt);
     }
 
-    return max_len;
+    ret = qemu_deliver_packet_iov(sender, iov, iovcnt);
+
+    qemu_flush_queued_packets(sender);
+
+    return ret;
 }
 
 #if defined(CONFIG_SLIRP)
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Qemu-devel] [PATCH 11/13] net: add qemu_send_packet_async()
  2009-05-22 14:23                   ` [Qemu-devel] [PATCH 10/13] net: split out packet queueing and flushing into separate functions Mark McLoughlin
@ 2009-05-22 14:24                     ` Mark McLoughlin
  2009-05-22 14:24                       ` [Qemu-devel] [PATCH 12/13] net: make use of async packet sending API in tap client Mark McLoughlin
  0 siblings, 1 reply; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-22 14:24 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

Add a qemu_send_packet() variant which will queue up the packet
if it cannot be sent when all client queues are full. It later
invokes the supplied callback when the packet has been sent.

If qemu_send_packet_async() returns zero, the caller is expected
to not send any more packets until the queued packet has been
sent.

Packets are queued iff a receive() handler returns zero (indicating
queue full) and the caller has provided a sent notification callback
(indicating it will stop and start its own queue).

We need the packet sending API to support queueing because:

  - a sending client should process all available packets in one go
    (e.g. virtio-net emptying its tx ring)

  - a receiving client may not be able to handle the packet
    (e.g. -EAGAIN from write() to tapfd)

  - the sending client could detect this condition in advance
    (e.g. by select() for writable on tapfd)

  - that's too much overhead (e.g. a select() call per packet)

  - therefore the sending client must handle the condition by
    dropping the packet or queueing it

  - dropping packets is poor form; we should queue.

However, we don't want queueing to be completely transparent. We
want the sending client to stop sending packets as soon as a
packet is queued. This allows the sending client to be throttled
by the receiver.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 net.c |   83 ++++++++++++++++++++++++++++++++++++++++++++++++----------------
 net.h |    8 ++++++
 2 files changed, 70 insertions(+), 21 deletions(-)

diff --git a/net.c b/net.c
index 2f4743e..3675bc5 100644
--- a/net.c
+++ b/net.c
@@ -439,19 +439,32 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
     return ret;
 }
 
-static void qemu_flush_queued_packets(VLANClientState *vc)
+void qemu_flush_queued_packets(VLANClientState *vc)
 {
     VLANPacket *packet;
 
     while ((packet = vc->vlan->send_queue) != NULL) {
+        int ret;
+
         vc->vlan->send_queue = packet->next;
-        qemu_deliver_packet(packet->sender, packet->data, packet->size);
+
+        ret = qemu_deliver_packet(packet->sender, packet->data, packet->size);
+        if (ret == 0 && packet->sent_cb != NULL) {
+            packet->next = vc->vlan->send_queue;
+            vc->vlan->send_queue = packet;
+            break;
+        }
+
+        if (packet->sent_cb)
+            packet->sent_cb(packet->sender);
+
         qemu_free(packet);
     }
 }
 
-static void
-qemu_enqueue_packet(VLANClientState *sender, const uint8_t *buf, int size)
+static void qemu_enqueue_packet(VLANClientState *sender,
+                                const uint8_t *buf, int size,
+                                NetPacketSent *sent_cb)
 {
     VLANPacket *packet;
 
@@ -459,28 +472,45 @@ qemu_enqueue_packet(VLANClientState *sender, const uint8_t *buf, int size)
     packet->next = sender->vlan->send_queue;
     packet->sender = sender;
     packet->size = size;
+    packet->sent_cb = sent_cb;
     memcpy(packet->data, buf, size);
     sender->vlan->send_queue = packet;
 }
 
-void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
+ssize_t qemu_send_packet_async(VLANClientState *sender,
+                               const uint8_t *buf, int size,
+                               NetPacketSent *sent_cb)
 {
-    VLANState *vlan = vc->vlan;
+    int ret;
 
-    if (vc->link_down)
-        return;
+    if (sender->link_down) {
+        return size;
+    }
 
 #ifdef DEBUG_NET
-    printf("vlan %d send:\n", vlan->id);
+    printf("vlan %d send:\n", sender->vlan->id);
     hex_dump(stdout, buf, size);
 #endif
-    if (vlan->delivering) {
-        qemu_enqueue_packet(vc, buf, size);
-        return;
+
+    if (sender->vlan->delivering) {
+        qemu_enqueue_packet(sender, buf, size, NULL);
+        return size;
     }
 
-    qemu_deliver_packet(vc, buf, size);
-    qemu_flush_queued_packets(vc);
+    ret = qemu_deliver_packet(sender, buf, size);
+    if (ret == 0 && sent_cb != NULL) {
+        qemu_enqueue_packet(sender, buf, size, sent_cb);
+        return 0;
+    }
+
+    qemu_flush_queued_packets(sender);
+
+    return ret;
+}
+
+void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
+{
+    qemu_send_packet_async(vc, buf, size, NULL);
 }
 
 static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
@@ -498,9 +528,7 @@ static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
         offset += len;
     }
 
-    vc->receive(vc, buffer, offset);
-
-    return offset;
+    return vc->receive(vc, buffer, offset);
 }
 
 static ssize_t calc_iov_length(const struct iovec *iov, int iovcnt)
@@ -548,7 +576,8 @@ static int qemu_deliver_packet_iov(VLANClientState *sender,
 }
 
 static ssize_t qemu_enqueue_packet_iov(VLANClientState *sender,
-                                       const struct iovec *iov, int iovcnt)
+                                       const struct iovec *iov, int iovcnt,
+                                       NetPacketSent *sent_cb)
 {
     VLANPacket *packet;
     size_t max_len = 0;
@@ -559,6 +588,7 @@ static ssize_t qemu_enqueue_packet_iov(VLANClientState *sender,
     packet = qemu_malloc(sizeof(VLANPacket) + max_len);
     packet->next = sender->vlan->send_queue;
     packet->sender = sender;
+    packet->sent_cb = sent_cb;
     packet->size = 0;
 
     for (i = 0; i < iovcnt; i++) {
@@ -573,8 +603,9 @@ static ssize_t qemu_enqueue_packet_iov(VLANClientState *sender,
     return packet->size;
 }
 
-ssize_t qemu_sendv_packet(VLANClientState *sender, const struct iovec *iov,
-                          int iovcnt)
+ssize_t qemu_sendv_packet_async(VLANClientState *sender,
+                                const struct iovec *iov, int iovcnt,
+                                NetPacketSent *sent_cb)
 {
     int ret;
 
@@ -583,16 +614,26 @@ ssize_t qemu_sendv_packet(VLANClientState *sender, const struct iovec *iov,
     }
 
     if (sender->vlan->delivering) {
-        return qemu_enqueue_packet_iov(sender, iov, iovcnt);
+        return qemu_enqueue_packet_iov(sender, iov, iovcnt, NULL);
     }
 
     ret = qemu_deliver_packet_iov(sender, iov, iovcnt);
+    if (ret == 0 && sent_cb != NULL) {
+        qemu_enqueue_packet_iov(sender, iov, iovcnt, sent_cb);
+        return 0;
+    }
 
     qemu_flush_queued_packets(sender);
 
     return ret;
 }
 
+ssize_t
+qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov, int iovcnt)
+{
+    return qemu_sendv_packet_async(vc, iov, iovcnt, NULL);
+}
+
 #if defined(CONFIG_SLIRP)
 
 /* slirp network adapter */
diff --git a/net.h b/net.h
index 766edbe..82ca255 100644
--- a/net.h
+++ b/net.h
@@ -32,10 +32,13 @@ struct VLANClientState {
 
 typedef struct VLANPacket VLANPacket;
 
+typedef void (NetPacketSent) (VLANClientState *);
+
 struct VLANPacket {
     struct VLANPacket *next;
     VLANClientState *sender;
     int size;
+    NetPacketSent *sent_cb;
     uint8_t data[0];
 };
 
@@ -62,7 +65,12 @@ VLANClientState *qemu_find_vlan_client(VLANState *vlan, void *opaque);
 int qemu_can_send_packet(VLANClientState *vc);
 ssize_t qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov,
                           int iovcnt);
+ssize_t qemu_sendv_packet_async(VLANClientState *vc, const struct iovec *iov,
+                                int iovcnt, NetPacketSent *sent_cb);
 void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
+ssize_t qemu_send_packet_async(VLANClientState *vc, const uint8_t *buf,
+                               int size, NetPacketSent *sent_cb);
+void qemu_flush_queued_packets(VLANClientState *vc);
 void qemu_format_nic_info_str(VLANClientState *vc, uint8_t macaddr[6]);
 void qemu_check_nic_model(NICInfo *nd, const char *model);
 void qemu_check_nic_model_list(NICInfo *nd, const char * const *models,
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Qemu-devel] [PATCH 12/13] net: make use of async packet sending API in tap client
  2009-05-22 14:24                     ` [Qemu-devel] [PATCH 11/13] net: add qemu_send_packet_async() Mark McLoughlin
@ 2009-05-22 14:24                       ` Mark McLoughlin
  2009-05-22 14:25                         ` [Qemu-devel] [PATCH 13/13] virtio-net: implement rx packet queueing Mark McLoughlin
  0 siblings, 1 reply; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-22 14:24 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

If a packet is queued by qemu_send_packet(), remove I/O
handler for the tap fd until we get notification that the
packet has been sent.

A not insignificant side effect of this is we can now
drain the tap send queue in one go without fear of packets
being dropped.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 net.c |   24 ++++++++++++++++++++----
 1 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/net.c b/net.c
index 3675bc5..4cd041c 100644
--- a/net.c
+++ b/net.c
@@ -934,15 +934,31 @@ static ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)
 }
 #endif
 
+static void tap_send(void *opaque);
+
+static void tap_send_completed(VLANClientState *vc)
+{
+    TAPState *s = vc->opaque;
+
+    qemu_set_fd_handler2(s->fd, tap_can_send, tap_send, NULL, s);
+}
+
 static void tap_send(void *opaque)
 {
     TAPState *s = opaque;
     int size;
 
-    size = tap_read_packet(s->fd, s->buf, sizeof(s->buf));
-    if (size > 0) {
-        qemu_send_packet(s->vc, s->buf, size);
-    }
+    do {
+        size = tap_read_packet(s->fd, s->buf, sizeof(s->buf));
+        if (size <= 0) {
+            break;
+        }
+
+        size = qemu_send_packet_async(s->vc, s->buf, size, tap_send_completed);
+        if (size == 0) {
+            qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+        }
+    } while (size > 0);
 }
 
 static void tap_cleanup(VLANClientState *vc)
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Qemu-devel] [PATCH 13/13] virtio-net: implement rx packet queueing
  2009-05-22 14:24                       ` [Qemu-devel] [PATCH 12/13] net: make use of async packet sending API in tap client Mark McLoughlin
@ 2009-05-22 14:25                         ` Mark McLoughlin
  0 siblings, 0 replies; 19+ messages in thread
From: Mark McLoughlin @ 2009-05-22 14:25 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

If we don't have room to receive a packet, we return zero
from virtio_net_receive() and call qemu_flush_queued_packets()
as soon as space becomes available.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 hw/virtio-net.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 6b34c5a..a3ba890 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -269,6 +269,9 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
 
 static void virtio_net_handle_rx(VirtIODevice *vdev, VirtQueue *vq)
 {
+    VirtIONet *n = to_virtio_net(vdev);
+
+    qemu_flush_queued_packets(n->vc);
 }
 
 static int do_virtio_net_can_receive(VirtIONet *n, int bufsize)
@@ -368,7 +371,7 @@ static ssize_t virtio_net_receive(VLANClientState *vc, const uint8_t *buf, size_
     size_t hdr_len, offset, i;
 
     if (!do_virtio_net_can_receive(n, size))
-        return -1;
+        return 0;
 
     if (!receive_filter(n, buf, size))
         return size;
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2009-05-22 14:25 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-19  9:55 [Qemu-devel] [PATCH 0/13] Add generic packet buffering API Mark McLoughlin
2009-05-19  9:55 ` [Qemu-devel] [PATCH 01/13] net: factor tap_read_packet() out of tap_send() Mark McLoughlin
2009-05-19  9:55   ` [Qemu-devel] [PATCH 02/13] net: move the tap buffer into TAPState Mark McLoughlin
2009-05-19  9:55     ` [Qemu-devel] [PATCH 03/13] net: vlan clients with no fd_can_read() can always receive Mark McLoughlin
2009-05-19  9:55       ` [Qemu-devel] [PATCH 04/13] net: only read from tapfd when we can send Mark McLoughlin
2009-05-19  9:55         ` [Qemu-devel] [PATCH 05/13] net: add fd_readv() handler to qemu_new_vlan_client() args Mark McLoughlin
2009-05-19  9:55           ` [Qemu-devel] [PATCH 06/13] net: re-name vc->fd_read() to vc->receive() Mark McLoughlin
2009-05-19  9:55             ` [Qemu-devel] [PATCH 07/13] net: pass VLANClientState* as first arg to receive handlers Mark McLoughlin
2009-05-19  9:55               ` [Qemu-devel] [PATCH 08/13] net: add return value to packet receive handler Mark McLoughlin
2009-05-19  9:55                 ` [Qemu-devel] [PATCH 09/13] net: return status from qemu_deliver_packet() Mark McLoughlin
2009-05-22 14:23                   ` [Qemu-devel] [PATCH 10/13] net: split out packet queueing and flushing into separate functions Mark McLoughlin
2009-05-22 14:24                     ` [Qemu-devel] [PATCH 11/13] net: add qemu_send_packet_async() Mark McLoughlin
2009-05-22 14:24                       ` [Qemu-devel] [PATCH 12/13] net: make use of async packet sending API in tap client Mark McLoughlin
2009-05-22 14:25                         ` [Qemu-devel] [PATCH 13/13] virtio-net: implement rx packet queueing Mark McLoughlin
2009-05-19 10:18 ` [Qemu-devel] [PATCH 0/13] Add generic packet buffering API Avi Kivity
2009-05-19 10:33   ` Mark McLoughlin
2009-05-19 11:56     ` Avi Kivity
2009-05-22 13:43 ` [Qemu-devel] " Anthony Liguori
2009-05-22 14:23   ` Mark McLoughlin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).