diff -r e24734266067 -r 85624db56a91 sys/netinet/tcp_input.c --- a/sys/netinet/tcp_input.c Sun Aug 08 14:28:12 2010 +1000 +++ b/sys/netinet/tcp_input.c Sun Aug 08 17:24:40 2010 +1000 @@ -1240,7 +1240,7 @@ tp->snd_nxt == tp->snd_max && tiwin && tiwin == tp->snd_wnd && ((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) && - LIST_EMPTY(&tp->t_segq) && + LIST_EMPTY(tp->t_segq) && ((to.to_flags & TOF_TS) == 0 || TSTMP_GEQ(to.to_tsval, tp->ts_recent)) ) { @@ -2570,7 +2570,7 @@ * fast retransmit can work). */ if (th->th_seq == tp->rcv_nxt && - LIST_EMPTY(&tp->t_segq) && + LIST_EMPTY(tp->t_segq) && TCPS_HAVEESTABLISHED(tp->t_state)) { if (DELAY_ACK(tp)) tp->t_flags |= TF_DELACK; diff -r e24734266067 -r 85624db56a91 sys/netinet/tcp_reass.c --- a/sys/netinet/tcp_reass.c Sun Aug 08 14:28:12 2010 +1000 +++ b/sys/netinet/tcp_reass.c Sun Aug 08 17:24:40 2010 +1000 @@ -142,10 +142,13 @@ struct tseg_qent *nq; struct tseg_qent *te = NULL; struct socket *so = tp->t_inpcb->inp_socket; + struct tsegq *t_segq; int flags; INP_WLOCK_ASSERT(tp->t_inpcb); + t_segq = tp->t_segq; + /* * XXX: tcp_reass() is rather inefficient with its data structures * and should be rewritten (see NetBSD for optimizations). @@ -167,7 +170,7 @@ */ if (th->th_seq != tp->rcv_nxt && (V_tcp_reass_qsize + 1 >= V_tcp_reass_maxseg || - tp->t_segqlen >= V_tcp_reass_maxqlen)) { + t_segq->tsegq_mbufs >= V_tcp_reass_maxqlen)) { V_tcp_reass_overflows++; TCPSTAT_INC(tcps_rcvmemdrop); m_freem(m); @@ -186,13 +189,13 @@ *tlenp = 0; return (0); } - tp->t_segqlen++; + t_segq->tsegq_mbufs++; V_tcp_reass_qsize++; /* * Find a segment which begins after this one does. */ - LIST_FOREACH(q, &tp->t_segq, tqe_q) { + LIST_FOREACH(q, t_segq, tqe_q) { if (SEQ_GT(q->tqe_th->th_seq, th->th_seq)) break; p = q; @@ -213,7 +216,7 @@ TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); m_freem(m); uma_zfree(V_tcp_reass_zone, te); - tp->t_segqlen--; + t_segq->tsegq_mbufs--; V_tcp_reass_qsize--; /* * Try to present any queued data @@ -250,7 +253,7 @@ LIST_REMOVE(q, tqe_q); m_freem(q->tqe_m); uma_zfree(V_tcp_reass_zone, q); - tp->t_segqlen--; + t_segq->tsegq_mbufs--; V_tcp_reass_qsize--; q = nq; } @@ -261,7 +264,7 @@ te->tqe_len = *tlenp; if (p == NULL) { - LIST_INSERT_HEAD(&tp->t_segq, te, tqe_q); + LIST_INSERT_HEAD(t_segq, te, tqe_q); } else { LIST_INSERT_AFTER(p, te, tqe_q); } @@ -273,7 +276,7 @@ */ if (!TCPS_HAVEESTABLISHED(tp->t_state)) return (0); - q = LIST_FIRST(&tp->t_segq); + q = LIST_FIRST(t_segq); if (!q || q->tqe_th->th_seq != tp->rcv_nxt) return (0); SOCKBUF_LOCK(&so->so_rcv); @@ -287,7 +290,7 @@ else sbappendstream_locked(&so->so_rcv, q->tqe_m); uma_zfree(V_tcp_reass_zone, q); - tp->t_segqlen--; + t_segq->tsegq_mbufs--; V_tcp_reass_qsize--; q = nq; } while (q && q->tqe_th->th_seq == tp->rcv_nxt); diff -r e24734266067 -r 85624db56a91 sys/netinet/tcp_subr.c --- a/sys/netinet/tcp_subr.c Sun Aug 08 14:28:12 2010 +1000 +++ b/sys/netinet/tcp_subr.c Sun Aug 08 17:24:40 2010 +1000 @@ -288,6 +288,7 @@ struct tcpcb_mem { struct tcpcb tcb; struct tcp_timer tt; + struct tsegq tsq; }; static VNET_DEFINE(uma_zone_t, tcpcb_zone); @@ -696,7 +697,7 @@ tp->t_vnet = inp->inp_vnet; #endif tp->t_timers = &tm->tt; - /* LIST_INIT(&tp->t_segq); */ /* XXX covered by M_ZERO */ + tp->t_segq = &tm->tsq; tp->t_maxseg = tp->t_maxopd = #ifdef INET6 isipv6 ? V_tcp_v6mssdflt : @@ -857,11 +858,11 @@ } /* free the reassembly queue, if any */ - while ((q = LIST_FIRST(&tp->t_segq)) != NULL) { + while ((q = LIST_FIRST(tp->t_segq)) != NULL) { LIST_REMOVE(q, tqe_q); m_freem(q->tqe_m); uma_zfree(V_tcp_reass_zone, q); - tp->t_segqlen--; + tp->t_segq->tsegq_mbufs--; V_tcp_reass_qsize--; } /* Disconnect offload device, if any. */ @@ -937,12 +938,12 @@ continue; INP_WLOCK(inpb); if ((tcpb = intotcpcb(inpb)) != NULL) { - while ((te = LIST_FIRST(&tcpb->t_segq)) + while ((te = LIST_FIRST(tcpb->t_segq)) != NULL) { LIST_REMOVE(te, tqe_q); m_freem(te->tqe_m); uma_zfree(V_tcp_reass_zone, te); - tcpb->t_segqlen--; + tcpb->t_segq->tsegq_mbufs--; V_tcp_reass_qsize--; } tcp_clean_sackreport(tcpb); diff -r e24734266067 -r 85624db56a91 sys/netinet/tcp_usrreq.c --- a/sys/netinet/tcp_usrreq.c Sun Aug 08 14:28:12 2010 +1000 +++ b/sys/netinet/tcp_usrreq.c Sun Aug 08 17:24:40 2010 +1000 @@ -1757,8 +1757,8 @@ indent += 2; db_print_indent(indent); - db_printf("t_segq first: %p t_segqlen: %d t_dupacks: %d\n", - LIST_FIRST(&tp->t_segq), tp->t_segqlen, tp->t_dupacks); + db_printf("t_segq first: %p tsegq_mbufs: %d t_dupacks: %d\n", + LIST_FIRST(tp->t_segq), tp->t_segq->tsegq_mbufs, tp->t_dupacks); db_print_indent(indent); db_printf("tt_rexmt: %p tt_persist: %p tt_keep: %p\n", diff -r e24734266067 -r 85624db56a91 sys/netinet/tcp_var.h --- a/sys/netinet/tcp_var.h Sun Aug 08 14:28:12 2010 +1000 +++ b/sys/netinet/tcp_var.h Sun Aug 08 17:24:40 2010 +1000 @@ -57,7 +57,11 @@ struct tcphdr *tqe_th; /* a pointer to tcp header */ struct mbuf *tqe_m; /* mbuf contains packet */ }; -LIST_HEAD(tsegqe_head, tseg_qent); + +struct tsegq { + int tsegq_mbufs; + struct tseg_qent *lh_first; +}; struct sackblk { tcp_seq start; /* start seq no. of sack block */ @@ -103,9 +107,7 @@ * Organized for 16 byte cacheline efficiency. */ struct tcpcb { - struct tsegqe_head t_segq; /* segment reassembly queue */ - void *t_pspare[2]; /* new reassembly queue */ - int t_segqlen; /* segment reassembly queue length */ + struct tsegq *t_segq; /* segment reassembly queue */ int t_dupacks; /* consecutive dup acks recd */ struct tcp_timer *t_timers; /* All the TCP timers in one struct */