[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |