lkml.org 
[lkml]   [1999]   [Mar]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch] fixed af_packet to not lose frames and made us crazy in debugging TCP/IP ;) [Re: TCP window updates [Was: PROBLEM: Sending mail-attachment]]
On Tue, 9 Mar 1999, Andrea Arcangeli wrote:

>On Mon, 8 Mar 1999, David Miller wrote:
>
>>tcpdump sniffs the "wire", this means incoming and outgoing packets,
>>thus you are seeing loopback transmit and receive every frame.
>
>Yes infact a tcpdump -l | uniq should be enough to simplify the duplicated
>data.
>
>I know this, but my point is that it seems to me that some packet gets
>completly dropped in some cases.
>
>If you look closely at the tcp trace I attached at my previous email:
>
>01:22:08.669493 localhost.1029 > localhost.3334: S 846173315:846173315(0) win 31072 <mss 3884,sackOK,timestamp 89653 0,nop,wscale 0> (DF)
>01:22:08.669493 localhost.1029 > localhost.3334: S 846173315:846173315(0) win 31072 <mss 3884,sackOK,timestamp 89653 0,nop,wscale 0> (DF)
>01:22:08.669547 localhost.3334 > localhost.1029: S 844580933:844580933(0) ack 846173316 win 31072 <mss 3884,sackOK,timestamp 89653 89653,nop,wscale 0> (DF)
>01:22:08.669547 localhost.3334 > localhost.1029: S 844580933:844580933(0) ack 846173316 win 31072 <mss 3884,sackOK,timestamp 89653 89653,nop,wscale 0> (DF)
>01:22:08.669587 localhost.1029 > localhost.3334: . ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.669587 localhost.1029 > localhost.3334: . ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.669739 localhost.3334 > localhost.1029: . 1:3873(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.669739 localhost.3334 > localhost.1029: . 1:3873(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.669781 localhost.1029 > localhost.3334: . ack 3873 win 27200 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.669781 localhost.1029 > localhost.3334: . ack 3873 win 27200 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670064 localhost.3334 > localhost.1029: . 3873:7745(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670073 localhost.3334 > localhost.1029: . 7745:11617(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670064 localhost.3334 > localhost.1029: . 3873:7745(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670098 localhost.1029 > localhost.3334: . ack 7745 win 27104 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670073 localhost.3334 > localhost.1029: . 7745:11617(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670098 localhost.1029 > localhost.3334: . ack 7745 win 27104 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670123 localhost.3334 > localhost.1029: . 11617:15489(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670131 localhost.3334 > localhost.1029: . 15489:19361(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670123 localhost.3334 > localhost.1029: . 11617:15489(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670146 localhost.1029 > localhost.3334: . ack 15489 win 23232 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670131 localhost.3334 > localhost.1029: . 15489:19361(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670146 localhost.1029 > localhost.3334: . ack 15489 win 23232 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670170 localhost.3334 > localhost.1029: . 19361:23233(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670178 localhost.3334 > localhost.1029: . 23233:27105(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670187 localhost.3334 > localhost.1029: . 27105:30977(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670170 localhost.3334 > localhost.1029: . 19361:23233(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670203 localhost.1029 > localhost.3334: . ack 23233 win 19360 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670178 localhost.3334 > localhost.1029: . 23233:27105(3872) ack 1 win 31072 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670222 localhost.1029 > localhost.3334: . ack 30977 win 15488 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670203 localhost.1029 > localhost.3334: . ack 23233 win 19360 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670222 localhost.1029 > localhost.3334: . ack 30977 win 15488 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670290 localhost.1029 > localhost.3334: . ack 38721 win 11616 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670308 localhost.1029 > localhost.3334: . ack 46465 win 7744 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670290 localhost.1029 > localhost.3334: . ack 38721 win 11616 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670308 localhost.1029 > localhost.3334: . ack 46465 win 7744 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.670361 localhost.1029 > localhost.3334: . ack 54209 win 3872 <nop,nop,timestamp 89653 89653> (DF)
>01:22:08.678085 localhost.1029 > localhost.3334: . ack 57501 win 580 <nop,nop,timestamp 89654 89653> (DF)
>01:22:08.678123 localhost.3334 > localhost.1029: P 54209:57501(3292) ack 1 win 31072 <nop,nop,timestamp 89654 89653> (DF)
>01:22:08.678085 localhost.1029 > localhost.3334: . ack 57501 win 580 <nop,nop,timestamp 89654 89653> (DF)
>01:22:08.678123 localhost.3334 > localhost.1029: P 54209:57501(3292) ack 1 win 31072 <nop,nop,timestamp 89654 89653> (DF)
>01:22:08.678157 localhost.1029 > localhost.3334: . ack 57501 win 580 <nop,nop,timestamp 89654 89654> (DF)
>
>The packets between 27105 and 54209 looks like dropped according to the
>trace while instead they are been received correctly. How do you explain
>that? Could it be a bug in the af_packet code or a loopback specific
>problem? Or a bug in tcpdump or maybe I only need a looong sleep ;)?

Oh well, it's a af_packet bug. Or better a feature that I consider a bug.

The problem is more easily reproducible with the loopback device that
rarely go to sleep because the sender just netif_rx for the receiver, and
so tcpdump flush the queued packets from it's rcvbuf too late, when the
rcvbuf is just been full for ages and so af_packet had just to drop some
_always_ interesting packet from its receive queue.

So I fixed the thing simply changing af_packet to ignore the rcvbuf
limits. I think it's a good thing to be sure to always have a _relialable_
tcpdump.

Note that the bad behavior of 2.2.x could happens also on device other
than the loopback one, so Kris, I suggest you to try out this my new patch
and let us know if you can still reproduce the `TCP forgot to send out one
frame' problem that you managed to reproduce using tcpdump on both sides
(and both sides was 2.2.x looking at your previous emails). Maybe it's
unrelated (also because ppp is quite slow and tcpdump should be wakenup
quite fast) but I think it worth to try it out.

Here my af_packet fix against 2.2.3:

Index: include/net/sock.h
===================================================================
RCS file: /var/cvs/linux/include/net/sock.h,v
retrieving revision 1.1.2.7
diff -u -r1.1.2.7 sock.h
--- sock.h 1999/03/09 01:24:05 1.1.2.7
+++ linux/include/net/sock.h 1999/03/12 17:38:50
@@ -843,14 +843,8 @@
}


-extern __inline__ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+extern __inline__ void force_sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
- /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
- number of warnings when compiling with -W --ANK
- */
- if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf)
- return -ENOMEM;
-
#ifdef CONFIG_FILTER
if (sk->filter && sk_filter(skb, sk->filter))
return -EPERM; /* Toss packet */
@@ -860,6 +854,17 @@
skb_queue_tail(&sk->receive_queue, skb);
if (!sk->dead)
sk->data_ready(sk,skb->len);
+}
+
+extern __inline__ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+{
+ /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
+ number of warnings when compiling with -W --ANK
+ */
+ if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf)
+ return -ENOMEM;
+
+ force_sock_queue_rcv_skb(sk, skb);
return 0;
}

Index: net/packet/af_packet.c
===================================================================
RCS file: /var/cvs/linux/net/packet/af_packet.c,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 af_packet.c
--- af_packet.c 1999/01/18 01:35:01 1.1.2.1
+++ linux/net/packet/af_packet.c 1999/03/12 18:17:18
@@ -33,6 +33,7 @@
* Alan Cox : Protocol setting support
* Alexey Kuznetsov : Untied from IPv4 stack.
* Cyrus Durgin : Fixed kerneld for kmod.
+ * Andrea Arcangeli : Don't lose frames anymore.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -233,16 +234,17 @@
spkt->spkt_protocol = skb->protocol;

/*
- * Charge the memory to the socket. This is done specifically
- * to prevent sockets using all the memory up.
+ * Sock packet can be created by root and the only thing that root
+ * cares when him uses af_packet is to _not_ lose frames. So
+ * completly ignore the rcvbuf limit and queue as much skb
+ * as possible. This avoids us to lose frames and become crazy
+ * while debugging TCP/IP ;). No, this won't either impact the
+ * stability of the system because we woundn't reach this point if
+ * the machine would been OOM because the skb woundn't be alloced in
+ * first place. -arca
*/
+ force_sock_queue_rcv_skb(sk,skb);

- if (sock_queue_rcv_skb(sk,skb)<0)
- {
- kfree_skb(skb);
- return 0;
- }
-
/*
* Processing complete.
*/
@@ -409,15 +411,16 @@
}

/*
- * Charge the memory to the socket. This is done specifically
- * to prevent sockets using all the memory up.
+ * Sock packet can be created by root and the only thing that root
+ * cares when him uses af_packet is to _not_ lose frames. So
+ * completly ignore the rcvbuf limit and queue as much skb
+ * as possible. This avoids us to lose frames and become crazy
+ * while debugging TCP/IP ;). No, this won't either impact the
+ * stability of the system because we woundn't reach this point if
+ * the machine would been OOM because the skb woundn't be alloced in
+ * first place. -arca
*/
-
- if (sock_queue_rcv_skb(sk,skb)<0)
- {
- kfree_skb(skb);
- return 0;
- }
+ force_sock_queue_rcv_skb(sk,skb);
return(0);
}

BTW, why are we kprinting this message?

tcpdump uses obsolete (PF_INET,SOCK_PACKET)

Andrea Arcangeli


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:50    [W:1.647 / U:0.304 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site