All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/11] Net patches
@ 2014-02-25 13:33 Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 01/11] opencores_eth: flush queue whenever can_receive can go from false to true Stefan Hajnoczi
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: Stefan Hajnoczi @ 2014-02-25 13:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Anthony Liguori

The following changes since commit c58e291591dbc1c846fa152d4792554803405ebb:

  Merge remote-tracking branch 'remotes/sstabellini/xen-140220' into staging (2014-02-24 16:12:55 +0000)

are available in the git repository at:


  git://github.com/stefanha/qemu.git tags/net-pull-request

for you to fetch changes up to ad37bb3b000963b36b5c30f5a4239cfbc4fe8725:

  virtio-net: use qemu_get_queue() where possible (2014-02-25 14:31:05 +0100)

----------------------------------------------------------------
Net patches

----------------------------------------------------------------
Max Filippov (1):
      opencores_eth: flush queue whenever can_receive can go from false to true

Stefan Hajnoczi (3):
      net: remove implicit peer from offload API
      vhost_net: use offload API instead of bypassing it
      virtio-net: use qemu_get_queue() where possible

Vincenzo Maffione (7):
      net: change vnet-hdr TAP prototypes
      net: extend NetClientInfo for offloading
      net: TAP uses NetClientInfo offloading callbacks
      net: virtio-net and vmxnet3 use offloading API
      net: make tap offloading callbacks static
      net: add offloading support to netmap backend
      net: Disable netmap backend when not supported

 configure              |  10 +++-
 hw/net/opencores_eth.c |  33 ++++++++++++-
 hw/net/vhost_net.c     |   6 +--
 hw/net/virtio-net.c    |  16 +++----
 hw/net/vmxnet3.c       |  22 ++++-----
 include/net/net.h      |  19 ++++++++
 include/net/tap.h      |   6 ---
 net/net.c              |  55 ++++++++++++++++++++++
 net/netmap.c           | 123 ++++++++++++++++++++++++++++++++-----------------
 net/tap-win32.c        |  92 +++++++++++++++++++-----------------
 net/tap.c              |  20 +++++---
 11 files changed, 275 insertions(+), 127 deletions(-)

-- 
1.8.5.3

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

* [Qemu-devel] [PULL 01/11] opencores_eth: flush queue whenever can_receive can go from false to true
  2014-02-25 13:33 [Qemu-devel] [PULL 00/11] Net patches Stefan Hajnoczi
@ 2014-02-25 13:33 ` Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 02/11] net: change vnet-hdr TAP prototypes Stefan Hajnoczi
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Stefan Hajnoczi @ 2014-02-25 13:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Anthony Liguori

From: Max Filippov <jcmvbkbc@gmail.com>

The following registers control whether MAC can receive frames:
- MODER.RXEN bit that enables/disables receiver;
- TX_BD_NUM register that specifies number of RX descriptors.
Notify QEMU networking core when the MAC is ready to receive frames.
Discard frame and raise BUSY interrupt when the frame arrives but the
current RX descriptor is not empty.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/net/opencores_eth.c | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c
index 4118d54..4a44304 100644
--- a/hw/net/opencores_eth.c
+++ b/hw/net/opencores_eth.c
@@ -169,6 +169,7 @@ enum {
 };
 
 enum {
+    INT_SOURCE_BUSY = 0x10,
     INT_SOURCE_RXB = 0x4,
     INT_SOURCE_TXB = 0x1,
 };
@@ -351,8 +352,7 @@ static int open_eth_can_receive(NetClientState *nc)
     OpenEthState *s = qemu_get_nic_opaque(nc);
 
     return GET_REGBIT(s, MODER, RXEN) &&
-        (s->regs[TX_BD_NUM] < 0x80) &&
-        (rx_desc(s)->len_flags & RXD_E);
+        (s->regs[TX_BD_NUM] < 0x80);
 }
 
 static ssize_t open_eth_receive(NetClientState *nc,
@@ -402,6 +402,12 @@ static ssize_t open_eth_receive(NetClientState *nc,
         desc *desc = rx_desc(s);
         size_t copy_size = GET_REGBIT(s, MODER, HUGEN) ? 65536 : maxfl;
 
+        if (!(desc->len_flags & RXD_E)) {
+            open_eth_int_source_write(s,
+                    s->regs[INT_SOURCE] | INT_SOURCE_BUSY);
+            return size;
+        }
+
         desc->len_flags &= ~(RXD_CF | RXD_M | RXD_OR |
                 RXD_IS | RXD_DN | RXD_TL | RXD_SF | RXD_CRC | RXD_LC);
 
@@ -551,6 +557,15 @@ static uint64_t open_eth_reg_read(void *opaque,
     return v;
 }
 
+static void open_eth_notify_can_receive(OpenEthState *s)
+{
+    NetClientState *nc = qemu_get_queue(s->nic);
+
+    if (open_eth_can_receive(nc)) {
+        qemu_flush_queued_packets(nc);
+    }
+}
+
 static void open_eth_ro(OpenEthState *s, uint32_t val)
 {
 }
@@ -567,6 +582,7 @@ static void open_eth_moder_host_write(OpenEthState *s, uint32_t val)
 
     if (set & MODER_RXEN) {
         s->rx_desc = s->regs[TX_BD_NUM];
+        open_eth_notify_can_receive(s);
     }
     if (set & MODER_TXEN) {
         s->tx_desc = 0;
@@ -592,6 +608,18 @@ static void open_eth_int_mask_host_write(OpenEthState *s, uint32_t val)
             s->regs[INT_SOURCE] & s->regs[INT_MASK]);
 }
 
+static void open_eth_tx_bd_num_host_write(OpenEthState *s, uint32_t val)
+{
+    if (val < 0x80) {
+        bool enable = s->regs[TX_BD_NUM] == 0x80;
+
+        s->regs[TX_BD_NUM] = val;
+        if (enable) {
+            open_eth_notify_can_receive(s);
+        }
+    }
+}
+
 static void open_eth_mii_command_host_write(OpenEthState *s, uint32_t val)
 {
     unsigned fiad = GET_REGFIELD(s, MIIADDRESS, FIAD);
@@ -630,6 +658,7 @@ static void open_eth_reg_write(void *opaque,
         [MODER] = open_eth_moder_host_write,
         [INT_SOURCE] = open_eth_int_source_host_write,
         [INT_MASK] = open_eth_int_mask_host_write,
+        [TX_BD_NUM] = open_eth_tx_bd_num_host_write,
         [MIICOMMAND] = open_eth_mii_command_host_write,
         [MIITX_DATA] = open_eth_mii_tx_host_write,
         [MIISTATUS] = open_eth_ro,
-- 
1.8.5.3

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

* [Qemu-devel] [PULL 02/11] net: change vnet-hdr TAP prototypes
  2014-02-25 13:33 [Qemu-devel] [PULL 00/11] Net patches Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 01/11] opencores_eth: flush queue whenever can_receive can go from false to true Stefan Hajnoczi
@ 2014-02-25 13:33 ` Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 03/11] net: extend NetClientInfo for offloading Stefan Hajnoczi
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Stefan Hajnoczi @ 2014-02-25 13:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Anthony Liguori

From: Vincenzo Maffione <v.maffione@gmail.com>

The tap_has_vnet_hdr() and tap_has_vnet_hdr_len() functions used
to return int, even though they only return true/false values.
This patch changes the prototypes to return bool.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 include/net/tap.h | 4 ++--
 net/tap-win32.c   | 8 ++++----
 net/tap.c         | 6 +++---
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/net/tap.h b/include/net/tap.h
index a994f20..a3490a9 100644
--- a/include/net/tap.h
+++ b/include/net/tap.h
@@ -30,8 +30,8 @@
 #include "qapi-types.h"
 
 bool tap_has_ufo(NetClientState *nc);
-int tap_has_vnet_hdr(NetClientState *nc);
-int tap_has_vnet_hdr_len(NetClientState *nc, int len);
+bool tap_has_vnet_hdr(NetClientState *nc);
+bool tap_has_vnet_hdr_len(NetClientState *nc, int len);
 void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr);
 void tap_set_offload(NetClientState *nc, int csum, int tso4, int tso6, int ecn, int ufo);
 void tap_set_vnet_hdr_len(NetClientState *nc, int len);
diff --git a/net/tap-win32.c b/net/tap-win32.c
index 91e9e84..edf26c4 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -727,9 +727,9 @@ bool tap_has_ufo(NetClientState *nc)
     return false;
 }
 
-int tap_has_vnet_hdr(NetClientState *nc)
+bool tap_has_vnet_hdr(NetClientState *nc)
 {
-    return 0;
+    return false;
 }
 
 int tap_probe_vnet_hdr_len(int fd, int len)
@@ -755,9 +755,9 @@ struct vhost_net *tap_get_vhost_net(NetClientState *nc)
     return NULL;
 }
 
-int tap_has_vnet_hdr_len(NetClientState *nc, int len)
+bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
 {
-    return 0;
+    return false;
 }
 
 void tap_set_vnet_hdr_len(NetClientState *nc, int len)
diff --git a/net/tap.c b/net/tap.c
index 39c1cda..c805f3c 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -219,7 +219,7 @@ bool tap_has_ufo(NetClientState *nc)
     return s->has_ufo;
 }
 
-int tap_has_vnet_hdr(NetClientState *nc)
+bool tap_has_vnet_hdr(NetClientState *nc)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
@@ -228,13 +228,13 @@ int tap_has_vnet_hdr(NetClientState *nc)
     return !!s->host_vnet_hdr_len;
 }
 
-int tap_has_vnet_hdr_len(NetClientState *nc, int len)
+bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
     assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
 
-    return tap_probe_vnet_hdr_len(s->fd, len);
+    return !!tap_probe_vnet_hdr_len(s->fd, len);
 }
 
 void tap_set_vnet_hdr_len(NetClientState *nc, int len)
-- 
1.8.5.3

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

* [Qemu-devel] [PULL 03/11] net: extend NetClientInfo for offloading
  2014-02-25 13:33 [Qemu-devel] [PULL 00/11] Net patches Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 01/11] opencores_eth: flush queue whenever can_receive can go from false to true Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 02/11] net: change vnet-hdr TAP prototypes Stefan Hajnoczi
@ 2014-02-25 13:33 ` Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 04/11] net: TAP uses NetClientInfo offloading callbacks Stefan Hajnoczi
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Stefan Hajnoczi @ 2014-02-25 13:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Anthony Liguori

From: Vincenzo Maffione <v.maffione@gmail.com>

Some new callbacks have been added to generalize the operations done
by virtio-net and vmxnet3 frontends to manipulate TAP offloadings.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 include/net/net.h | 19 +++++++++++++++++++
 net/net.c         | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/include/net/net.h b/include/net/net.h
index 11e1468..7b25394 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -50,6 +50,12 @@ typedef void (NetCleanup) (NetClientState *);
 typedef void (LinkStatusChanged)(NetClientState *);
 typedef void (NetClientDestructor)(NetClientState *);
 typedef RxFilterInfo *(QueryRxFilter)(NetClientState *);
+typedef bool (HasUfo)(NetClientState *);
+typedef bool (HasVnetHdr)(NetClientState *);
+typedef bool (HasVnetHdrLen)(NetClientState *, int);
+typedef void (UsingVnetHdr)(NetClientState *, bool);
+typedef void (SetOffload)(NetClientState *, int, int, int, int, int);
+typedef void (SetVnetHdrLen)(NetClientState *, int);
 
 typedef struct NetClientInfo {
     NetClientOptionsKind type;
@@ -62,6 +68,12 @@ typedef struct NetClientInfo {
     LinkStatusChanged *link_status_changed;
     QueryRxFilter *query_rx_filter;
     NetPoll *poll;
+    HasUfo *has_ufo;
+    HasVnetHdr *has_vnet_hdr;
+    HasVnetHdrLen *has_vnet_hdr_len;
+    UsingVnetHdr *using_vnet_hdr;
+    SetOffload *set_offload;
+    SetVnetHdrLen *set_vnet_hdr_len;
 } NetClientInfo;
 
 struct NetClientState {
@@ -120,6 +132,13 @@ ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf,
 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]);
+bool qemu_peer_has_ufo(NetClientState *nc);
+bool qemu_peer_has_vnet_hdr(NetClientState *nc);
+bool qemu_peer_has_vnet_hdr_len(NetClientState *nc, int len);
+void qemu_peer_using_vnet_hdr(NetClientState *nc, bool enable);
+void qemu_peer_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
+                           int ecn, int ufo);
+void qemu_peer_set_vnet_hdr_len(NetClientState *nc, int len);
 void qemu_macaddr_default_if_unset(MACAddr *macaddr);
 int qemu_show_nic_models(const char *arg, const char *const *models);
 void qemu_check_nic_model(NICInfo *nd, const char *model);
diff --git a/net/net.c b/net/net.c
index 41b3883..06d690a 100644
--- a/net/net.c
+++ b/net/net.c
@@ -378,6 +378,61 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
     }
 }
 
+bool qemu_peer_has_ufo(NetClientState *nc)
+{
+    if (!nc->peer || !nc->peer->info->has_ufo) {
+        return false;
+    }
+
+    return nc->peer->info->has_ufo(nc->peer);
+}
+
+bool qemu_peer_has_vnet_hdr(NetClientState *nc)
+{
+    if (!nc->peer || !nc->peer->info->has_vnet_hdr) {
+        return false;
+    }
+
+    return nc->peer->info->has_vnet_hdr(nc->peer);
+}
+
+bool qemu_peer_has_vnet_hdr_len(NetClientState *nc, int len)
+{
+    if (!nc->peer || !nc->peer->info->has_vnet_hdr_len) {
+        return false;
+    }
+
+    return nc->peer->info->has_vnet_hdr_len(nc->peer, len);
+}
+
+void qemu_peer_using_vnet_hdr(NetClientState *nc, bool enable)
+{
+    if (!nc->peer || !nc->peer->info->using_vnet_hdr) {
+        return;
+    }
+
+    nc->peer->info->using_vnet_hdr(nc->peer, enable);
+}
+
+void qemu_peer_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
+                          int ecn, int ufo)
+{
+    if (!nc->peer || !nc->peer->info->set_offload) {
+        return;
+    }
+
+    nc->peer->info->set_offload(nc->peer, csum, tso4, tso6, ecn, ufo);
+}
+
+void qemu_peer_set_vnet_hdr_len(NetClientState *nc, int len)
+{
+    if (!nc->peer || !nc->peer->info->set_vnet_hdr_len) {
+        return;
+    }
+
+    nc->peer->info->set_vnet_hdr_len(nc->peer, len);
+}
+
 int qemu_can_send_packet(NetClientState *sender)
 {
     if (!sender->peer) {
-- 
1.8.5.3

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

* [Qemu-devel] [PULL 04/11] net: TAP uses NetClientInfo offloading callbacks
  2014-02-25 13:33 [Qemu-devel] [PULL 00/11] Net patches Stefan Hajnoczi
                   ` (2 preceding siblings ...)
  2014-02-25 13:33 ` [Qemu-devel] [PULL 03/11] net: extend NetClientInfo for offloading Stefan Hajnoczi
@ 2014-02-25 13:33 ` Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 05/11] net: virtio-net and vmxnet3 use offloading API Stefan Hajnoczi
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Stefan Hajnoczi @ 2014-02-25 13:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Anthony Liguori

From: Vincenzo Maffione <v.maffione@gmail.com>

The TAP NetClientInfo structure is inizialized with the TAP-specific
functions that manipulates offloading features.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 net/tap-win32.c | 92 ++++++++++++++++++++++++++++++---------------------------
 net/tap.c       |  6 ++++
 2 files changed, 55 insertions(+), 43 deletions(-)

diff --git a/net/tap-win32.c b/net/tap-win32.c
index edf26c4..924ca55 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -669,11 +669,60 @@ static void tap_win32_send(void *opaque)
     }
 }
 
+bool tap_has_ufo(NetClientState *nc)
+{
+    return false;
+}
+
+bool tap_has_vnet_hdr(NetClientState *nc)
+{
+    return false;
+}
+
+int tap_probe_vnet_hdr_len(int fd, int len)
+{
+    return 0;
+}
+
+void tap_fd_set_vnet_hdr_len(int fd, int len)
+{
+}
+
+void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
+{
+}
+
+void tap_set_offload(NetClientState *nc, int csum, int tso4,
+                     int tso6, int ecn, int ufo)
+{
+}
+
+struct vhost_net *tap_get_vhost_net(NetClientState *nc)
+{
+    return NULL;
+}
+
+bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
+{
+    return false;
+}
+
+void tap_set_vnet_hdr_len(NetClientState *nc, int len)
+{
+    abort();
+}
+
 static NetClientInfo net_tap_win32_info = {
     .type = NET_CLIENT_OPTIONS_KIND_TAP,
     .size = sizeof(TAPState),
     .receive = tap_receive,
     .cleanup = tap_cleanup,
+    .has_ufo = tap_has_ufo,
+    .has_vnet_hdr = tap_has_vnet_hdr,
+    .has_vnet_hdr_len = tap_has_vnet_hdr_len,
+    .using_vnet_hdr = tap_using_vnet_hdr,
+    .set_offload = tap_set_offload,
+    .set_vnet_hdr_len = tap_set_vnet_hdr_len,
 };
 
 static int tap_win32_init(NetClientState *peer, const char *model,
@@ -722,49 +771,6 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
     return 0;
 }
 
-bool tap_has_ufo(NetClientState *nc)
-{
-    return false;
-}
-
-bool tap_has_vnet_hdr(NetClientState *nc)
-{
-    return false;
-}
-
-int tap_probe_vnet_hdr_len(int fd, int len)
-{
-    return 0;
-}
-
-void tap_fd_set_vnet_hdr_len(int fd, int len)
-{
-}
-
-void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
-{
-}
-
-void tap_set_offload(NetClientState *nc, int csum, int tso4,
-                     int tso6, int ecn, int ufo)
-{
-}
-
-struct vhost_net *tap_get_vhost_net(NetClientState *nc)
-{
-    return NULL;
-}
-
-bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
-{
-    return false;
-}
-
-void tap_set_vnet_hdr_len(NetClientState *nc, int len)
-{
-    abort();
-}
-
 int tap_enable(NetClientState *nc)
 {
     abort();
diff --git a/net/tap.c b/net/tap.c
index c805f3c..d34ec88 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -314,6 +314,12 @@ static NetClientInfo net_tap_info = {
     .receive_iov = tap_receive_iov,
     .poll = tap_poll,
     .cleanup = tap_cleanup,
+    .has_ufo = tap_has_ufo,
+    .has_vnet_hdr = tap_has_vnet_hdr,
+    .has_vnet_hdr_len = tap_has_vnet_hdr_len,
+    .using_vnet_hdr = tap_using_vnet_hdr,
+    .set_offload = tap_set_offload,
+    .set_vnet_hdr_len = tap_set_vnet_hdr_len,
 };
 
 static TAPState *net_tap_fd_init(NetClientState *peer,
-- 
1.8.5.3

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

* [Qemu-devel] [PULL 05/11] net: virtio-net and vmxnet3 use offloading API
  2014-02-25 13:33 [Qemu-devel] [PULL 00/11] Net patches Stefan Hajnoczi
                   ` (3 preceding siblings ...)
  2014-02-25 13:33 ` [Qemu-devel] [PULL 04/11] net: TAP uses NetClientInfo offloading callbacks Stefan Hajnoczi
@ 2014-02-25 13:33 ` Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 06/11] net: make tap offloading callbacks static Stefan Hajnoczi
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Stefan Hajnoczi @ 2014-02-25 13:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Anthony Liguori

From: Vincenzo Maffione <v.maffione@gmail.com>

With this patch, virtio-net and vmxnet3 frontends make
use of the qemu_peer_* API for backend offloadings manipulations,
instead of calling TAP-specific functions directly.
We also remove the existing checks which prevent those frontends
from using offloadings with backends different from TAP (e.g. netmap).

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/net/vhost_net.c  |  4 ++--
 hw/net/virtio-net.c | 16 ++++++----------
 hw/net/vmxnet3.c    | 12 +++++-------
 3 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 854997d..c90b9ec 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -106,7 +106,7 @@ struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
         goto fail;
     }
     net->nc = backend;
-    net->dev.backend_features = tap_has_vnet_hdr(backend) ? 0 :
+    net->dev.backend_features = backend->info->has_vnet_hdr(backend) ? 0 :
         (1 << VHOST_NET_F_VIRTIO_NET_HDR);
     net->backend = r;
 
@@ -117,7 +117,7 @@ struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
     if (r < 0) {
         goto fail;
     }
-    if (!tap_has_vnet_hdr_len(backend,
+    if (!backend->info->has_vnet_hdr_len(backend,
                               sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
         net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
     }
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 3626608..cda8c75 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -325,11 +325,7 @@ static void peer_test_vnet_hdr(VirtIONet *n)
         return;
     }
 
-    if (nc->peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP) {
-        return;
-    }
-
-    n->has_vnet_hdr = tap_has_vnet_hdr(nc->peer);
+    n->has_vnet_hdr = qemu_peer_has_vnet_hdr(nc);
 }
 
 static int peer_has_vnet_hdr(VirtIONet *n)
@@ -342,7 +338,7 @@ static int peer_has_ufo(VirtIONet *n)
     if (!peer_has_vnet_hdr(n))
         return 0;
 
-    n->has_ufo = tap_has_ufo(qemu_get_queue(n->nic)->peer);
+    n->has_ufo = qemu_peer_has_ufo(qemu_get_queue(n->nic));
 
     return n->has_ufo;
 }
@@ -361,8 +357,8 @@ static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs)
         nc = qemu_get_subqueue(n->nic, i);
 
         if (peer_has_vnet_hdr(n) &&
-            tap_has_vnet_hdr_len(nc->peer, n->guest_hdr_len)) {
-            tap_set_vnet_hdr_len(nc->peer, n->guest_hdr_len);
+            qemu_peer_has_vnet_hdr_len(nc, n->guest_hdr_len)) {
+            qemu_peer_set_vnet_hdr_len(nc, n->guest_hdr_len);
             n->host_hdr_len = n->guest_hdr_len;
         }
     }
@@ -463,7 +459,7 @@ static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
 
 static void virtio_net_apply_guest_offloads(VirtIONet *n)
 {
-    tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
+    qemu_peer_set_offload(qemu_get_subqueue(n->nic, 0),
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_CSUM)),
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)),
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)),
@@ -1544,7 +1540,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
     peer_test_vnet_hdr(n);
     if (peer_has_vnet_hdr(n)) {
         for (i = 0; i < n->max_queues; i++) {
-            tap_using_vnet_hdr(qemu_get_subqueue(n->nic, i)->peer, true);
+            qemu_peer_using_vnet_hdr(qemu_get_subqueue(n->nic, i), true);
         }
         n->host_hdr_len = sizeof(struct virtio_net_hdr);
     } else {
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 19687aa..0524684 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -1290,7 +1290,7 @@ static void vmxnet3_update_features(VMXNET3State *s)
               s->lro_supported, rxcso_supported,
               s->rx_vlan_stripping);
     if (s->peer_has_vhdr) {
-        tap_set_offload(qemu_get_queue(s->nic)->peer,
+        qemu_peer_set_offload(qemu_get_queue(s->nic),
                         rxcso_supported,
                         s->lro_supported,
                         s->lro_supported,
@@ -1883,11 +1883,9 @@ static NetClientInfo net_vmxnet3_info = {
 
 static bool vmxnet3_peer_has_vnet_hdr(VMXNET3State *s)
 {
-    NetClientState *peer = qemu_get_queue(s->nic)->peer;
+    NetClientState *nc = qemu_get_queue(s->nic);
 
-    if ((NULL != peer)                              &&
-        (peer->info->type == NET_CLIENT_OPTIONS_KIND_TAP)   &&
-        tap_has_vnet_hdr(peer)) {
+    if (qemu_peer_has_vnet_hdr(nc)) {
         return true;
     }
 
@@ -1935,10 +1933,10 @@ static void vmxnet3_net_init(VMXNET3State *s)
     s->lro_supported = false;
 
     if (s->peer_has_vhdr) {
-        tap_set_vnet_hdr_len(qemu_get_queue(s->nic)->peer,
+        qemu_peer_set_vnet_hdr_len(qemu_get_queue(s->nic),
             sizeof(struct virtio_net_hdr));
 
-        tap_using_vnet_hdr(qemu_get_queue(s->nic)->peer, 1);
+        qemu_peer_using_vnet_hdr(qemu_get_queue(s->nic), 1);
     }
 
     qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
-- 
1.8.5.3

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

* [Qemu-devel] [PULL 06/11] net: make tap offloading callbacks static
  2014-02-25 13:33 [Qemu-devel] [PULL 00/11] Net patches Stefan Hajnoczi
                   ` (4 preceding siblings ...)
  2014-02-25 13:33 ` [Qemu-devel] [PULL 05/11] net: virtio-net and vmxnet3 use offloading API Stefan Hajnoczi
@ 2014-02-25 13:33 ` Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 07/11] net: add offloading support to netmap backend Stefan Hajnoczi
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Stefan Hajnoczi @ 2014-02-25 13:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Anthony Liguori

From: Vincenzo Maffione <v.maffione@gmail.com>

Since TAP offloadings are manipulated through a new API, it's
not necessary to export them in include/net/tap.h anymore.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 include/net/tap.h |  6 ------
 net/tap-win32.c   | 12 ++++++------
 net/tap.c         | 12 ++++++------
 3 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/include/net/tap.h b/include/net/tap.h
index a3490a9..6daeb42 100644
--- a/include/net/tap.h
+++ b/include/net/tap.h
@@ -29,12 +29,6 @@
 #include "qemu-common.h"
 #include "qapi-types.h"
 
-bool tap_has_ufo(NetClientState *nc);
-bool tap_has_vnet_hdr(NetClientState *nc);
-bool tap_has_vnet_hdr_len(NetClientState *nc, int len);
-void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr);
-void tap_set_offload(NetClientState *nc, int csum, int tso4, int tso6, int ecn, int ufo);
-void tap_set_vnet_hdr_len(NetClientState *nc, int len);
 int tap_enable(NetClientState *nc);
 int tap_disable(NetClientState *nc);
 
diff --git a/net/tap-win32.c b/net/tap-win32.c
index 924ca55..8aee611 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -669,12 +669,12 @@ static void tap_win32_send(void *opaque)
     }
 }
 
-bool tap_has_ufo(NetClientState *nc)
+static bool tap_has_ufo(NetClientState *nc)
 {
     return false;
 }
 
-bool tap_has_vnet_hdr(NetClientState *nc)
+static bool tap_has_vnet_hdr(NetClientState *nc)
 {
     return false;
 }
@@ -688,11 +688,11 @@ void tap_fd_set_vnet_hdr_len(int fd, int len)
 {
 }
 
-void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
+static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
 {
 }
 
-void tap_set_offload(NetClientState *nc, int csum, int tso4,
+static void tap_set_offload(NetClientState *nc, int csum, int tso4,
                      int tso6, int ecn, int ufo)
 {
 }
@@ -702,12 +702,12 @@ struct vhost_net *tap_get_vhost_net(NetClientState *nc)
     return NULL;
 }
 
-bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
+static bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
 {
     return false;
 }
 
-void tap_set_vnet_hdr_len(NetClientState *nc, int len)
+static void tap_set_vnet_hdr_len(NetClientState *nc, int len)
 {
     abort();
 }
diff --git a/net/tap.c b/net/tap.c
index d34ec88..2d5099b 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -210,7 +210,7 @@ static void tap_send(void *opaque)
     } while (size > 0 && qemu_can_send_packet(&s->nc));
 }
 
-bool tap_has_ufo(NetClientState *nc)
+static bool tap_has_ufo(NetClientState *nc)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
@@ -219,7 +219,7 @@ bool tap_has_ufo(NetClientState *nc)
     return s->has_ufo;
 }
 
-bool tap_has_vnet_hdr(NetClientState *nc)
+static bool tap_has_vnet_hdr(NetClientState *nc)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
@@ -228,7 +228,7 @@ bool tap_has_vnet_hdr(NetClientState *nc)
     return !!s->host_vnet_hdr_len;
 }
 
-bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
+static bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
@@ -237,7 +237,7 @@ bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
     return !!tap_probe_vnet_hdr_len(s->fd, len);
 }
 
-void tap_set_vnet_hdr_len(NetClientState *nc, int len)
+static void tap_set_vnet_hdr_len(NetClientState *nc, int len)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
@@ -249,7 +249,7 @@ void tap_set_vnet_hdr_len(NetClientState *nc, int len)
     s->host_vnet_hdr_len = len;
 }
 
-void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
+static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
@@ -259,7 +259,7 @@ void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
     s->using_vnet_hdr = using_vnet_hdr;
 }
 
-void tap_set_offload(NetClientState *nc, int csum, int tso4,
+static void tap_set_offload(NetClientState *nc, int csum, int tso4,
                      int tso6, int ecn, int ufo)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
-- 
1.8.5.3

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

* [Qemu-devel] [PULL 07/11] net: add offloading support to netmap backend
  2014-02-25 13:33 [Qemu-devel] [PULL 00/11] Net patches Stefan Hajnoczi
                   ` (5 preceding siblings ...)
  2014-02-25 13:33 ` [Qemu-devel] [PULL 06/11] net: make tap offloading callbacks static Stefan Hajnoczi
@ 2014-02-25 13:33 ` Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 08/11] net: Disable netmap backend when not supported Stefan Hajnoczi
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Stefan Hajnoczi @ 2014-02-25 13:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Anthony Liguori

From: Vincenzo Maffione <v.maffione@gmail.com>

Whit this patch, the netmap backend supports TSO/UFO/CSUM
offloadings, and accepts the virtio-net header, similarly to what
happens with TAP. The offloading callbacks in the NetClientInfo
interface have been implemented.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 net/netmap.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/net/netmap.c b/net/netmap.c
index 0ccc497..73f6d7a 100644
--- a/net/netmap.c
+++ b/net/netmap.c
@@ -31,6 +31,7 @@
 #include <net/netmap_user.h>
 
 #include "net/net.h"
+#include "net/tap.h"
 #include "clients.h"
 #include "sysemu/sysemu.h"
 #include "qemu/error-report.h"
@@ -54,6 +55,7 @@ typedef struct NetmapState {
     bool                read_poll;
     bool                write_poll;
     struct iovec        iov[IOV_MAX];
+    int                 vnet_hdr_len;  /* Current virtio-net header length. */
 } NetmapState;
 
 #define D(format, ...)                                          \
@@ -274,7 +276,7 @@ static ssize_t netmap_receive_iov(NetClientState *nc,
         return iov_size(iov, iovcnt);
     }
 
-    i = ring->cur;
+    last = i = ring->cur;
     avail = ring->avail;
 
     if (avail < iovcnt) {
@@ -394,6 +396,63 @@ static void netmap_cleanup(NetClientState *nc)
     s->me.fd = -1;
 }
 
+/* Offloading manipulation support callbacks. */
+static bool netmap_has_ufo(NetClientState *nc)
+{
+    return true;
+}
+
+static bool netmap_has_vnet_hdr(NetClientState *nc)
+{
+    return true;
+}
+
+static bool netmap_has_vnet_hdr_len(NetClientState *nc, int len)
+{
+    return len == 0 || len == sizeof(struct virtio_net_hdr) ||
+                len == sizeof(struct virtio_net_hdr_mrg_rxbuf);
+}
+
+static void netmap_using_vnet_hdr(NetClientState *nc, bool enable)
+{
+}
+
+static void netmap_set_vnet_hdr_len(NetClientState *nc, int len)
+{
+    NetmapState *s = DO_UPCAST(NetmapState, nc, nc);
+    int err;
+    struct nmreq req;
+
+    /* Issue a NETMAP_BDG_VNET_HDR command to change the virtio-net header
+     * length for the netmap adapter associated to 'me->ifname'.
+     */
+    memset(&req, 0, sizeof(req));
+    pstrcpy(req.nr_name, sizeof(req.nr_name), s->me.ifname);
+    req.nr_version = NETMAP_API;
+    req.nr_cmd = NETMAP_BDG_VNET_HDR;
+    req.nr_arg1 = len;
+    err = ioctl(s->me.fd, NIOCREGIF, &req);
+    if (err) {
+        error_report("Unable to execute NETMAP_BDG_VNET_HDR on %s: %s",
+                     s->me.ifname, strerror(errno));
+    } else {
+        /* Keep track of the current length. */
+        s->vnet_hdr_len = len;
+    }
+}
+
+static void netmap_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
+                               int ecn, int ufo)
+{
+    NetmapState *s = DO_UPCAST(NetmapState, nc, nc);
+
+    /* Setting a virtio-net header length greater than zero automatically
+     * enables the offloadings.
+     */
+    if (!s->vnet_hdr_len) {
+        netmap_set_vnet_hdr_len(nc, sizeof(struct virtio_net_hdr));
+    }
+}
 
 /* NetClientInfo methods */
 static NetClientInfo net_netmap_info = {
@@ -403,6 +462,12 @@ static NetClientInfo net_netmap_info = {
     .receive_iov = netmap_receive_iov,
     .poll = netmap_poll,
     .cleanup = netmap_cleanup,
+    .has_ufo = netmap_has_ufo,
+    .has_vnet_hdr = netmap_has_vnet_hdr,
+    .has_vnet_hdr_len = netmap_has_vnet_hdr_len,
+    .using_vnet_hdr = netmap_using_vnet_hdr,
+    .set_offload = netmap_set_offload,
+    .set_vnet_hdr_len = netmap_set_vnet_hdr_len,
 };
 
 /* The exported init function
@@ -428,6 +493,7 @@ int net_init_netmap(const NetClientOptions *opts,
     nc = qemu_new_net_client(&net_netmap_info, peer, "netmap", name);
     s = DO_UPCAST(NetmapState, nc, nc);
     s->me = me;
+    s->vnet_hdr_len = 0;
     netmap_read_poll(s, true); /* Initially only poll for reads. */
 
     return 0;
-- 
1.8.5.3

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

* [Qemu-devel] [PULL 08/11] net: Disable netmap backend when not supported
  2014-02-25 13:33 [Qemu-devel] [PULL 00/11] Net patches Stefan Hajnoczi
                   ` (6 preceding siblings ...)
  2014-02-25 13:33 ` [Qemu-devel] [PULL 07/11] net: add offloading support to netmap backend Stefan Hajnoczi
@ 2014-02-25 13:33 ` Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 09/11] net: remove implicit peer from offload API Stefan Hajnoczi
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Stefan Hajnoczi @ 2014-02-25 13:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Anthony Liguori

From: Vincenzo Maffione <v.maffione@gmail.com>

This patch fixes configure so that the netmap backend is not compiled in if the
host doesn't support an API version >= 11. A version upper bound (15) has been
added so that the netmap API can be extended with some minor features without
requiring QEMU code modifications.

Moreover, some changes have been done to net/netmap.c in order to reflect the
current netmap API/ABI (11).

The NETMAP_WITH_LIBS macro makes possible to include some utilities (e.g.
netmap ring macros, D(), RD() and other high level functions) through the netmap
headers. In this way we get rid of the D and RD macro definitions in the QEMU
code, and we open the way for further code simplifications that will be
introduced by future patches.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 configure    | 10 +++++++++-
 net/netmap.c | 55 +++++++++++++------------------------------------------
 2 files changed, 22 insertions(+), 43 deletions(-)

diff --git a/configure b/configure
index 00f9070..9ad3ff3 100755
--- a/configure
+++ b/configure
@@ -2215,13 +2215,21 @@ EOF
 fi
 
 ##########################################
-# netmap headers probe
+# netmap support probe
+# Apart from looking for netmap headers, we make sure that the host API version
+# supports the netmap backend (>=11). The upper bound (15) is meant to simulate
+# a minor/major version number. Minor new features will be marked with values up
+# to 15, and if something happens that requires a change to the backend we will
+# move above 15, submit the backend fixes and modify this two bounds.
 if test "$netmap" != "no" ; then
   cat > $TMPC << EOF
 #include <inttypes.h>
 #include <net/if.h>
 #include <net/netmap.h>
 #include <net/netmap_user.h>
+#if (NETMAP_API < 11) || (NETMAP_API > 15)
+#error
+#endif
 int main(void) { return 0; }
 EOF
   if compile_prog "" "" ; then
diff --git a/net/netmap.c b/net/netmap.c
index 73f6d7a..8213304 100644
--- a/net/netmap.c
+++ b/net/netmap.c
@@ -27,6 +27,8 @@
 #include <net/if.h>
 #include <sys/mman.h>
 #include <stdint.h>
+#include <stdio.h>
+#define NETMAP_WITH_LIBS
 #include <net/netmap.h>
 #include <net/netmap_user.h>
 
@@ -58,31 +60,6 @@ typedef struct NetmapState {
     int                 vnet_hdr_len;  /* Current virtio-net header length. */
 } NetmapState;
 
-#define D(format, ...)                                          \
-    do {                                                        \
-        struct timeval __xxts;                                  \
-        gettimeofday(&__xxts, NULL);                            \
-        printf("%03d.%06d %s [%d] " format "\n",                \
-                (int)__xxts.tv_sec % 1000, (int)__xxts.tv_usec, \
-                __func__, __LINE__, ##__VA_ARGS__);         \
-    } while (0)
-
-/* Rate limited version of "D", lps indicates how many per second */
-#define RD(lps, format, ...)                                    \
-    do {                                                        \
-        static int t0, __cnt;                                   \
-        struct timeval __xxts;                                  \
-        gettimeofday(&__xxts, NULL);                            \
-        if (t0 != __xxts.tv_sec) {                              \
-            t0 = __xxts.tv_sec;                                 \
-            __cnt = 0;                                          \
-        }                                                       \
-        if (__cnt++ < lps) {                                    \
-            D(format, ##__VA_ARGS__);                           \
-        }                                                       \
-    } while (0)
-
-
 #ifndef __FreeBSD__
 #define pkt_copy bcopy
 #else
@@ -239,7 +216,7 @@ static ssize_t netmap_receive(NetClientState *nc,
         return size;
     }
 
-    if (ring->avail == 0) {
+    if (nm_ring_empty(ring)) {
         /* No available slots in the netmap TX ring. */
         netmap_write_poll(s, true);
         return 0;
@@ -252,8 +229,7 @@ static ssize_t netmap_receive(NetClientState *nc,
     ring->slot[i].len = size;
     ring->slot[i].flags = 0;
     pkt_copy(buf, dst, size);
-    ring->cur = NETMAP_RING_NEXT(ring, i);
-    ring->avail--;
+    ring->cur = ring->head = nm_ring_next(ring, i);
     ioctl(s->me.fd, NIOCTXSYNC, NULL);
 
     return size;
@@ -269,7 +245,6 @@ static ssize_t netmap_receive_iov(NetClientState *nc,
     uint8_t *dst;
     int j;
     uint32_t i;
-    uint32_t avail;
 
     if (unlikely(!ring)) {
         /* Drop the packet. */
@@ -277,9 +252,8 @@ static ssize_t netmap_receive_iov(NetClientState *nc,
     }
 
     last = i = ring->cur;
-    avail = ring->avail;
 
-    if (avail < iovcnt) {
+    if (nm_ring_space(ring) < iovcnt) {
         /* Not enough netmap slots. */
         netmap_write_poll(s, true);
         return 0;
@@ -295,7 +269,7 @@ static ssize_t netmap_receive_iov(NetClientState *nc,
         while (iov_frag_size) {
             nm_frag_size = MIN(iov_frag_size, ring->nr_buf_size);
 
-            if (unlikely(avail == 0)) {
+            if (unlikely(nm_ring_empty(ring))) {
                 /* We run out of netmap slots while splitting the
                    iovec fragments. */
                 netmap_write_poll(s, true);
@@ -310,8 +284,7 @@ static ssize_t netmap_receive_iov(NetClientState *nc,
             pkt_copy(iov[j].iov_base + offset, dst, nm_frag_size);
 
             last = i;
-            i = NETMAP_RING_NEXT(ring, i);
-            avail--;
+            i = nm_ring_next(ring, i);
 
             offset += nm_frag_size;
             iov_frag_size -= nm_frag_size;
@@ -320,9 +293,8 @@ static ssize_t netmap_receive_iov(NetClientState *nc,
     /* The last slot must not have NS_MOREFRAG set. */
     ring->slot[last].flags &= ~NS_MOREFRAG;
 
-    /* Now update ring->cur and ring->avail. */
-    ring->cur = i;
-    ring->avail = avail;
+    /* Now update ring->cur and ring->head. */
+    ring->cur = ring->head = i;
 
     ioctl(s->me.fd, NIOCTXSYNC, NULL);
 
@@ -345,7 +317,7 @@ static void netmap_send(void *opaque)
 
     /* Keep sending while there are available packets into the netmap
        RX ring and the forwarding path towards the peer is open. */
-    while (ring->avail > 0 && qemu_can_send_packet(&s->nc)) {
+    while (!nm_ring_empty(ring) && qemu_can_send_packet(&s->nc)) {
         uint32_t i;
         uint32_t idx;
         bool morefrag;
@@ -360,11 +332,10 @@ static void netmap_send(void *opaque)
             s->iov[iovcnt].iov_len = ring->slot[i].len;
             iovcnt++;
 
-            ring->cur = NETMAP_RING_NEXT(ring, i);
-            ring->avail--;
-        } while (ring->avail && morefrag);
+            ring->cur = ring->head = nm_ring_next(ring, i);
+        } while (!nm_ring_empty(ring) && morefrag);
 
-        if (unlikely(!ring->avail && morefrag)) {
+        if (unlikely(nm_ring_empty(ring) && morefrag)) {
             RD(5, "[netmap_send] ran out of slots, with a pending"
                    "incomplete packet\n");
         }
-- 
1.8.5.3

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

* [Qemu-devel] [PULL 09/11] net: remove implicit peer from offload API
  2014-02-25 13:33 [Qemu-devel] [PULL 00/11] Net patches Stefan Hajnoczi
                   ` (7 preceding siblings ...)
  2014-02-25 13:33 ` [Qemu-devel] [PULL 08/11] net: Disable netmap backend when not supported Stefan Hajnoczi
@ 2014-02-25 13:33 ` Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 10/11] vhost_net: use offload API instead of bypassing it Stefan Hajnoczi
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Stefan Hajnoczi @ 2014-02-25 13:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Anthony Liguori

The virtio_net offload APIs are used on the NIC's peer (i.e. the tap
device).  The API was defined to implicitly use nc->peer, saving the
caller the trouble.

This wasn't ideal because:
1. There are callers who have the peer but not the NIC.  Currently they
   are forced to bypass the API and access peer->info->... directly.
2. The rest of the net.h API uses nc, not nc->peer, so it is
   inconsistent.

This patch pushes nc->peer back up to callers.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/net/virtio-net.c | 12 ++++++------
 hw/net/vmxnet3.c    | 18 +++++++++---------
 include/net/net.h   | 14 +++++++-------
 net/net.c           | 36 ++++++++++++++++++------------------
 4 files changed, 40 insertions(+), 40 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index cda8c75..9218a09 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -325,7 +325,7 @@ static void peer_test_vnet_hdr(VirtIONet *n)
         return;
     }
 
-    n->has_vnet_hdr = qemu_peer_has_vnet_hdr(nc);
+    n->has_vnet_hdr = qemu_has_vnet_hdr(nc->peer);
 }
 
 static int peer_has_vnet_hdr(VirtIONet *n)
@@ -338,7 +338,7 @@ static int peer_has_ufo(VirtIONet *n)
     if (!peer_has_vnet_hdr(n))
         return 0;
 
-    n->has_ufo = qemu_peer_has_ufo(qemu_get_queue(n->nic));
+    n->has_ufo = qemu_has_ufo(qemu_get_queue(n->nic)->peer);
 
     return n->has_ufo;
 }
@@ -357,8 +357,8 @@ static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs)
         nc = qemu_get_subqueue(n->nic, i);
 
         if (peer_has_vnet_hdr(n) &&
-            qemu_peer_has_vnet_hdr_len(nc, n->guest_hdr_len)) {
-            qemu_peer_set_vnet_hdr_len(nc, n->guest_hdr_len);
+            qemu_has_vnet_hdr_len(nc->peer, n->guest_hdr_len)) {
+            qemu_set_vnet_hdr_len(nc->peer, n->guest_hdr_len);
             n->host_hdr_len = n->guest_hdr_len;
         }
     }
@@ -459,7 +459,7 @@ static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
 
 static void virtio_net_apply_guest_offloads(VirtIONet *n)
 {
-    qemu_peer_set_offload(qemu_get_subqueue(n->nic, 0),
+    qemu_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_CSUM)),
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)),
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)),
@@ -1540,7 +1540,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
     peer_test_vnet_hdr(n);
     if (peer_has_vnet_hdr(n)) {
         for (i = 0; i < n->max_queues; i++) {
-            qemu_peer_using_vnet_hdr(qemu_get_subqueue(n->nic, i), true);
+            qemu_using_vnet_hdr(qemu_get_subqueue(n->nic, i)->peer, true);
         }
         n->host_hdr_len = sizeof(struct virtio_net_hdr);
     } else {
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 0524684..5be807c 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -1290,12 +1290,12 @@ static void vmxnet3_update_features(VMXNET3State *s)
               s->lro_supported, rxcso_supported,
               s->rx_vlan_stripping);
     if (s->peer_has_vhdr) {
-        qemu_peer_set_offload(qemu_get_queue(s->nic),
-                        rxcso_supported,
-                        s->lro_supported,
-                        s->lro_supported,
-                        0,
-                        0);
+        qemu_set_offload(qemu_get_queue(s->nic)->peer,
+                         rxcso_supported,
+                         s->lro_supported,
+                         s->lro_supported,
+                         0,
+                         0);
     }
 }
 
@@ -1885,7 +1885,7 @@ static bool vmxnet3_peer_has_vnet_hdr(VMXNET3State *s)
 {
     NetClientState *nc = qemu_get_queue(s->nic);
 
-    if (qemu_peer_has_vnet_hdr(nc)) {
+    if (qemu_has_vnet_hdr(nc->peer)) {
         return true;
     }
 
@@ -1933,10 +1933,10 @@ static void vmxnet3_net_init(VMXNET3State *s)
     s->lro_supported = false;
 
     if (s->peer_has_vhdr) {
-        qemu_peer_set_vnet_hdr_len(qemu_get_queue(s->nic),
+        qemu_set_vnet_hdr_len(qemu_get_queue(s->nic)->peer,
             sizeof(struct virtio_net_hdr));
 
-        qemu_peer_using_vnet_hdr(qemu_get_queue(s->nic), 1);
+        qemu_using_vnet_hdr(qemu_get_queue(s->nic)->peer, 1);
     }
 
     qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
diff --git a/include/net/net.h b/include/net/net.h
index 7b25394..8166345 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -132,13 +132,13 @@ ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf,
 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]);
-bool qemu_peer_has_ufo(NetClientState *nc);
-bool qemu_peer_has_vnet_hdr(NetClientState *nc);
-bool qemu_peer_has_vnet_hdr_len(NetClientState *nc, int len);
-void qemu_peer_using_vnet_hdr(NetClientState *nc, bool enable);
-void qemu_peer_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
-                           int ecn, int ufo);
-void qemu_peer_set_vnet_hdr_len(NetClientState *nc, int len);
+bool qemu_has_ufo(NetClientState *nc);
+bool qemu_has_vnet_hdr(NetClientState *nc);
+bool qemu_has_vnet_hdr_len(NetClientState *nc, int len);
+void qemu_using_vnet_hdr(NetClientState *nc, bool enable);
+void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
+                      int ecn, int ufo);
+void qemu_set_vnet_hdr_len(NetClientState *nc, int len);
 void qemu_macaddr_default_if_unset(MACAddr *macaddr);
 int qemu_show_nic_models(const char *arg, const char *const *models);
 void qemu_check_nic_model(NICInfo *nd, const char *model);
diff --git a/net/net.c b/net/net.c
index 06d690a..e3ef1e4 100644
--- a/net/net.c
+++ b/net/net.c
@@ -378,59 +378,59 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
     }
 }
 
-bool qemu_peer_has_ufo(NetClientState *nc)
+bool qemu_has_ufo(NetClientState *nc)
 {
-    if (!nc->peer || !nc->peer->info->has_ufo) {
+    if (!nc || !nc->info->has_ufo) {
         return false;
     }
 
-    return nc->peer->info->has_ufo(nc->peer);
+    return nc->info->has_ufo(nc);
 }
 
-bool qemu_peer_has_vnet_hdr(NetClientState *nc)
+bool qemu_has_vnet_hdr(NetClientState *nc)
 {
-    if (!nc->peer || !nc->peer->info->has_vnet_hdr) {
+    if (!nc || !nc->info->has_vnet_hdr) {
         return false;
     }
 
-    return nc->peer->info->has_vnet_hdr(nc->peer);
+    return nc->info->has_vnet_hdr(nc);
 }
 
-bool qemu_peer_has_vnet_hdr_len(NetClientState *nc, int len)
+bool qemu_has_vnet_hdr_len(NetClientState *nc, int len)
 {
-    if (!nc->peer || !nc->peer->info->has_vnet_hdr_len) {
+    if (!nc || !nc->info->has_vnet_hdr_len) {
         return false;
     }
 
-    return nc->peer->info->has_vnet_hdr_len(nc->peer, len);
+    return nc->info->has_vnet_hdr_len(nc, len);
 }
 
-void qemu_peer_using_vnet_hdr(NetClientState *nc, bool enable)
+void qemu_using_vnet_hdr(NetClientState *nc, bool enable)
 {
-    if (!nc->peer || !nc->peer->info->using_vnet_hdr) {
+    if (!nc || !nc->info->using_vnet_hdr) {
         return;
     }
 
-    nc->peer->info->using_vnet_hdr(nc->peer, enable);
+    nc->info->using_vnet_hdr(nc, enable);
 }
 
-void qemu_peer_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
+void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
                           int ecn, int ufo)
 {
-    if (!nc->peer || !nc->peer->info->set_offload) {
+    if (!nc || !nc->info->set_offload) {
         return;
     }
 
-    nc->peer->info->set_offload(nc->peer, csum, tso4, tso6, ecn, ufo);
+    nc->info->set_offload(nc, csum, tso4, tso6, ecn, ufo);
 }
 
-void qemu_peer_set_vnet_hdr_len(NetClientState *nc, int len)
+void qemu_set_vnet_hdr_len(NetClientState *nc, int len)
 {
-    if (!nc->peer || !nc->peer->info->set_vnet_hdr_len) {
+    if (!nc || !nc->info->set_vnet_hdr_len) {
         return;
     }
 
-    nc->peer->info->set_vnet_hdr_len(nc->peer, len);
+    nc->info->set_vnet_hdr_len(nc, len);
 }
 
 int qemu_can_send_packet(NetClientState *sender)
-- 
1.8.5.3

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

* [Qemu-devel] [PULL 10/11] vhost_net: use offload API instead of bypassing it
  2014-02-25 13:33 [Qemu-devel] [PULL 00/11] Net patches Stefan Hajnoczi
                   ` (8 preceding siblings ...)
  2014-02-25 13:33 ` [Qemu-devel] [PULL 09/11] net: remove implicit peer from offload API Stefan Hajnoczi
@ 2014-02-25 13:33 ` Stefan Hajnoczi
  2014-02-25 13:33 ` [Qemu-devel] [PULL 11/11] virtio-net: use qemu_get_queue() where possible Stefan Hajnoczi
  2014-02-26 20:52 ` [Qemu-devel] [PULL 00/11] Net patches Peter Maydell
  11 siblings, 0 replies; 13+ messages in thread
From: Stefan Hajnoczi @ 2014-02-25 13:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Anthony Liguori

There is no need to access backend->info->has_vnet_hdr() and friends
anymore.  Use the qemu_has_vnet_hdr() API instead.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/net/vhost_net.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index c90b9ec..a1de2f4 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -106,7 +106,7 @@ struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
         goto fail;
     }
     net->nc = backend;
-    net->dev.backend_features = backend->info->has_vnet_hdr(backend) ? 0 :
+    net->dev.backend_features = qemu_has_vnet_hdr(backend) ? 0 :
         (1 << VHOST_NET_F_VIRTIO_NET_HDR);
     net->backend = r;
 
@@ -117,8 +117,8 @@ struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
     if (r < 0) {
         goto fail;
     }
-    if (!backend->info->has_vnet_hdr_len(backend,
-                              sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
+    if (!qemu_has_vnet_hdr_len(backend,
+                               sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
         net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
     }
     if (~net->dev.features & net->dev.backend_features) {
-- 
1.8.5.3

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

* [Qemu-devel] [PULL 11/11] virtio-net: use qemu_get_queue() where possible
  2014-02-25 13:33 [Qemu-devel] [PULL 00/11] Net patches Stefan Hajnoczi
                   ` (9 preceding siblings ...)
  2014-02-25 13:33 ` [Qemu-devel] [PULL 10/11] vhost_net: use offload API instead of bypassing it Stefan Hajnoczi
@ 2014-02-25 13:33 ` Stefan Hajnoczi
  2014-02-26 20:52 ` [Qemu-devel] [PULL 00/11] Net patches Peter Maydell
  11 siblings, 0 replies; 13+ messages in thread
From: Stefan Hajnoczi @ 2014-02-25 13:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Anthony Liguori

qemu_get_queue() is a shorthand for qemu_get_subqueue(n->nic, 0).  Use
the shorthand where possible.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/net/virtio-net.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 9218a09..3c0342e 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -459,7 +459,7 @@ static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
 
 static void virtio_net_apply_guest_offloads(VirtIONet *n)
 {
-    qemu_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
+    qemu_set_offload(qemu_get_queue(n->nic)->peer,
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_CSUM)),
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)),
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)),
-- 
1.8.5.3

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

* Re: [Qemu-devel] [PULL 00/11] Net patches
  2014-02-25 13:33 [Qemu-devel] [PULL 00/11] Net patches Stefan Hajnoczi
                   ` (10 preceding siblings ...)
  2014-02-25 13:33 ` [Qemu-devel] [PULL 11/11] virtio-net: use qemu_get_queue() where possible Stefan Hajnoczi
@ 2014-02-26 20:52 ` Peter Maydell
  11 siblings, 0 replies; 13+ messages in thread
From: Peter Maydell @ 2014-02-26 20:52 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: QEMU Developers, Anthony Liguori

On 25 February 2014 13:33, Stefan Hajnoczi <stefanha@redhat.com> wrote:
> The following changes since commit c58e291591dbc1c846fa152d4792554803405ebb:
>
>   Merge remote-tracking branch 'remotes/sstabellini/xen-140220' into staging (2014-02-24 16:12:55 +0000)
>
> are available in the git repository at:
>
>
>   git://github.com/stefanha/qemu.git tags/net-pull-request
>
> for you to fetch changes up to ad37bb3b000963b36b5c30f5a4239cfbc4fe8725:
>
>   virtio-net: use qemu_get_queue() where possible (2014-02-25 14:31:05 +0100)

Applied, thanks.

-- PMM

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

end of thread, other threads:[~2014-02-26 20:53 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-25 13:33 [Qemu-devel] [PULL 00/11] Net patches Stefan Hajnoczi
2014-02-25 13:33 ` [Qemu-devel] [PULL 01/11] opencores_eth: flush queue whenever can_receive can go from false to true Stefan Hajnoczi
2014-02-25 13:33 ` [Qemu-devel] [PULL 02/11] net: change vnet-hdr TAP prototypes Stefan Hajnoczi
2014-02-25 13:33 ` [Qemu-devel] [PULL 03/11] net: extend NetClientInfo for offloading Stefan Hajnoczi
2014-02-25 13:33 ` [Qemu-devel] [PULL 04/11] net: TAP uses NetClientInfo offloading callbacks Stefan Hajnoczi
2014-02-25 13:33 ` [Qemu-devel] [PULL 05/11] net: virtio-net and vmxnet3 use offloading API Stefan Hajnoczi
2014-02-25 13:33 ` [Qemu-devel] [PULL 06/11] net: make tap offloading callbacks static Stefan Hajnoczi
2014-02-25 13:33 ` [Qemu-devel] [PULL 07/11] net: add offloading support to netmap backend Stefan Hajnoczi
2014-02-25 13:33 ` [Qemu-devel] [PULL 08/11] net: Disable netmap backend when not supported Stefan Hajnoczi
2014-02-25 13:33 ` [Qemu-devel] [PULL 09/11] net: remove implicit peer from offload API Stefan Hajnoczi
2014-02-25 13:33 ` [Qemu-devel] [PULL 10/11] vhost_net: use offload API instead of bypassing it Stefan Hajnoczi
2014-02-25 13:33 ` [Qemu-devel] [PULL 11/11] virtio-net: use qemu_get_queue() where possible Stefan Hajnoczi
2014-02-26 20:52 ` [Qemu-devel] [PULL 00/11] Net patches Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.