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

[Xen-changelog] Checksum offload for local virtual networking, and to/from a physical



ChangeSet 1.1506, 2005/05/21 20:08:56+01:00, kaf24@viper.(none)

        Checksum offload for local virtual networking, and to/from a physical
        interface that may be connected via a virtual bridge or router. This 
adds
        a coupel of new fields to skbuffs that are intended to survive across IP
        or MAC level forwarding. I've tested basic connectivity with this patch,
        but further stress-testing and performance benchmarking is really 
required.
        Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>



 linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c |    1 
 linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c  |   10 
 linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c   |   22 
 linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c |    7 
 linux-2.6.11-xen-sparse/include/linux/skbuff.h          | 1184 +++++
 linux-2.6.11-xen-sparse/net/core/dev.c                  | 3389 ++++++++++++++++
 linux-2.6.11-xen-sparse/net/core/skbuff.c               | 1523 +++++++
 xen/include/public/io/netif.h                           |    6 
 8 files changed, 6133 insertions(+), 9 deletions(-)


diff -Nru a/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c 
b/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c   2005-05-22 
13:04:37 -04:00
+++ b/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c   2005-05-22 
13:04:37 -04:00
@@ -159,6 +159,7 @@
     dev->get_stats       = netif_be_get_stats;
     dev->open            = net_open;
     dev->stop            = net_close;
+    dev->features        = NETIF_F_NO_CSUM;
 
     /* Disable queuing. */
     dev->tx_queue_len = 0;
diff -Nru a/linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c 
b/linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c
--- a/linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c    2005-05-22 
13:04:37 -04:00
+++ b/linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c    2005-05-22 
13:04:37 -04:00
@@ -67,6 +67,11 @@
     np->stats.rx_bytes += skb->len;
     np->stats.rx_packets++;
 
+    if ( skb->ip_summed == CHECKSUM_HW )
+        skb->proto_csum_blank = 1;
+    skb->ip_summed = skb->proto_csum_valid ?
+        CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
+
     skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */
     skb->protocol = eth_type_trans(skb, dev);
     skb->dev      = dev;
@@ -95,6 +100,8 @@
 
     dev->tx_queue_len    = 0;
 
+    dev->features        = NETIF_F_HIGHDMA | NETIF_F_LLTX;
+
     /*
      * We do not set a jumbo MTU on the interface. Otherwise the network
      * stack will try to send large packets that will get dropped by the
@@ -117,6 +124,9 @@
 
     loopback_construct(dev1, dev2);
     loopback_construct(dev2, dev1);
+
+    dev1->features |= NETIF_F_NO_CSUM;
+    dev2->features |= NETIF_F_IP_CSUM;
 
     /*
      * Initialise a dummy MAC address for the 'dummy backend' interface. We
diff -Nru a/linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c 
b/linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c     2005-05-22 
13:04:37 -04:00
+++ b/linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c     2005-05-22 
13:04:37 -04:00
@@ -27,7 +27,8 @@
                              u16      id, 
                              s8       st,
                              memory_t addr,
-                             u16      size);
+                             u16      size,
+                             u16      csum_valid);
 
 static void net_tx_action(unsigned long unused);
 static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0);
@@ -154,6 +155,7 @@
         __skb_put(nskb, skb->len);
         (void)skb_copy_bits(skb, -hlen, nskb->data - hlen, skb->len + hlen);
         nskb->dev = skb->dev;
+        nskb->proto_csum_valid = skb->proto_csum_valid;
         dev_kfree_skb(skb);
         skb = nskb;
     }
@@ -308,7 +310,8 @@
 
         evtchn = netif->evtchn;
         id = netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
-        if ( make_rx_response(netif, id, status, mdata, size) &&
+        if ( make_rx_response(netif, id, status, mdata,
+                              size, skb->proto_csum_valid) &&
              (rx_notify[evtchn] == 0) )
         {
             rx_notify[evtchn] = 1;
@@ -646,6 +649,11 @@
         skb->dev      = netif->dev;
         skb->protocol = eth_type_trans(skb, skb->dev);
 
+        /* No checking needed on localhost, but remember the field is blank. */
+        skb->ip_summed        = CHECKSUM_UNNECESSARY;
+        skb->proto_csum_valid = 1;
+        skb->proto_csum_blank = txreq.csum_blank;
+
         netif->stats.rx_bytes += txreq.size;
         netif->stats.rx_packets++;
 
@@ -711,15 +719,17 @@
                             u16      id, 
                             s8       st,
                             memory_t addr,
-                            u16      size)
+                            u16      size,
+                            u16      csum_valid)
 {
     NETIF_RING_IDX i = netif->rx_resp_prod;
     netif_rx_response_t *resp;
 
     resp = &netif->rx->ring[MASK_NETIF_RX_IDX(i)].resp;
-    resp->addr   = addr;
-    resp->id     = id;
-    resp->status = (s16)size;
+    resp->addr       = addr;
+    resp->csum_valid = csum_valid;
+    resp->id         = id;
+    resp->status     = (s16)size;
     if ( st < 0 )
         resp->status = (s16)st;
     wmb();
diff -Nru a/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c 
b/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c   2005-05-22 
13:04:37 -04:00
+++ b/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c   2005-05-22 
13:04:37 -04:00
@@ -473,6 +473,7 @@
     tx->id   = id;
     tx->addr = virt_to_machine(skb->data);
     tx->size = skb->len;
+    tx->csum_blank = (skb->ip_summed == CHECKSUM_HW);
 
     wmb(); /* Ensure that backend will see the request. */
     np->tx->req_prod = i + 1;
@@ -573,6 +574,9 @@
         skb->len  = rx->status;
         skb->tail = skb->data + skb->len;
 
+        if ( rx->csum_valid )
+            skb->ip_summed = CHECKSUM_UNNECESSARY;
+
         np->stats.rx_packets++;
         np->stats.rx_bytes += rx->status;
 
@@ -967,7 +971,8 @@
     dev->get_stats       = network_get_stats;
     dev->poll            = netif_poll;
     dev->weight          = 64;
-    
+    dev->features        = NETIF_F_IP_CSUM;
+
     if ((err = register_netdev(dev)) != 0) {
         printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err);
         goto exit;
diff -Nru a/linux-2.6.11-xen-sparse/include/linux/skbuff.h 
b/linux-2.6.11-xen-sparse/include/linux/skbuff.h
--- /dev/null   Wed Dec 31 16:00:00 196900
+++ b/linux-2.6.11-xen-sparse/include/linux/skbuff.h    2005-05-22 13:04:37 
-04:00
@@ -0,0 +1,1184 @@
+/*
+ *     Definitions for the 'struct sk_buff' memory handlers.
+ *
+ *     Authors:
+ *             Alan Cox, <gw4pts@xxxxxxxxxxxxxxx>
+ *             Florian La Roche, <rzsfl@xxxxxxxxxxxx>
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     as published by the Free Software Foundation; either version
+ *     2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_SKBUFF_H
+#define _LINUX_SKBUFF_H
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/time.h>
+#include <linux/cache.h>
+
+#include <asm/atomic.h>
+#include <asm/types.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/poll.h>
+#include <linux/net.h>
+#include <net/checksum.h>
+
+#define HAVE_ALLOC_SKB         /* For the drivers to know */
+#define HAVE_ALIGNABLE_SKB     /* Ditto 8)                */
+#define SLAB_SKB               /* Slabified skbuffs       */
+
+#define CHECKSUM_NONE 0
+#define CHECKSUM_HW 1
+#define CHECKSUM_UNNECESSARY 2
+
+#define SKB_DATA_ALIGN(X)      (((X) + (SMP_CACHE_BYTES - 1)) & \
+                                ~(SMP_CACHE_BYTES - 1))
+#define SKB_MAX_ORDER(X, ORDER)        (((PAGE_SIZE << (ORDER)) - (X) - \
+                                 sizeof(struct skb_shared_info)) & \
+                                 ~(SMP_CACHE_BYTES - 1))
+#define SKB_MAX_HEAD(X)                (SKB_MAX_ORDER((X), 0))
+#define SKB_MAX_ALLOC          (SKB_MAX_ORDER(0, 2))
+
+/* A. Checksumming of received packets by device.
+ *
+ *     NONE: device failed to checksum this packet.
+ *             skb->csum is undefined.
+ *
+ *     UNNECESSARY: device parsed packet and wouldbe verified checksum.
+ *             skb->csum is undefined.
+ *           It is bad option, but, unfortunately, many of vendors do this.
+ *           Apparently with secret goal to sell you new device, when you
+ *           will add new protocol to your host. F.e. IPv6. 8)
+ *
+ *     HW: the most generic way. Device supplied checksum of _all_
+ *         the packet as seen by netif_rx in skb->csum.
+ *         NOTE: Even if device supports only some protocols, but
+ *         is able to produce some skb->csum, it MUST use HW,
+ *         not UNNECESSARY.
+ *
+ * B. Checksumming on output.
+ *
+ *     NONE: skb is checksummed by protocol or csum is not required.
+ *
+ *     HW: device is required to csum packet as seen by hard_start_xmit
+ *     from skb->h.raw to the end and to record the checksum
+ *     at skb->h.raw+skb->csum.
+ *
+ *     Device must show its capabilities in dev->features, set
+ *     at device setup time.
+ *     NETIF_F_HW_CSUM - it is clever device, it is able to checksum
+ *                       everything.
+ *     NETIF_F_NO_CSUM - loopback or reliable single hop media.
+ *     NETIF_F_IP_CSUM - device is dumb. It is able to csum only
+ *                       TCP/UDP over IPv4. Sigh. Vendors like this
+ *                       way by an unknown reason. Though, see comment above
+ *                       about CHECKSUM_UNNECESSARY. 8)
+ *
+ *     Any questions? No questions, good.              --ANK
+ */
+
+#ifdef __i386__
+#define NET_CALLER(arg) (*(((void **)&arg) - 1))
+#else
+#define NET_CALLER(arg) __builtin_return_address(0)
+#endif
+
+struct net_device;
+
+#ifdef CONFIG_NETFILTER
+struct nf_conntrack {
+       atomic_t use;
+       void (*destroy)(struct nf_conntrack *);
+};
+
+#ifdef CONFIG_BRIDGE_NETFILTER
+struct nf_bridge_info {
+       atomic_t use;
+       struct net_device *physindev;
+       struct net_device *physoutdev;
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.