qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] net: QEMU_NET_PACKET_FLAG_MORE introduced


From: Michael S. Tsirkin
Subject: Re: [Qemu-devel] [PATCH] net: QEMU_NET_PACKET_FLAG_MORE introduced
Date: Sun, 8 Dec 2013 14:11:17 +0200

On Fri, Dec 06, 2013 at 03:44:33PM +0100, Vincenzo Maffione wrote:
> This patch extends the frontend-backend interface so that it is possible
> to pass a new flag (QEMU_NET_PACKET_FLAG_MORE) when sending a packet to the
> other peer. The new flag acts as a hint for the receiving peer, which can
> accumulate a batch of packets before forwarding those packets (to the host
> if the receiving peer is the backend or to the guest if the receiving peer
> is the frontend).
> 
> The patch also implements a batching mechanism for the netmap backend (on the
> backend receive side) and for the e1000 and virtio frontends (on the frontend
> transmit side).
> 
> Measured improvement of a guest-to-guest UDP_STREAM netperf test (64 bytes
> packets) with virtio-net frontends:
>     820 Kpps ==> 1000 Kpps (+22%).
> 
> Measured improvement of a guest-to-guest UDP test (64 bytes packets) with
> e1000 frontends and netmap clients on the guests:
>     1.8 Mpps ==> 3.1 Mpps (+72%).
> 
> Signed-off-by: Vincenzo Maffione <address@hidden>

So we are batching some more and this helps throughput. However I wonder
what this does to a more bursty traffic, such as
several TCP streams running in parallel.


> ---
> Experiment details:
>     - Processor: Intel i7-3770K CPU @ 3.50GHz (8 cores)
>     - Memory @ 1333 MHz
>     - Host O.S.: Archlinux with Linux 3.11
>     - Guest O.S.: Archlinux with Linux 3.11
> 
> QEMU command line for the virtio experiment:
>     qemu-system-x86_64 archdisk.qcow -snapshot -enable-kvm -device 
> virtio-net-pci,ioeventfd=on,mac=00:AA:BB:CC:DD:01,netdev=mynet -netdev 
> netmap,ifname=vale0:01,id=mynet -smp 2 -vga std -m 3G
> 
> QEMU command line for the e1000 experiment:
>     qemu-system-x86_64 archdisk.qcow -snapshot -enable-kvm -device 
> e1000,mitigation=off,mac=00:AA:BB:CC:DD:01,netdev=mynet -netdev 
> netmap,ifname=vale0:01,id=mynet -smp 2 -vga std -m 3G
> 
> With the e1000 experiments, we don't use netperf on the guests, but netmap 
> clients (pkt-gen)
> that run directly on the e1000 adapter, bypassing the O.S. stack.
> 
> Other things:
>     - This patch is against the net-next tree 
> (https://github.com/stefanha/qemu.git)
>       because the first netmap patch is not in the qemu master (AFAIK).
>     - The batching can also be implemented on the backend transmit side and 
> frontend
>       receive side. We could do it in the future.
> 
>  hw/net/cadence_gem.c    |  3 ++-
>  hw/net/dp8393x.c        |  5 +++--
>  hw/net/e1000.c          | 21 ++++++++++++++++-----
>  hw/net/eepro100.c       |  5 +++--
>  hw/net/etraxfs_eth.c    |  5 +++--
>  hw/net/lan9118.c        |  2 +-
>  hw/net/mcf_fec.c        |  5 +++--
>  hw/net/mipsnet.c        |  6 ++++--
>  hw/net/ne2000.c         |  5 +++--
>  hw/net/ne2000.h         |  3 ++-
>  hw/net/opencores_eth.c  |  2 +-
>  hw/net/pcnet.c          |  8 +++++---
>  hw/net/pcnet.h          |  3 ++-
>  hw/net/rtl8139.c        |  7 ++++---
>  hw/net/smc91c111.c      |  5 +++--
>  hw/net/spapr_llan.c     |  2 +-
>  hw/net/stellaris_enet.c |  3 ++-
>  hw/net/virtio-net.c     | 10 ++++++++--
>  hw/net/vmxnet3.c        |  3 ++-
>  hw/net/vmxnet_tx_pkt.c  |  4 ++--
>  hw/net/xgmac.c          |  2 +-
>  hw/net/xilinx_axienet.c |  2 +-
>  hw/usb/dev-network.c    |  8 +++++---
>  include/net/net.h       | 20 +++++++++++++-------
>  include/net/queue.h     |  1 +
>  net/dump.c              |  3 ++-
>  net/hub.c               | 10 ++++++----
>  net/net.c               | 39 +++++++++++++++++++++++----------------
>  net/netmap.c            | 17 ++++++++++++-----
>  net/slirp.c             |  5 +++--
>  net/socket.c            | 10 ++++++----
>  net/tap-win32.c         |  2 +-
>  net/tap.c               | 12 +++++++-----
>  net/vde.c               |  5 +++--
>  savevm.c                |  2 +-
>  35 files changed, 155 insertions(+), 90 deletions(-)
> 
> diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
> index 4a355bb..432687a 100644
> --- a/hw/net/cadence_gem.c
> +++ b/hw/net/cadence_gem.c
> @@ -583,7 +583,8 @@ static int gem_mac_address_filter(GemState *s, const 
> uint8_t *packet)
>   * gem_receive:
>   * Fit a packet handed to us by QEMU into the receive descriptor ring.
>   */
> -static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t 
> size)
> +static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t 
> size,
> +                           unsigned flags)
>  {
>      unsigned    desc[2];
>      hwaddr packet_desc_addr, last_desc_addr;
> diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
> index 789d385..d8c7da8 100644
> --- a/hw/net/dp8393x.c
> +++ b/hw/net/dp8393x.c
> @@ -415,7 +415,7 @@ static void do_transmit_packets(dp8393xState *s)
>              }
>          } else {
>              /* Transmit packet */
> -            qemu_send_packet(nc, s->tx_buffer, tx_len);
> +            qemu_send_packet(nc, s->tx_buffer, tx_len, 0);
>          }
>          s->regs[SONIC_TCR] |= SONIC_TCR_PTX;
>  
> @@ -723,7 +723,8 @@ static int receive_filter(dp8393xState *s, const uint8_t 
> * buf, int size)
>      return -1;
>  }
>  
> -static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t 
> size)
> +static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf,
> +                           size_t size, unsigned flags)
>  {
>      dp8393xState *s = qemu_get_nic_opaque(nc);
>      uint16_t data[10];
> diff --git a/hw/net/e1000.c b/hw/net/e1000.c
> index ae63591..5294ec5 100644
> --- a/hw/net/e1000.c
> +++ b/hw/net/e1000.c
> @@ -570,10 +570,19 @@ static void
>  e1000_send_packet(E1000State *s, const uint8_t *buf, int size)
>  {
>      NetClientState *nc = qemu_get_queue(s->nic);
> +    uint32_t tdh = s->mac_reg[TDH];
> +    unsigned flags = QEMU_NET_PACKET_FLAG_MORE;
> +
>      if (s->phy_reg[PHY_CTRL] & MII_CR_LOOPBACK) {
> -        nc->info->receive(nc, buf, size);
> +        nc->info->receive(nc, buf, size, 0);
>      } else {
> -        qemu_send_packet(nc, buf, size);
> +        if (++tdh * sizeof(struct e1000_tx_desc) >= s->mac_reg[TDLEN]) {
> +            tdh = 0;
> +        }
> +        if (tdh == s->mac_reg[TDT]) {
> +            flags = 0;
> +        }
> +        qemu_send_packet(nc, buf, size, flags);
>      }
>  }
>  
> @@ -899,7 +908,8 @@ static uint64_t rx_desc_base(E1000State *s)
>  }
>  
>  static ssize_t
> -e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
> +e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt,
> +                  unsigned flags)
>  {
>      E1000State *s = qemu_get_nic_opaque(nc);
>      PCIDevice *d = PCI_DEVICE(s);
> @@ -1054,14 +1064,15 @@ e1000_receive_iov(NetClientState *nc, const struct 
> iovec *iov, int iovcnt)
>  }
>  
>  static ssize_t
> -e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size)
> +e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size,
> +              unsigned flags)
>  {
>      const struct iovec iov = {
>          .iov_base = (uint8_t *)buf,
>          .iov_len = size
>      };
>  
> -    return e1000_receive_iov(nc, &iov, 1);
> +    return e1000_receive_iov(nc, &iov, 1, flags);
>  }
>  
>  static uint32_t
> diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
> index 3b891ca..9763904 100644
> --- a/hw/net/eepro100.c
> +++ b/hw/net/eepro100.c
> @@ -828,7 +828,7 @@ static void tx_command(EEPRO100State *s)
>          }
>      }
>      TRACE(RXTX, logout("%p sending frame, len=%d,%s\n", s, size, 
> nic_dump(buf, size)));
> -    qemu_send_packet(qemu_get_queue(s->nic), buf, size);
> +    qemu_send_packet(qemu_get_queue(s->nic), buf, size, 0);
>      s->statistics.tx_good_frames++;
>      /* Transmit with bad status would raise an CX/TNO interrupt.
>       * (82557 only). Emulation never has bad status. */
> @@ -1627,7 +1627,8 @@ static int nic_can_receive(NetClientState *nc)
>  #endif
>  }
>  
> -static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t 
> size)
> +static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf,
> +                           size_t size, unsigned flags)
>  {
>      /* TODO:
>       * - Magic packets should set bit 30 in power management driver register.
> diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c
> index 78ebbbc..6cba74e 100644
> --- a/hw/net/etraxfs_eth.c
> +++ b/hw/net/etraxfs_eth.c
> @@ -525,7 +525,8 @@ static int eth_can_receive(NetClientState *nc)
>      return 1;
>  }
>  
> -static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t 
> size)
> +static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t 
> size,
> +                           unsigned flags)
>  {
>      unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
>      ETRAXFSEthState *eth = qemu_get_nic_opaque(nc);
> @@ -560,7 +561,7 @@ static int eth_tx_push(void *opaque, unsigned char *buf, 
> int len, bool eop)
>      ETRAXFSEthState *eth = opaque;
>  
>      D(printf("%s buf=%p len=%d\n", __func__, buf, len));
> -    qemu_send_packet(qemu_get_queue(eth->nic), buf, len);
> +    qemu_send_packet(qemu_get_queue(eth->nic), buf, len, 0);
>      return len;
>  }
>  
> diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
> index 2315f99..55e06a9 100644
> --- a/hw/net/lan9118.c
> +++ b/hw/net/lan9118.c
> @@ -664,7 +664,7 @@ static void do_tx_packet(lan9118_state *s)
>          /* This assumes the receive routine doesn't touch the VLANClient.  */
>          lan9118_receive(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
>      } else {
> -        qemu_send_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
> +        qemu_send_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len, 
> 0);
>      }
>      s->txp->fifo_used = 0;
>  
> diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c
> index 4bff3de..14ed0dd 100644
> --- a/hw/net/mcf_fec.c
> +++ b/hw/net/mcf_fec.c
> @@ -174,7 +174,7 @@ static void mcf_fec_do_tx(mcf_fec_state *s)
>          if (bd.flags & FEC_BD_L) {
>              /* Last buffer in frame.  */
>              DPRINTF("Sending packet\n");
> -            qemu_send_packet(qemu_get_queue(s->nic), frame, len);
> +            qemu_send_packet(qemu_get_queue(s->nic), frame, len, 0);
>              ptr = frame;
>              frame_size = 0;
>              s->eir |= FEC_INT_TXF;
> @@ -357,7 +357,8 @@ static int mcf_fec_can_receive(NetClientState *nc)
>      return s->rx_enabled;
>  }
>  
> -static ssize_t mcf_fec_receive(NetClientState *nc, const uint8_t *buf, 
> size_t size)
> +static ssize_t mcf_fec_receive(NetClientState *nc, const uint8_t *buf,
> +                               size_t size, unsigned flags)
>  {
>      mcf_fec_state *s = qemu_get_nic_opaque(nc);
>      mcf_fec_bd bd;
> diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c
> index e421b86..7f5d4c4 100644
> --- a/hw/net/mipsnet.c
> +++ b/hw/net/mipsnet.c
> @@ -74,7 +74,8 @@ static int mipsnet_can_receive(NetClientState *nc)
>      return !mipsnet_buffer_full(s);
>  }
>  
> -static ssize_t mipsnet_receive(NetClientState *nc, const uint8_t *buf, 
> size_t size)
> +static ssize_t mipsnet_receive(NetClientState *nc, const uint8_t *buf,
> +                               size_t size, unsigned flags)
>  {
>      MIPSnetState *s = qemu_get_nic_opaque(nc);
>  
> @@ -176,7 +177,8 @@ static void mipsnet_ioport_write(void *opaque, hwaddr 
> addr,
>          if (s->tx_written == s->tx_count) {
>              /* Send buffer. */
>              trace_mipsnet_send(s->tx_count);
> -            qemu_send_packet(qemu_get_queue(s->nic), s->tx_buffer, 
> s->tx_count);
> +            qemu_send_packet(qemu_get_queue(s->nic), s->tx_buffer,
> +                             s->tx_count, 0);
>              s->tx_count = s->tx_written = 0;
>              s->intctl |= MIPSNET_INTCTL_TXDONE;
>              s->busy = 1;
> diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
> index 4c32e9e..52af46a 100644
> --- a/hw/net/ne2000.c
> +++ b/hw/net/ne2000.c
> @@ -176,7 +176,8 @@ int ne2000_can_receive(NetClientState *nc)
>  
>  #define MIN_BUF_SIZE 60
>  
> -ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
> +ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_,
> +                       unsigned flags)
>  {
>      NE2000State *s = qemu_get_nic_opaque(nc);
>      int size = size_;
> @@ -301,7 +302,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t 
> addr, uint32_t val)
>                  /* fail safe: check range on the transmitted length  */
>                  if (index + s->tcnt <= NE2000_PMEM_END) {
>                      qemu_send_packet(qemu_get_queue(s->nic), s->mem + index,
> -                                     s->tcnt);
> +                                     s->tcnt, 0);
>                  }
>                  /* signal end of transfer */
>                  s->tsr = ENTSR_PTX;
> diff --git a/hw/net/ne2000.h b/hw/net/ne2000.h
> index e500306..b62a8f3 100644
> --- a/hw/net/ne2000.h
> +++ b/hw/net/ne2000.h
> @@ -35,6 +35,7 @@ void ne2000_setup_io(NE2000State *s, DeviceState *dev, 
> unsigned size);
>  extern const VMStateDescription vmstate_ne2000;
>  void ne2000_reset(NE2000State *s);
>  int ne2000_can_receive(NetClientState *nc);
> -ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_);
> +ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_,
> +                       unsigned flags);
>  
>  #endif
> diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c
> index 4118d54..b4328ea 100644
> --- a/hw/net/opencores_eth.c
> +++ b/hw/net/opencores_eth.c
> @@ -503,7 +503,7 @@ static void open_eth_start_xmit(OpenEthState *s, desc *tx)
>      if (tx_len > len) {
>          memset(buf + len, 0, tx_len - len);
>      }
> -    qemu_send_packet(qemu_get_queue(s->nic), buf, tx_len);
> +    qemu_send_packet(qemu_get_queue(s->nic), buf, tx_len, 0);
>  
>      if (tx->len_flags & TXD_WR) {
>          s->tx_desc = 0;
> diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
> index 7cb47b3..707ac92 100644
> --- a/hw/net/pcnet.c
> +++ b/hw/net/pcnet.c
> @@ -1019,7 +1019,8 @@ int pcnet_can_receive(NetClientState *nc)
>  
>  #define MIN_BUF_SIZE 60
>  
> -ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
> +ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_,
> +                      unsigned flags)
>  {
>      PCNetState *s = qemu_get_nic_opaque(nc);
>      int is_padr = 0, is_bcast = 0, is_ladr = 0;
> @@ -1265,12 +1266,13 @@ 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(qemu_get_queue(s->nic), s->buffer, 
> s->xmit_pos);
> +                pcnet_receive(qemu_get_queue(s->nic), s->buffer,
> +                              s->xmit_pos, 0);
>                  s->looptest = 0;
>              } else
>                  if (s->nic)
>                      qemu_send_packet(qemu_get_queue(s->nic), s->buffer,
> -                                     s->xmit_pos);
> +                                     s->xmit_pos, 0);
>  
>              s->csr[0] &= ~0x0008;   /* clear TDMD */
>              s->csr[4] |= 0x0004;    /* set TXSTRT */
> diff --git a/hw/net/pcnet.h b/hw/net/pcnet.h
> index 9dee6f3..a26aacd 100644
> --- a/hw/net/pcnet.h
> +++ b/hw/net/pcnet.h
> @@ -61,7 +61,8 @@ void pcnet_ioport_writel(void *opaque, uint32_t addr, 
> uint32_t val);
>  uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr);
>  uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
>  int pcnet_can_receive(NetClientState *nc);
> -ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_);
> +ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_,
> +                      unsigned flags);
>  void pcnet_set_link_status(NetClientState *nc);
>  void pcnet_common_cleanup(PCNetState *d);
>  int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info);
> diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
> index 7f2b4db..340331f 100644
> --- a/hw/net/rtl8139.c
> +++ b/hw/net/rtl8139.c
> @@ -1195,7 +1195,8 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, 
> const uint8_t *buf, size_t
>      return size_;
>  }
>  
> -static ssize_t rtl8139_receive(NetClientState *nc, const uint8_t *buf, 
> size_t size)
> +static ssize_t rtl8139_receive(NetClientState *nc, const uint8_t *buf,
> +                               size_t size, unsigned flags)
>  {
>      return rtl8139_do_receive(nc, buf, size, 1);
>  }
> @@ -1814,9 +1815,9 @@ static void rtl8139_transfer_frame(RTL8139State *s, 
> uint8_t *buf, int size,
>      else
>      {
>          if (iov) {
> -            qemu_sendv_packet(qemu_get_queue(s->nic), iov, 3);
> +            qemu_sendv_packet(qemu_get_queue(s->nic), iov, 3, 0);
>          } else {
> -            qemu_send_packet(qemu_get_queue(s->nic), buf, size);
> +            qemu_send_packet(qemu_get_queue(s->nic), buf, size, 0);
>          }
>      }
>  }
> diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
> index a8e29b3..82289aa 100644
> --- a/hw/net/smc91c111.c
> +++ b/hw/net/smc91c111.c
> @@ -242,7 +242,7 @@ static void smc91c111_do_tx(smc91c111_state *s)
>              smc91c111_release_packet(s, packetnum);
>          else if (s->tx_fifo_done_len < NUM_PACKETS)
>              s->tx_fifo_done[s->tx_fifo_done_len++] = packetnum;
> -        qemu_send_packet(qemu_get_queue(s->nic), p, len);
> +        qemu_send_packet(qemu_get_queue(s->nic), p, len, 0);
>      }
>      s->tx_fifo_len = 0;
>      smc91c111_update(s);
> @@ -647,7 +647,8 @@ static int smc91c111_can_receive(NetClientState *nc)
>      return 1;
>  }
>  
> -static ssize_t smc91c111_receive(NetClientState *nc, const uint8_t *buf, 
> size_t size)
> +static ssize_t smc91c111_receive(NetClientState *nc, const uint8_t *buf,
> +                                 size_t size, unsigned flags)
>  {
>      smc91c111_state *s = qemu_get_nic_opaque(nc);
>      int status;
> diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
> index 1bd6f50..1a50bc1 100644
> --- a/hw/net/spapr_llan.c
> +++ b/hw/net/spapr_llan.c
> @@ -476,7 +476,7 @@ static target_ulong h_send_logical_lan(PowerPCCPU *cpu, 
> sPAPREnvironment *spapr,
>          p += VLAN_BD_LEN(bufs[i]);
>      }
>  
> -    qemu_send_packet(qemu_get_queue(dev->nic), lbuf, total_len);
> +    qemu_send_packet(qemu_get_queue(dev->nic), lbuf, total_len, 0);
>  
>      return H_SUCCESS;
>  }
> diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
> index 9dd77f7..950b455 100644
> --- a/hw/net/stellaris_enet.c
> +++ b/hw/net/stellaris_enet.c
> @@ -83,7 +83,8 @@ static void stellaris_enet_update(stellaris_enet_state *s)
>  }
>  
>  /* TODO: Implement MAC address filtering.  */
> -static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t 
> *buf, size_t size)
> +static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf,
> +                                      size_t size, unsigned flags)
>  {
>      stellaris_enet_state *s = qemu_get_nic_opaque(nc);
>      int n;
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 513c168..b25bc4e 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -938,7 +938,8 @@ static int receive_filter(VirtIONet *n, const uint8_t 
> *buf, int size)
>      return 0;
>  }
>  
> -static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, 
> size_t size)
> +static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf,
> +                                  size_t size, unsigned flags)
>  {
>      VirtIONet *n = qemu_get_nic_opaque(nc);
>      VirtIONetQueue *q = virtio_net_get_subqueue(nc);
> @@ -1079,6 +1080,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
>          unsigned int out_num = elem.out_num;
>          struct iovec *out_sg = &elem.out_sg[0];
>          struct iovec sg[VIRTQUEUE_MAX_SIZE];
> +        unsigned flags = QEMU_NET_PACKET_FLAG_MORE;
>  
>          if (out_num < 1) {
>              error_report("virtio-net header not in first element");
> @@ -1104,8 +1106,12 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
>  
>          len = n->guest_hdr_len;
>  
> +        if (num_packets + 1 >= n->tx_burst || virtio_queue_empty(q->tx_vq)) {
> +                flags = 0;
> +        }
>          ret = qemu_sendv_packet_async(qemu_get_subqueue(n->nic, queue_index),
> -                                      out_sg, out_num, 
> virtio_net_tx_complete);
> +                                      out_sg, out_num, 
> virtio_net_tx_complete,
> +                                      flags);
>          if (ret == 0) {
>              virtio_queue_set_notification(q->tx_vq, 0);
>              q->async_tx.elem = elem;
> diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
> index 19687aa..6bd59d0 100644
> --- a/hw/net/vmxnet3.c
> +++ b/hw/net/vmxnet3.c
> @@ -1817,7 +1817,8 @@ vmxnet3_rx_filter_may_indicate(VMXNET3State *s, const 
> void *data,
>  }
>  
>  static ssize_t
> -vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size)
> +vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size,
> +                unsigned flags)
>  {
>      VMXNET3State *s = qemu_get_nic_opaque(nc);
>      size_t bytes_indicated;
> diff --git a/hw/net/vmxnet_tx_pkt.c b/hw/net/vmxnet_tx_pkt.c
> index f7344c4..12d842e 100644
> --- a/hw/net/vmxnet_tx_pkt.c
> +++ b/hw/net/vmxnet_tx_pkt.c
> @@ -526,7 +526,7 @@ static bool vmxnet_tx_pkt_do_sw_fragmentation(struct 
> VmxnetTxPkt *pkt,
>  
>          eth_fix_ip4_checksum(l3_iov_base, l3_iov_len);
>  
> -        qemu_sendv_packet(nc, fragment, dst_idx);
> +        qemu_sendv_packet(nc, fragment, dst_idx, 0);
>  
>          fragment_offset += fragment_len;
>  
> @@ -559,7 +559,7 @@ bool vmxnet_tx_pkt_send(struct VmxnetTxPkt *pkt, 
> NetClientState *nc)
>      if (pkt->has_virt_hdr ||
>          pkt->virt_hdr.gso_type == VIRTIO_NET_HDR_GSO_NONE) {
>          qemu_sendv_packet(nc, pkt->vec,
> -            pkt->payload_frags + VMXNET_TX_PKT_PL_START_FRAG);
> +            pkt->payload_frags + VMXNET_TX_PKT_PL_START_FRAG, 0);
>          return true;
>      }
>  
> diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c
> index 9384fa0..683a5ad 100644
> --- a/hw/net/xgmac.c
> +++ b/hw/net/xgmac.c
> @@ -239,7 +239,7 @@ static void xgmac_enet_send(XgmacState *s)
>          frame_size += len;
>          if (bd.ctl_stat & 0x20000000) {
>              /* Last buffer in frame.  */
> -            qemu_send_packet(qemu_get_queue(s->nic), frame, len);
> +            qemu_send_packet(qemu_get_queue(s->nic), frame, len, 0);
>              ptr = frame;
>              frame_size = 0;
>              s->regs[DMA_STATUS] |= DMA_STATUS_TI | DMA_STATUS_NIS;
> diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
> index 3eb7715..9dd44bf 100644
> --- a/hw/net/xilinx_axienet.c
> +++ b/hw/net/xilinx_axienet.c
> @@ -919,7 +919,7 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t 
> *buf, size_t size)
>          buf[write_off + 1] = csum & 0xff;
>      }
>  
> -    qemu_send_packet(qemu_get_queue(s->nic), buf, size);
> +    qemu_send_packet(qemu_get_queue(s->nic), buf, size, 0);
>  
>      s->stats.tx_bytes += size;
>      s->regs[R_IS] |= IS_TX_COMPLETE;
> diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
> index 4c532b7..253878c 100644
> --- a/hw/usb/dev-network.c
> +++ b/hw/usb/dev-network.c
> @@ -1196,7 +1196,7 @@ static void usb_net_handle_dataout(USBNetState *s, 
> USBPacket *p)
>  
>      if (!is_rndis(s)) {
>          if (p->iov.size < 64) {
> -            qemu_send_packet(qemu_get_queue(s->nic), s->out_buf, s->out_ptr);
> +            qemu_send_packet(qemu_get_queue(s->nic), s->out_buf, s->out_ptr, 
> 0);
>              s->out_ptr = 0;
>          }
>          return;
> @@ -1209,7 +1209,8 @@ static void usb_net_handle_dataout(USBNetState *s, 
> USBPacket *p)
>          uint32_t offs = 8 + le32_to_cpu(msg->DataOffset);
>          uint32_t size = le32_to_cpu(msg->DataLength);
>          if (offs + size <= len)
> -            qemu_send_packet(qemu_get_queue(s->nic), s->out_buf + offs, 
> size);
> +            qemu_send_packet(qemu_get_queue(s->nic), s->out_buf + offs,
> +                             size, 0);
>      }
>      s->out_ptr -= len;
>      memmove(s->out_buf, &s->out_buf[len], s->out_ptr);
> @@ -1259,7 +1260,8 @@ static void usb_net_handle_data(USBDevice *dev, 
> USBPacket *p)
>      }
>  }
>  
> -static ssize_t usbnet_receive(NetClientState *nc, const uint8_t *buf, size_t 
> size)
> +static ssize_t usbnet_receive(NetClientState *nc, const uint8_t *buf,
> +                              size_t size, unsigned flags)
>  {
>      USBNetState *s = qemu_get_nic_opaque(nc);
>      uint8_t *in_buf = s->in_buf;
> diff --git a/include/net/net.h b/include/net/net.h
> index 11e1468..d3f0ad6 100644
> --- a/include/net/net.h
> +++ b/include/net/net.h
> @@ -44,8 +44,10 @@ typedef struct NICConf {
>  
>  typedef void (NetPoll)(NetClientState *, bool enable);
>  typedef int (NetCanReceive)(NetClientState *);
> -typedef ssize_t (NetReceive)(NetClientState *, const uint8_t *, size_t);
> -typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, int);
> +typedef ssize_t (NetReceive)(NetClientState *, const uint8_t *, size_t,
> +                 unsigned);
> +typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, int,
> +                                unsigned);
>  typedef void (NetCleanup) (NetClientState *);
>  typedef void (LinkStatusChanged)(NetClientState *);
>  typedef void (NetClientDestructor)(NetClientState *);
> @@ -110,13 +112,17 @@ typedef void (*qemu_nic_foreach)(NICState *nic, void 
> *opaque);
>  void qemu_foreach_nic(qemu_nic_foreach func, void *opaque);
>  int qemu_can_send_packet(NetClientState *nc);
>  ssize_t qemu_sendv_packet(NetClientState *nc, const struct iovec *iov,
> -                          int iovcnt);
> +                          int iovcnt, unsigned flags);
>  ssize_t qemu_sendv_packet_async(NetClientState *nc, const struct iovec *iov,
> -                                int iovcnt, NetPacketSent *sent_cb);
> -void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
> -ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int 
> size);
> +                                int iovcnt, NetPacketSent *sent_cb,
> +                                unsigned flags);
> +void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size,
> +                      unsigned flags);
> +ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int 
> size,
> +                             unsigned flags);
>  ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf,
> -                               int size, NetPacketSent *sent_cb);
> +                               int size, NetPacketSent *sent_cb,
> +                               unsigned flags);
>  void qemu_purge_queued_packets(NetClientState *nc);
>  void qemu_flush_queued_packets(NetClientState *nc);
>  void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]);
> diff --git a/include/net/queue.h b/include/net/queue.h
> index fc02b33..1d136a6 100644
> --- a/include/net/queue.h
> +++ b/include/net/queue.h
> @@ -33,6 +33,7 @@ typedef void (NetPacketSent) (NetClientState *sender, 
> ssize_t ret);
>  
>  #define QEMU_NET_PACKET_FLAG_NONE  0
>  #define QEMU_NET_PACKET_FLAG_RAW  (1<<0)
> +#define QEMU_NET_PACKET_FLAG_MORE (2<<0)
>  
>  NetQueue *qemu_new_net_queue(void *opaque);
>  
> diff --git a/net/dump.c b/net/dump.c
> index 9d3a09e..f718d5c 100644
> --- a/net/dump.c
> +++ b/net/dump.c
> @@ -57,7 +57,8 @@ struct pcap_sf_pkthdr {
>      uint32_t len;
>  };
>  
> -static ssize_t dump_receive(NetClientState *nc, const uint8_t *buf, size_t 
> size)
> +static ssize_t dump_receive(NetClientState *nc, const uint8_t *buf,
> +                            size_t size, unsigned flags)
>  {
>      DumpState *s = DO_UPCAST(DumpState, nc, nc);
>      struct pcap_sf_pkthdr hdr;
> diff --git a/net/hub.c b/net/hub.c
> index 33a99c9..7adca5d 100644
> --- a/net/hub.c
> +++ b/net/hub.c
> @@ -52,7 +52,7 @@ static ssize_t net_hub_receive(NetHub *hub, NetHubPort 
> *source_port,
>              continue;
>          }
>  
> -        qemu_send_packet(&port->nc, buf, len);
> +        qemu_send_packet(&port->nc, buf, len, 0);
>      }
>      return len;
>  }
> @@ -68,7 +68,7 @@ static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort 
> *source_port,
>              continue;
>          }
>  
> -        qemu_sendv_packet(&port->nc, iov, iovcnt);
> +        qemu_sendv_packet(&port->nc, iov, iovcnt, 0);
>      }
>      return len;
>  }
> @@ -107,7 +107,8 @@ static int net_hub_port_can_receive(NetClientState *nc)
>  }
>  
>  static ssize_t net_hub_port_receive(NetClientState *nc,
> -                                    const uint8_t *buf, size_t len)
> +                                    const uint8_t *buf, size_t len,
> +                                    unsigned flags)
>  {
>      NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
>  
> @@ -115,7 +116,8 @@ static ssize_t net_hub_port_receive(NetClientState *nc,
>  }
>  
>  static ssize_t net_hub_port_receive_iov(NetClientState *nc,
> -                                        const struct iovec *iov, int iovcnt)
> +                                        const struct iovec *iov, int iovcnt,
> +                                        unsigned flags)
>  {
>      NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
>  
> diff --git a/net/net.c b/net/net.c
> index 9db88cc..65cf5f1 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -414,9 +414,10 @@ ssize_t qemu_deliver_packet(NetClientState *sender,
>      }
>  
>      if (flags & QEMU_NET_PACKET_FLAG_RAW && nc->info->receive_raw) {
> -        ret = nc->info->receive_raw(nc, data, size);
> +        ret = nc->info->receive_raw(nc, data, size,
> +                                    flags & ~QEMU_NET_PACKET_FLAG_RAW);
>      } else {
> -        ret = nc->info->receive(nc, data, size);
> +        ret = nc->info->receive(nc, data, size, flags);
>      }
>  
>      if (ret == 0) {
> @@ -475,32 +476,36 @@ static ssize_t 
> qemu_send_packet_async_with_flags(NetClientState *sender,
>  
>  ssize_t qemu_send_packet_async(NetClientState *sender,
>                                 const uint8_t *buf, int size,
> -                               NetPacketSent *sent_cb)
> +                               NetPacketSent *sent_cb, unsigned flags)
>  {
> -    return qemu_send_packet_async_with_flags(sender, 
> QEMU_NET_PACKET_FLAG_NONE,
> +    return qemu_send_packet_async_with_flags(sender,
> +                                             flags | 
> QEMU_NET_PACKET_FLAG_NONE,
>                                               buf, size, sent_cb);
>  }
>  
> -void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
> +void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size,
> +                      unsigned flags)
>  {
> -    qemu_send_packet_async(nc, buf, size, NULL);
> +    qemu_send_packet_async(nc, buf, size, NULL, flags);
>  }
>  
> -ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int 
> size)
> +ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int 
> size,
> +                             unsigned flags)
>  {
> -    return qemu_send_packet_async_with_flags(nc, QEMU_NET_PACKET_FLAG_RAW,
> +    return qemu_send_packet_async_with_flags(nc,
> +                                             QEMU_NET_PACKET_FLAG_RAW | 
> flags,
>                                               buf, size, NULL);
>  }
>  
>  static ssize_t nc_sendv_compat(NetClientState *nc, const struct iovec *iov,
> -                               int iovcnt)
> +                               int iovcnt, unsigned flags)
>  {
>      uint8_t buffer[NET_BUFSIZE];
>      size_t offset;
>  
>      offset = iov_to_buf(iov, iovcnt, 0, buffer, sizeof(buffer));
>  
> -    return nc->info->receive(nc, buffer, offset);
> +    return nc->info->receive(nc, buffer, offset, flags);
>  }
>  
>  ssize_t qemu_deliver_packet_iov(NetClientState *sender,
> @@ -521,9 +526,9 @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
>      }
>  
>      if (nc->info->receive_iov) {
> -        ret = nc->info->receive_iov(nc, iov, iovcnt);
> +        ret = nc->info->receive_iov(nc, iov, iovcnt, flags);
>      } else {
> -        ret = nc_sendv_compat(nc, iov, iovcnt);
> +        ret = nc_sendv_compat(nc, iov, iovcnt, flags);
>      }
>  
>      if (ret == 0) {
> @@ -535,7 +540,8 @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
>  
>  ssize_t qemu_sendv_packet_async(NetClientState *sender,
>                                  const struct iovec *iov, int iovcnt,
> -                                NetPacketSent *sent_cb)
> +                                NetPacketSent *sent_cb,
> +                                unsigned flags)
>  {
>      NetQueue *queue;
>  
> @@ -546,14 +552,15 @@ ssize_t qemu_sendv_packet_async(NetClientState *sender,
>      queue = sender->peer->incoming_queue;
>  
>      return qemu_net_queue_send_iov(queue, sender,
> -                                   QEMU_NET_PACKET_FLAG_NONE,
> +                                   flags | QEMU_NET_PACKET_FLAG_NONE,
>                                     iov, iovcnt, sent_cb);
>  }
>  
>  ssize_t
> -qemu_sendv_packet(NetClientState *nc, const struct iovec *iov, int iovcnt)
> +qemu_sendv_packet(NetClientState *nc, const struct iovec *iov, int iovcnt,
> +                  unsigned flags)
>  {
> -    return qemu_sendv_packet_async(nc, iov, iovcnt, NULL);
> +    return qemu_sendv_packet_async(nc, iov, iovcnt, NULL, flags);
>  }
>  
>  NetClientState *qemu_find_netdev(const char *id)
> diff --git a/net/netmap.c b/net/netmap.c
> index 0ccc497..0b982a0 100644
> --- a/net/netmap.c
> +++ b/net/netmap.c
> @@ -218,7 +218,8 @@ static void netmap_writable(void *opaque)
>  }
>  
>  static ssize_t netmap_receive(NetClientState *nc,
> -      const uint8_t *buf, size_t size)
> +                              const uint8_t *buf,
> +                              size_t size, unsigned flags)
>  {
>      NetmapState *s = DO_UPCAST(NetmapState, nc, nc);
>      struct netmap_ring *ring = s->me.tx;
> @@ -252,13 +253,17 @@ static ssize_t netmap_receive(NetClientState *nc,
>      pkt_copy(buf, dst, size);
>      ring->cur = NETMAP_RING_NEXT(ring, i);
>      ring->avail--;
> -    ioctl(s->me.fd, NIOCTXSYNC, NULL);
> +
> +    if (!(flags & QEMU_NET_PACKET_FLAG_MORE)) {
> +        ioctl(s->me.fd, NIOCTXSYNC, NULL);
> +    }
>  
>      return size;
>  }
>  
>  static ssize_t netmap_receive_iov(NetClientState *nc,
> -                    const struct iovec *iov, int iovcnt)
> +                    const struct iovec *iov, int iovcnt,
> +                    unsigned flags)
>  {
>      NetmapState *s = DO_UPCAST(NetmapState, nc, nc);
>      struct netmap_ring *ring = s->me.tx;
> @@ -322,7 +327,9 @@ static ssize_t netmap_receive_iov(NetClientState *nc,
>      ring->cur = i;
>      ring->avail = avail;
>  
> -    ioctl(s->me.fd, NIOCTXSYNC, NULL);
> +    if (!(flags & QEMU_NET_PACKET_FLAG_MORE)) {
> +        ioctl(s->me.fd, NIOCTXSYNC, NULL);
> +    }
>  
>      return iov_size(iov, iovcnt);
>  }
> @@ -368,7 +375,7 @@ static void netmap_send(void *opaque)
>          }
>  
>          iovsize = qemu_sendv_packet_async(&s->nc, s->iov, iovcnt,
> -                                            netmap_send_completed);
> +                                            netmap_send_completed, 0);
>  
>          if (iovsize == 0) {
>              /* The peer does not receive anymore. Packet is queued, stop
> diff --git a/net/slirp.c b/net/slirp.c
> index 124e953..a801638 100644
> --- a/net/slirp.c
> +++ b/net/slirp.c
> @@ -103,10 +103,11 @@ void slirp_output(void *opaque, const uint8_t *pkt, int 
> pkt_len)
>  {
>      SlirpState *s = opaque;
>  
> -    qemu_send_packet(&s->nc, pkt, pkt_len);
> +    qemu_send_packet(&s->nc, pkt, pkt_len, 0);
>  }
>  
> -static ssize_t net_slirp_receive(NetClientState *nc, const uint8_t *buf, 
> size_t size)
> +static ssize_t net_slirp_receive(NetClientState *nc, const uint8_t *buf,
> +                                 size_t size, unsigned flags)
>  {
>      SlirpState *s = DO_UPCAST(SlirpState, nc, nc);
>  
> diff --git a/net/socket.c b/net/socket.c
> index fb21e20..acc715a 100644
> --- a/net/socket.c
> +++ b/net/socket.c
> @@ -89,7 +89,8 @@ static void net_socket_writable(void *opaque)
>      qemu_flush_queued_packets(&s->nc);
>  }
>  
> -static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, 
> size_t size)
> +static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf,
> +                                  size_t size, unsigned flags)
>  {
>      NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
>      uint32_t len = htonl(size);
> @@ -124,7 +125,8 @@ static ssize_t net_socket_receive(NetClientState *nc, 
> const uint8_t *buf, size_t
>      return size;
>  }
>  
> -static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t 
> *buf, size_t size)
> +static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t 
> *buf,
> +                                        size_t size, unsigned flags)
>  {
>      NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
>      ssize_t ret;
> @@ -211,7 +213,7 @@ static void net_socket_send(void *opaque)
>              buf += l;
>              size -= l;
>              if (s->index >= s->packet_len) {
> -                qemu_send_packet(&s->nc, s->buf, s->packet_len);
> +                qemu_send_packet(&s->nc, s->buf, s->packet_len, 0);
>                  s->index = 0;
>                  s->state = 0;
>              }
> @@ -234,7 +236,7 @@ static void net_socket_send_dgram(void *opaque)
>          net_socket_write_poll(s, false);
>          return;
>      }
> -    qemu_send_packet(&s->nc, s->buf, size);
> +    qemu_send_packet(&s->nc, s->buf, size, 0);
>  }
>  
>  static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct 
> in_addr *localaddr)
> diff --git a/net/tap-win32.c b/net/tap-win32.c
> index 91e9e84..2d86122 100644
> --- a/net/tap-win32.c
> +++ b/net/tap-win32.c
> @@ -664,7 +664,7 @@ static void tap_win32_send(void *opaque)
>  
>      size = tap_win32_read(s->handle, &buf, max_size);
>      if (size > 0) {
> -        qemu_send_packet(&s->nc, buf, size);
> +        qemu_send_packet(&s->nc, buf, size, 0);
>          tap_win32_free_buffer(s->handle, buf);
>      }
>  }
> diff --git a/net/tap.c b/net/tap.c
> index 39c1cda..6d7a02e 100644
> --- a/net/tap.c
> +++ b/net/tap.c
> @@ -112,7 +112,7 @@ static ssize_t tap_write_packet(TAPState *s, const struct 
> iovec *iov, int iovcnt
>  }
>  
>  static ssize_t tap_receive_iov(NetClientState *nc, const struct iovec *iov,
> -                               int iovcnt)
> +                               int iovcnt, unsigned flags)
>  {
>      TAPState *s = DO_UPCAST(TAPState, nc, nc);
>      const struct iovec *iovp = iov;
> @@ -130,7 +130,8 @@ static ssize_t tap_receive_iov(NetClientState *nc, const 
> struct iovec *iov,
>      return tap_write_packet(s, iovp, iovcnt);
>  }
>  
> -static ssize_t tap_receive_raw(NetClientState *nc, const uint8_t *buf, 
> size_t size)
> +static ssize_t tap_receive_raw(NetClientState *nc, const uint8_t *buf,
> +                               size_t size, unsigned flags)
>  {
>      TAPState *s = DO_UPCAST(TAPState, nc, nc);
>      struct iovec iov[2];
> @@ -150,13 +151,14 @@ static ssize_t tap_receive_raw(NetClientState *nc, 
> const uint8_t *buf, size_t si
>      return tap_write_packet(s, iov, iovcnt);
>  }
>  
> -static ssize_t tap_receive(NetClientState *nc, const uint8_t *buf, size_t 
> size)
> +static ssize_t tap_receive(NetClientState *nc, const uint8_t *buf, size_t 
> size,
> +                           unsigned flags)
>  {
>      TAPState *s = DO_UPCAST(TAPState, nc, nc);
>      struct iovec iov[1];
>  
>      if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
> -        return tap_receive_raw(nc, buf, size);
> +        return tap_receive_raw(nc, buf, size, flags);
>      }
>  
>      iov[0].iov_base = (char *)buf;
> @@ -203,7 +205,7 @@ static void tap_send(void *opaque)
>              size -= s->host_vnet_hdr_len;
>          }
>  
> -        size = qemu_send_packet_async(&s->nc, buf, size, tap_send_completed);
> +        size = qemu_send_packet_async(&s->nc, buf, size, tap_send_completed, 
> 0);
>          if (size == 0) {
>              tap_read_poll(s, false);
>          }
> diff --git a/net/vde.c b/net/vde.c
> index 2a619fb..5629f58 100644
> --- a/net/vde.c
> +++ b/net/vde.c
> @@ -44,11 +44,12 @@ static void vde_to_qemu(void *opaque)
>  
>      size = vde_recv(s->vde, (char *)buf, sizeof(buf), 0);
>      if (size > 0) {
> -        qemu_send_packet(&s->nc, buf, size);
> +        qemu_send_packet(&s->nc, buf, size, 0);
>      }
>  }
>  
> -static ssize_t vde_receive(NetClientState *nc, const uint8_t *buf, size_t 
> size)
> +static ssize_t vde_receive(NetClientState *nc, const uint8_t *buf, size_t 
> size,
> +                           unsigned flags)
>  {
>      VDEState *s = DO_UPCAST(VDEState, nc, nc);
>      ssize_t ret;
> diff --git a/savevm.c b/savevm.c
> index 3f912dd..a8d5373 100644
> --- a/savevm.c
> +++ b/savevm.c
> @@ -84,7 +84,7 @@ static void qemu_announce_self_iter(NICState *nic, void 
> *opaque)
>  
>      len = announce_self_create(buf, nic->conf->macaddr.a);
>  
> -    qemu_send_packet_raw(qemu_get_queue(nic), buf, len);
> +    qemu_send_packet_raw(qemu_get_queue(nic), buf, len, 0);
>  }
>  
>  
> -- 
> 1.8.4.2



reply via email to

[Prev in Thread] Current Thread [Next in Thread]