tcp: Use TAILQ for segments reassemble queue
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 16 May 2012 01:15:28 +0000 (09:15 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 16 May 2012 01:21:23 +0000 (09:21 +0800)
So the last segment of the reassemble queue could be peeked w/ minimal cost

sys/netinet/tcp_input.c
sys/netinet/tcp_output.c
sys/netinet/tcp_sack.c
sys/netinet/tcp_subr.c
sys/netinet/tcp_var.h

index 672b7f9..b3c3a80 100644 (file)
@@ -347,7 +347,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
        /*
         * Find a segment which begins after this one does.
         */
-       LIST_FOREACH(q, &tp->t_segq, tqe_q) {
+       TAILQ_FOREACH(q, &tp->t_segq, tqe_q) {
                if (SEQ_GT(q->tqe_th->th_seq, th->th_seq))
                        break;
                p = q;
@@ -430,8 +430,8 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
                        break;
                }
 
-               nq = LIST_NEXT(q, tqe_q);
-               LIST_REMOVE(q, tqe_q);
+               nq = TAILQ_NEXT(q, tqe_q);
+               TAILQ_REMOVE(&tp->t_segq, q, tqe_q);
                m_freem(q->tqe_m);
                kfree(q, M_TSEGQ);
                atomic_add_int(&tcp_reass_qsize, -1);
@@ -459,13 +459,13 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
                 */
                if (!(tp->sack_flags & TSACK_F_DUPSEG))
                        tp->reportblk.rblk_end = tend_sack;
-               LIST_REMOVE(q, tqe_q);
+               TAILQ_REMOVE(&tp->t_segq, q, tqe_q);
                kfree(q, M_TSEGQ);
                atomic_add_int(&tcp_reass_qsize, -1);
        }
 
        if (p == NULL) {
-               LIST_INSERT_HEAD(&tp->t_segq, te, tqe_q);
+               TAILQ_INSERT_HEAD(&tp->t_segq, te, tqe_q);
        } else {
                /* check if can coalesce with preceding segment */
                if (p->tqe_th->th_seq + p->tqe_len == th->th_seq) {
@@ -481,7 +481,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
                        kfree(te, M_TSEGQ);
                        atomic_add_int(&tcp_reass_qsize, -1);
                } else {
-                       LIST_INSERT_AFTER(p, te, tqe_q);
+                       TAILQ_INSERT_AFTER(&tp->t_segq, p, te, tqe_q);
                }
        }
 
@@ -492,7 +492,7 @@ present:
         */
        if (!TCPS_HAVEESTABLISHED(tp->t_state))
                return (0);
-       q = LIST_FIRST(&tp->t_segq);
+       q = TAILQ_FIRST(&tp->t_segq);
        if (q == NULL || q->tqe_th->th_seq != tp->rcv_nxt)
                return (0);
        tp->rcv_nxt += q->tqe_len;
@@ -503,9 +503,9 @@ present:
        /* no enclosing block to report since ACK advanced */
        tp->sack_flags &= ~TSACK_F_ENCLOSESEG;
        flags = q->tqe_th->th_flags & TH_FIN;
-       LIST_REMOVE(q, tqe_q);
-       KASSERT(LIST_EMPTY(&tp->t_segq) ||
-               LIST_FIRST(&tp->t_segq)->tqe_th->th_seq != tp->rcv_nxt,
+       TAILQ_REMOVE(&tp->t_segq, q, tqe_q);
+       KASSERT(TAILQ_EMPTY(&tp->t_segq) ||
+               TAILQ_FIRST(&tp->t_segq)->tqe_th->th_seq != tp->rcv_nxt,
                ("segment not coalesced"));
        if (so->so_state & SS_CANTRCVMORE) {
                m_freem(q->tqe_m);
@@ -1276,7 +1276,7 @@ after_listen:
                        }
                } else if (tiwin == tp->snd_wnd &&
                    th->th_ack == tp->snd_una &&
-                   LIST_EMPTY(&tp->t_segq) &&
+                   TAILQ_EMPTY(&tp->t_segq) &&
                    tlen <= ssb_space(&so->so_rcv)) {
                        u_long newsize = 0;     /* automatic sockbuf scaling */
                        /*
@@ -2474,7 +2474,7 @@ dodata:                                                   /* XXX */
                 * fast retransmit can work).
                 */
                if (th->th_seq == tp->rcv_nxt &&
-                   LIST_EMPTY(&tp->t_segq) &&
+                   TAILQ_EMPTY(&tp->t_segq) &&
                    TCPS_HAVEESTABLISHED(tp->t_state)) {
                        if (DELAY_ACK(tp)) {
                                tcp_callout_reset(tp, tp->tt_delack,
index c529e27..58296c5 100644 (file)
@@ -627,7 +627,7 @@ send:
         */
        if ((tp->t_flags & (TF_SACK_PERMITTED | TF_NOOPT)) ==
                TF_SACK_PERMITTED &&
-           (!LIST_EMPTY(&tp->t_segq) ||
+           (!TAILQ_EMPTY(&tp->t_segq) ||
             tp->reportblk.rblk_start != tp->reportblk.rblk_end))
                tcp_sack_fill_report(tp, opt, &optlen);
 
index 4b572d1..7abda17 100644 (file)
@@ -874,7 +874,7 @@ tcp_sack_fill_report(struct tcpcb *tp, u_char *opt, u_int *plen)
                /* Fill in from left!  Walk re-assembly queue. */
                struct tseg_qent *q;
 
-               q = LIST_FIRST(&tp->t_segq);
+               q = TAILQ_FIRST(&tp->t_segq);
                while (q != NULL &&
                    TCP_MAXOLEN - optlen >= TCPOLEN_SACK_BLOCK) {
                        *lp++ = htonl(q->tqe_th->th_seq);
@@ -882,7 +882,7 @@ tcp_sack_fill_report(struct tcpcb *tp, u_char *opt, u_int *plen)
                            q->tqe_th->th_seq + q->tqe_len,
                            q->tqe_th->th_flags));
                        optlen += TCPOLEN_SACK_BLOCK;
-                       q = LIST_NEXT(q, tqe_q);
+                       q = TAILQ_NEXT(q, tqe_q);
                }
        } else {
                int n = 0;
index f484f59..d4fbce6 100644 (file)
@@ -695,7 +695,7 @@ tcp_newtcpcb(struct inpcb *inp)
        it = (struct inp_tp *)inp;
        tp = &it->tcb;
        bzero(tp, sizeof(struct tcpcb));
-       LIST_INIT(&tp->t_segq);
+       TAILQ_INIT(&tp->t_segq);
        tp->t_maxseg = tp->t_maxopd = isipv6 ? tcp_v6mssdflt : tcp_mssdflt;
        tp->t_rxtthresh = tcprexmtthresh;
 
@@ -976,8 +976,8 @@ tcp_close(struct tcpcb *tp)
 
 no_valid_rt:
        /* free the reassembly queue, if any */
-       while((q = LIST_FIRST(&tp->t_segq)) != NULL) {
-               LIST_REMOVE(q, tqe_q);
+       while((q = TAILQ_FIRST(&tp->t_segq)) != NULL) {
+               TAILQ_REMOVE(&tp->t_segq, q, tqe_q);
                m_freem(q->tqe_m);
                kfree(q, M_TSEGQ);
                atomic_add_int(&tcp_reass_qsize, -1);
@@ -1028,8 +1028,8 @@ tcp_drain_oncpu(struct inpcbhead *head)
        while ((inpb = LIST_NEXT(marker, inp_list)) != NULL) {
                if ((inpb->inp_flags & INP_PLACEMARKER) == 0 &&
                    (tcpb = intotcpcb(inpb)) != NULL &&
-                   (te = LIST_FIRST(&tcpb->t_segq)) != NULL) {
-                       LIST_REMOVE(te, tqe_q);
+                   (te = TAILQ_FIRST(&tcpb->t_segq)) != NULL) {
+                       TAILQ_REMOVE(&tcpb->t_segq, te, tqe_q);
                        m_freem(te->tqe_m);
                        kfree(te, M_TSEGQ);
                        atomic_add_int(&tcp_reass_qsize, -1);
index b0bffe5..72f1e9a 100644 (file)
@@ -94,12 +94,12 @@ extern int tcp_eifel_rtoinc;
 
 /* TCP segment queue entry */
 struct tseg_qent {
-       LIST_ENTRY(tseg_qent) tqe_q;
+       TAILQ_ENTRY(tseg_qent) tqe_q;
        int     tqe_len;                /* TCP segment data length */
        struct  tcphdr *tqe_th;         /* a pointer to tcp header */
        struct  mbuf    *tqe_m;         /* mbuf contains packet */
 };
-LIST_HEAD(tsegqe_head, tseg_qent);
+TAILQ_HEAD(tsegqe_head, tseg_qent);
 extern int     tcp_reass_maxseg;
 extern int     tcp_reass_qsize;
 #ifdef MALLOC_DECLARE