Hi,
        Neterion Xframe adapter supports TSO over IPv6 but the linux kernel 
        don't support TSO over Ipv6. This patch will allow TCP
        Segmentation Offload (TSO) packets to be created over IPv6. 
        
        The following table shows there is significant improvement in
        throughput with normal frames and CPU usage for both normal and jumbo.

        --------------------------------------------------
        |          |     1500        |      9600         |
        |          ------------------|-------------------|
        |          | thru     CPU    |  thru     CPU     |
        --------------------------------------------------
        | TSO OFF  | 1.80   2.0% id  |  5.53   1.0% id   |
        --------------------------------------------------
        | TSO ON   | 2.61   74.0 id  |  5.52   32.0% id  |
        --------------------------------------------------

Please review the patch.

Signed-off-by: Ananda Raju <[EMAIL PROTECTED]>
---
diff -upNr netdev.org/drivers/net/s2io.c netdev.ipv6_tso/drivers/net/s2io.c
--- netdev.org/drivers/net/s2io.c       2006-06-02 07:29:22.000000000 -0700
+++ netdev.ipv6_tso/drivers/net/s2io.c  2006-06-02 09:37:50.000000000 -0700
@@ -6211,6 +6211,7 @@ Defaulting to INTA\n");
 #endif
 
        dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+       dev->features |= NETIF_F_IP6_CSUM;
        if (sp->high_dma_flag == TRUE)
                dev->features |= NETIF_F_HIGHDMA;
 #ifdef NETIF_F_TSO
diff -upNr netdev.org/include/linux/netdevice.h 
netdev.ipv6_tso/include/linux/netdevice.h
--- netdev.org/include/linux/netdevice.h        2006-06-02 07:28:21.000000000 
-0700
+++ netdev.ipv6_tso/include/linux/netdevice.h   2006-06-02 08:30:54.000000000 
-0700
@@ -310,6 +310,7 @@ struct net_device
 #define NETIF_F_TSO            2048    /* Can offload TCP/IP segmentation */
 #define NETIF_F_LLTX           4096    /* LockLess TX */
 #define NETIF_F_UFO             8192    /* Can offload UDP Large Send*/
+#define NETIF_F_IP6_CSUM       16384   /* Can checksum TCP/UDP over IPv6 */
 
        struct net_device       *next_sched;
 
diff -upNr netdev.org/net/ipv6/af_inet6.c netdev.ipv6_tso/net/ipv6/af_inet6.c
--- netdev.org/net/ipv6/af_inet6.c      2006-06-02 06:51:57.000000000 -0700
+++ netdev.ipv6_tso/net/ipv6/af_inet6.c 2006-06-02 09:56:05.000000000 -0700
@@ -660,8 +660,11 @@ int inet6_sk_rebuild_header(struct sock 
                }
 
                ip6_dst_store(sk, dst, NULL);
-               sk->sk_route_caps = dst->dev->features &
-                       ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+               if (dst->dev->features & NETIF_F_IP6_CSUM)
+                       sk->sk_route_caps = dst->dev->features;
+               else
+                       sk->sk_route_caps = dst->dev->features &
+                               ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
        }
 
        return 0;
diff -upNr netdev.org/net/ipv6/inet6_connection_sock.c 
netdev.ipv6_tso/net/ipv6/inet6_connection_sock.c
--- netdev.org/net/ipv6/inet6_connection_sock.c 2006-06-02 06:52:06.000000000 
-0700
+++ netdev.ipv6_tso/net/ipv6/inet6_connection_sock.c    2006-06-02 
09:54:50.000000000 -0700
@@ -187,8 +187,11 @@ int inet6_csk_xmit(struct sk_buff *skb, 
                }
 
                ip6_dst_store(sk, dst, NULL);
-               sk->sk_route_caps = dst->dev->features &
-                       ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+               if (dst->dev->features & NETIF_F_IP6_CSUM)
+                       sk->sk_route_caps = dst->dev->features;
+               else
+                       sk->sk_route_caps = dst->dev->features &
+                               ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
        }
 
        skb->dst = dst_clone(dst);
diff -upNr netdev.org/net/ipv6/ip6_output.c 
netdev.ipv6_tso/net/ipv6/ip6_output.c
--- netdev.org/net/ipv6/ip6_output.c    2006-06-02 06:55:31.000000000 -0700
+++ netdev.ipv6_tso/net/ipv6/ip6_output.c       2006-06-02 08:50:29.000000000 
-0700
@@ -147,7 +147,8 @@ static int ip6_output2(struct sk_buff *s
 
 int ip6_output(struct sk_buff *skb)
 {
-       if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->ufo_size) ||
+       if ((skb->len > dst_mtu(skb->dst) &&
+            !(skb_shinfo(skb)->tso_size || skb_shinfo(skb)->ufo_size)) ||
                                dst_allfrag(skb->dst))
                return ip6_fragment(skb, ip6_output2);
        else
@@ -229,7 +230,7 @@ int ip6_xmit(struct sock *sk, struct sk_
        skb->priority = sk->sk_priority;
 
        mtu = dst_mtu(dst);
-       if ((skb->len <= mtu) || ipfragok) {
+       if ((skb->len <= mtu) || ipfragok || skb_shinfo(skb)->tso_size) {
                IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
                return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev,
                                dst_output);
diff -upNr netdev.org/net/ipv6/tcp_ipv6.c netdev.ipv6_tso/net/ipv6/tcp_ipv6.c
--- netdev.org/net/ipv6/tcp_ipv6.c      2006-06-02 06:52:12.000000000 -0700
+++ netdev.ipv6_tso/net/ipv6/tcp_ipv6.c 2006-06-02 09:59:01.000000000 -0700
@@ -271,8 +271,12 @@ static int tcp_v6_connect(struct sock *s
        inet->rcv_saddr = LOOPBACK4_IPV6;
 
        ip6_dst_store(sk, dst, NULL);
-       sk->sk_route_caps = dst->dev->features &
-               ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+
+       if (dst->dev->features & NETIF_F_IP6_CSUM)
+               sk->sk_route_caps = dst->dev->features;
+       else
+               sk->sk_route_caps = dst->dev->features &
+                       ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
 
        icsk->icsk_ext_hdr_len = 0;
        if (np->opt)
@@ -931,8 +935,12 @@ static struct sock * tcp_v6_syn_recv_soc
         */
 
        ip6_dst_store(newsk, dst, NULL);
-       newsk->sk_route_caps = dst->dev->features &
-               ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+
+       if (dst->dev->features & NETIF_F_IP6_CSUM)
+               newsk->sk_route_caps = dst->dev->features;
+       else
+               newsk->sk_route_caps = dst->dev->features &
+                       ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
 
        newtcp6sk = (struct tcp6_sock *)newsk;
        inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to