From 673fb149c6f3079d4d92ff3f938d44af592c49a6 Mon Sep 17 00:00:00 2001 From: thorpej Date: Wed, 31 Dec 1997 03:31:23 +0000 Subject: [PATCH] Implement a queue for delayed ACK processing. This queue is used in tcp_fasttimo() in lieu of scanning all open TCP connections. --- sys/netinet/tcp_input.c | 4 ++-- sys/netinet/tcp_output.c | 5 +++-- sys/netinet/tcp_subr.c | 3 ++- sys/netinet/tcp_timer.c | 25 +++++++++++++------------ sys/netinet/tcp_var.h | 27 ++++++++++++++++++++++++++- 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 51662ca59934..531e91267204 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $NetBSD: tcp_input.c,v 1.37 1997/12/11 06:33:29 thorpej Exp $ */ +/* $NetBSD: tcp_input.c,v 1.38 1997/12/31 03:31:23 thorpej Exp $ */ /* * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994 @@ -121,7 +121,7 @@ do { \ (tp)->t_flags & TF_DELACK) \ tp->t_flags |= TF_ACKNOW; \ else \ - tp->t_flags |= TF_DELACK; \ + TCP_SET_DELACK(tp); \ } while (0) /* diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index 421e8768594b..78cfcaa6463a 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1,4 +1,4 @@ -/* $NetBSD: tcp_output.c,v 1.25 1997/12/17 05:59:32 thorpej Exp $ */ +/* $NetBSD: tcp_output.c,v 1.26 1997/12/31 03:31:25 thorpej Exp $ */ /* * Copyright (c) 1982, 1986, 1988, 1990, 1993 @@ -642,7 +642,8 @@ out: if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv)) tp->rcv_adv = tp->rcv_nxt + win; tp->last_ack_sent = tp->rcv_nxt; - tp->t_flags &= ~(TF_ACKNOW|TF_DELACK); + tp->t_flags &= ~TF_ACKNOW; + TCP_CLEAR_DELACK(tp); if (sendalot) goto again; return (0); diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 723f33a6202f..4f4e83aedc4f 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: tcp_subr.c,v 1.36 1997/12/11 22:47:25 thorpej Exp $ */ +/* $NetBSD: tcp_subr.c,v 1.37 1997/12/31 03:31:26 thorpej Exp $ */ /* * Copyright (c) 1982, 1986, 1988, 1990, 1993 @@ -88,6 +88,7 @@ tcp_init() { in_pcbinit(&tcbtable, tcbhashsize, tcbhashsize); + LIST_INIT(&tcp_delacks); if (max_protohdr < sizeof(struct tcpiphdr)) max_protohdr = sizeof(struct tcpiphdr); if (max_linkhdr + sizeof(struct tcpiphdr) > MHLEN) diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index 41de101a8605..17f1e4dad667 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -1,4 +1,4 @@ -/* $NetBSD: tcp_timer.c,v 1.26 1997/12/17 06:04:17 thorpej Exp $ */ +/* $NetBSD: tcp_timer.c,v 1.27 1997/12/31 03:31:27 thorpej Exp $ */ /* * Copyright (c) 1982, 1986, 1988, 1990, 1993 @@ -71,26 +71,27 @@ extern int tcp_keepcnt; extern int tcp_maxpersistidle; #endif /* TUBA_INCLUDE */ +struct tcp_delack_head tcp_delacks; + /* * Fast timeout routine for processing delayed acks */ void tcp_fasttimo() { - register struct inpcb *inp; - register struct tcpcb *tp; + register struct tcpcb *tp, *ntp; int s; s = splsoftnet(); - inp = tcbtable.inpt_queue.cqh_first; - if (inp) /* XXX */ - for (; inp != (struct inpcb *)&tcbtable.inpt_queue; - inp = inp->inp_queue.cqe_next) { - if ((tp = intotcpcb(inp)) != NULL && - (tp->t_flags & TF_DELACK)) { - tp->t_flags |= TF_ACKNOW; - (void) tcp_output(tp); - } + for (tp = tcp_delacks.lh_first; tp != NULL; tp = ntp) { + /* + * If tcp_output() can't transmit the ACK for whatever + * reason, it will remain on the queue for the next + * time the heartbeat ticks. + */ + ntp = tp->t_delack.le_next; + tp->t_flags |= TF_ACKNOW; + (void) tcp_output(tp); } splx(s); } diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 912e6009c90b..b04885b7e124 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -1,4 +1,4 @@ -/* $NetBSD: tcp_var.h,v 1.31 1997/12/17 06:06:41 thorpej Exp $ */ +/* $NetBSD: tcp_var.h,v 1.32 1997/12/31 03:31:29 thorpej Exp $ */ /* * Copyright (c) 1982, 1986, 1993, 1994 @@ -67,6 +67,7 @@ struct tcpcb { struct tcpiphdr *t_template; /* skeletal packet for transmit */ struct inpcb *t_inpcb; /* back pointer to internet pcb */ + LIST_ENTRY(tcpcb) t_delack; /* delayed ACK queue */ /* * The following fields are used as in the protocol specification. * See RFC783, Dec. 1981, page 21. @@ -131,6 +132,30 @@ struct tcpcb { caddr_t t_tuba_pcb; /* next level down pcb for TCP over z */ }; +/* + * Queue for delayed ACK processing. + */ +LIST_HEAD(tcp_delack_head, tcpcb); +#ifdef _KERNEL +extern struct tcp_delack_head tcp_delacks; + +#define TCP_SET_DELACK(tp) \ +do { \ + if (((tp)->t_flags & TF_DELACK) == 0) { \ + (tp)->t_flags |= TF_DELACK; \ + LIST_INSERT_HEAD(&tcp_delacks, (tp), t_delack); \ + } \ +} while (0) + +#define TCP_CLEAR_DELACK(tp) \ +do { \ + if ((tp)->t_flags & TF_DELACK) { \ + (tp)->t_flags &= ~TF_DELACK; \ + LIST_REMOVE((tp), t_delack); \ + } \ +} while (0) +#endif /* _KERNEL */ + /* * Handy way of passing around TCP option info. */