Re: [UPDATE] zerocopy BETA 3

From: Jan Rekorajski (baggins@sith.mimuw.edu.pl)
Date: Sat Feb 24 2001 - 22:54:20 EST


On Sun, 25 Feb 2001, Chris Wedgwood wrote:

> On Fri, Feb 23, 2001 at 11:42:49AM +0100, Jan Rekorajski wrote:
>
> Could you please make a patch with this fix only? Or is it
> available somewhere?
>
[cut incomplete patch ;)]

There are more changes, I hacked'em out of vger CVS:

diff -urN linux/include/net/ip.h linux.fixed/include/net/ip.h
--- linux/include/net/ip.h Thu Feb 22 01:10:38 2001
+++ linux.fixed/include/net/ip.h Fri Feb 23 14:40:40 2001
@@ -188,11 +188,16 @@
 
 extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst);
 
-static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst)
+static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk)
 {
- if (iph->frag_off&__constant_htons(IP_DF))
- iph->id = 0;
- else
+ if (iph->frag_off&__constant_htons(IP_DF)) {
+ /* This is only to work around buggy Windows95/2000
+ * VJ compression implementations. If the ID field
+ * does not change, they drop every other packet in
+ * a TCP stream using header compression.
+ */
+ iph->id = (sk ? sk->protinfo.af_inet.id++ : 0);
+ } else
                 __ip_select_ident(iph, dst);
 }
 
diff -urN linux/include/net/ipip.h linux.fixed/include/net/ipip.h
--- linux/include/net/ipip.h Sat Aug 5 03:18:49 2000
+++ linux.fixed/include/net/ipip.h Fri Feb 23 14:40:43 2001
@@ -30,7 +30,7 @@
         int pkt_len = skb->len; \
                                                                         \
         iph->tot_len = htons(skb->len); \
- ip_select_ident(iph, &rt->u.dst); \
+ ip_select_ident(iph, &rt->u.dst, NULL); \
         ip_send_check(iph); \
                                                                         \
         err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, do_ip_send); \
diff -urN linux/include/net/sock.h linux.fixed/include/net/sock.h
--- linux/include/net/sock.h Thu Feb 22 01:10:24 2001
+++ linux.fixed/include/net/sock.h Fri Feb 23 14:40:49 2001
@@ -204,6 +204,7 @@
         __u8 mc_loop; /* Loopback */
         unsigned recverr : 1,
                                 freebind : 1;
+ __u16 id; /* ID counter for DF pkts */
         __u8 pmtudisc;
         int mc_index; /* Multicast device index */
         __u32 mc_addr;
diff -urN linux/net/ipv4/af_inet.c linux.fixed/net/ipv4/af_inet.c
--- linux/net/ipv4/af_inet.c Fri Dec 29 23:07:24 2000
+++ linux.fixed/net/ipv4/af_inet.c Fri Feb 23 14:40:34 2001
@@ -355,6 +355,8 @@
         else
                 sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
 
+ sk->protinfo.af_inet.id = 0;
+
         sock_init_data(sock,sk);
 
         sk->destruct = inet_sock_destruct;
diff -urN linux/net/ipv4/igmp.c linux.fixed/net/ipv4/igmp.c
--- linux/net/ipv4/igmp.c Tue Jan 9 19:54:57 2001
+++ linux.fixed/net/ipv4/igmp.c Fri Feb 23 14:40:38 2001
@@ -235,7 +235,7 @@
         iph->saddr = rt->rt_src;
         iph->protocol = IPPROTO_IGMP;
         iph->tot_len = htons(IGMP_SIZE);
- ip_select_ident(iph, &rt->u.dst);
+ ip_select_ident(iph, &rt->u.dst, NULL);
         ((u8*)&iph[1])[0] = IPOPT_RA;
         ((u8*)&iph[1])[1] = 4;
         ((u8*)&iph[1])[2] = 0;
diff -urN linux/net/ipv4/ip_output.c linux.fixed/net/ipv4/ip_output.c
--- linux/net/ipv4/ip_output.c Fri Oct 27 20:03:14 2000
+++ linux.fixed/net/ipv4/ip_output.c Fri Feb 23 14:54:17 2001
@@ -141,7 +141,7 @@
         iph->saddr = rt->rt_src;
         iph->protocol = sk->protocol;
         iph->tot_len = htons(skb->len);
- ip_select_ident(iph, &rt->u.dst);
+ ip_select_ident(iph, &rt->u.dst, sk);
         skb->nh.iph = iph;
 
         if (opt && opt->optlen) {
@@ -307,7 +307,7 @@
         if (ip_dont_fragment(sk, &rt->u.dst))
                 iph->frag_off |= __constant_htons(IP_DF);
 
- ip_select_ident(iph, &rt->u.dst);
+ ip_select_ident(iph, &rt->u.dst, sk);
 
         /* Add an IP checksum. */
         ip_send_check(iph);
@@ -328,7 +328,7 @@
                 kfree_skb(skb);
                 return -EMSGSIZE;
         }
- ip_select_ident(iph, &rt->u.dst);
+ ip_select_ident(iph, &rt->u.dst, sk);
         return ip_fragment(skb, skb->dst->output);
 }
 
@@ -425,7 +425,7 @@
         int err;
         int offset, mf;
         int mtu;
- u16 id = 0;
+ u16 id;
 
         int hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
         int nfrags=0;
@@ -495,6 +495,8 @@
          * Begin outputting the bytes.
          */
 
+ id = (sk ? sk->protinfo.af_inet.id++ : 0);
+
         do {
                 char *data;
                 struct sk_buff * skb;
@@ -677,7 +679,7 @@
                 iph->tot_len = htons(length);
                 iph->frag_off = df;
                 iph->ttl=sk->protinfo.af_inet.mc_ttl;
- ip_select_ident(iph, &rt->u.dst);
+ ip_select_ident(iph, &rt->u.dst, sk);
                 if (rt->rt_type != RTN_MULTICAST)
                         iph->ttl=sk->protinfo.af_inet.ttl;
                 iph->protocol=sk->protocol;
diff -urN linux/net/ipv4/ipmr.c linux.fixed/net/ipv4/ipmr.c
--- linux/net/ipv4/ipmr.c Wed Nov 29 06:53:45 2000
+++ linux.fixed/net/ipv4/ipmr.c Fri Feb 23 14:40:45 2001
@@ -1092,7 +1092,7 @@
         iph->protocol = IPPROTO_IPIP;
         iph->ihl = 5;
         iph->tot_len = htons(skb->len);
- ip_select_ident(iph, skb->dst);
+ ip_select_ident(iph, skb->dst, NULL);
         ip_send_check(iph);
 
         skb->h.ipiph = skb->nh.iph;
diff -urN linux/net/ipv4/raw.c linux.fixed/net/ipv4/raw.c
--- linux/net/ipv4/raw.c Fri Feb 9 20:29:44 2001
+++ linux.fixed/net/ipv4/raw.c Fri Feb 23 14:40:47 2001
@@ -296,7 +296,7 @@
                   * ip_build_xmit clean (well less messy).
                  */
                 if (!iph->id)
- ip_select_ident(iph, rfh->dst);
+ ip_select_ident(iph, rfh->dst, NULL);
                 iph->check=ip_fast_csum((unsigned char *)iph, iph->ihl);
         }
         return 0;

> FWIW; I am still seeing _really_ bad throughput on a 10M ethernet
> segment between 2.4.2+zc-2 and Windows98 SE. Nobody else has
> complained so I guess it is something local (mii-tool for Windows
> wouldn't be a bad idea), but if the above doesn't work for you I'd
> been keen to know about it.

I hadn't the time to test it fully yet, but DaveM's quick and dirty patch
for this cured my problems.

Jan

-- 
Jan Rêkorajski            |  ALL SUSPECTS ARE GUILTY. PERIOD!
baggins<at>mimuw.edu.pl   |  OTHERWISE THEY WOULDN'T BE SUSPECTS, WOULD THEY?
BOFH, MANIAC              |                   -- TROOPS by Kevin Rubio
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Feb 28 2001 - 21:00:09 EST