Messages in this thread Patch in this message | | | Date | Tue, 2 Mar 1999 18:01:20 +0100 (CET) | From | Andrea Arcangeli <> | Subject | Re: [patch] acks delayed and then merged in data-segment sent a bit after |
| |
On Tue, 2 Mar 1999, Andrea Arcangeli wrote:
>sender-userspace will kick out new data shortly. And to get this >ack-merging feature from the TCP we should not use a fixed HZ/50 timeout >but use the normal ato timeout to get the improvement over all kind of >underlying hardware.
This my idea was wrong too. The __only__ object of the HZ/50 timeout is to cope with merging the ack in the next packet full of data sent very soon. So it doesn't care how much the network device is fast, but it cares instead how much the userspace is fast to do a send() after read() is finished. We can't guess this time in any way and the only clean way to cope with this is to use a timeout of HZ/50.
The reason before yesterday I am always been against this HZ/50 value is that you never said me that it's _not_ set in the hope that the other end then will send us another packet after this one (as I was thinking).
It's instead used to merge the ack with the next send when possible and that's very important in slowlink like mine (and in the global Internet) to save a lots of bandwith in iteractive tcp connections.
The side effect of using HZ/50 is that we could have less raw speed sometimes because we delay the ack even if maybe there's no send() after the read(). So finally I thought that we could disable delayed acks if TCP_NODELAY is set. That way the tcp connection will be more responsive as possible without care about the traffic generated on the underlying device. I think it's rasonable. TCP_NODELAY don't want the maximal performance optimization of the network but want the maximal responsiveness of the tcp connection.
As last thought I think that delacks should not go under HZ/50 of timeout to always left the receiver to do then a send and merge the ack in the next data packet.
Setting TCP_NODELAY on the sock Josip should keep the x20 improvement without losing smartness in normal internet (also maybe offline) usage.
Here my current tree against 2.2.2, it does the thing I thought above:
Index: tcp_output.c =================================================================== RCS file: /var/cvs/linux/net/ipv4/tcp_output.c,v retrieving revision 1.1.1.5 diff -u -r1.1.1.5 tcp_output.c --- tcp_output.c 1999/02/23 16:48:26 1.1.1.5 +++ linux/net/ipv4/tcp_output.c 1999/03/02 16:53:50 @@ -973,6 +986,8 @@ timeout = tp->ato; if (timeout > max_timeout) timeout = max_timeout; + if (timeout < (HZ+49)/50) + timeout = (HZ+49)/50; timeout += jiffies; /* Use new timeout only if there wasn't a older one earlier. */ @@ -980,7 +995,7 @@ tp->delack_timer.expires = timeout; add_timer(&tp->delack_timer); } else { - if (timeout < tp->delack_timer.expires) + if (time_before(timeout, tp->delack_timer.expires)) mod_timer(&tp->delack_timer, timeout); } } Index: tcp_input.c =================================================================== RCS file: /var/cvs/linux/net/ipv4/tcp_input.c,v retrieving revision 1.1.1.6 diff -u -r1.1.1.6 tcp_input.c --- tcp_input.c 1999/02/23 16:48:26 1.1.1.6 +++ linux/net/ipv4/tcp_input.c 1999/03/02 16:53:50 @@ -55,6 +55,7 @@ * work without delayed acks. * Andi Kleen: Process packets with PSH set in the * fast path. + * Andrea Arcangeli: TCP_NODELAY disable delacks. */ #include <linux/config.h> @@ -103,8 +104,7 @@ * and also makes sure we do not take this * branch ever again for this connection. */ - tp->ato = 1; - tcp_enter_quickack_mode(tp); + tp->ato = (HZ+49)/50 | (1<<31); } else { int m = jiffies - tp->lrcvtime; @@ -135,9 +135,9 @@ */ if(th->psh && (skb->len < (tp->mss_cache >> 1))) { /* Preserve the quickack state. */ - if((tp->ato & 0x7fffffff) > HZ/50) + if((tp->ato & 0x7fffffff) > (HZ+49)/50) tp->ato = ((tp->ato & 0x80000000) | - (HZ/50)); + ((HZ+49)/50)); } } @@ -241,7 +241,7 @@ extern __inline__ int tcp_paws_discard(struct tcp_opt *tp, struct tcphdr *th, unsigned len) { /* ts_recent must be younger than 24 days */ - return (((jiffies - tp->ts_recent_stamp) >= PAWS_24DAYS) || + return (((s32)(jiffies - tp->ts_recent_stamp) >= PAWS_24DAYS) || (((s32)(tp->rcv_tsval-tp->ts_recent) < 0) && /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM */ (len != (th->doff * 4)))); @@ -1580,7 +1580,9 @@ /* We entered "quick ACK" mode or... */ tcp_in_quickack_mode(tp) || /* We have out of order data */ - (skb_peek(&tp->out_of_order_queue) != NULL)) { + (skb_peek(&tp->out_of_order_queue) != NULL) || + /* TCP_NODELAY is set */ + sk->nonagle == 1) { /* Then ack it now */ tcp_send_ack(sk); } else {
Comments?
I hope I am not causing wasting time to you if maybe I am thinking or implementing wrong things.
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/
| |