From c7e6499a1827f4ee1521adb892f3ea33c282d5ba Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 10 May 2012 15:30:58 +0800 Subject: [PATCH] tcp: Add sack_flags for SACK related operations This saves us 4 bits in the crowded t_flags --- sys/netinet/tcp_input.c | 29 ++++++++++++++++------------- sys/netinet/tcp_sack.c | 18 ++++++++++-------- sys/netinet/tcp_timer.c | 2 +- sys/netinet/tcp_var.h | 14 ++++++++++---- 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 114702d696..873b812ef1 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -364,7 +364,8 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) /* conversion to int (in i) handles seq wraparound */ i = p->tqe_th->th_seq + p->tqe_len - th->th_seq; if (i > 0) { /* overlaps preceding segment */ - tp->t_flags |= (TF_DUPSEG | TF_ENCLOSESEG); + tp->sack_flags |= + (TSACK_F_DUPSEG | TSACK_F_ENCLOSESEG); /* enclosing block starts w/ preceding segment */ tp->encloseblk.rblk_start = p->tqe_th->th_seq; if (i >= *tlenp) { @@ -410,13 +411,14 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) if (i <= 0) break; - if (!(tp->t_flags & TF_DUPSEG)) { /* first time through */ - tp->t_flags |= (TF_DUPSEG | TF_ENCLOSESEG); + if (!(tp->sack_flags & TSACK_F_DUPSEG)) { + /* first time through */ + tp->sack_flags |= (TSACK_F_DUPSEG | TSACK_F_ENCLOSESEG); tp->encloseblk = tp->reportblk; /* report trailing duplicate D-SACK segment */ tp->reportblk.rblk_start = q->tqe_th->th_seq; } - if ((tp->t_flags & TF_ENCLOSESEG) && + if ((tp->sack_flags & TSACK_F_ENCLOSESEG) && SEQ_GT(qend_sack, tp->encloseblk.rblk_end)) { /* extend enclosing block if one exists */ tp->encloseblk.rblk_end = qend_sack; @@ -455,7 +457,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) * When not reporting a duplicate segment, use * the larger enclosing block as the SACK block. */ - if (!(tp->t_flags & TF_DUPSEG)) + if (!(tp->sack_flags & TSACK_F_DUPSEG)) tp->reportblk.rblk_end = tend_sack; LIST_REMOVE(q, tqe_q); kfree(q, M_TSEGQ); @@ -474,7 +476,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) * When not reporting a duplicate segment, use * the larger enclosing block as the SACK block. */ - if (!(tp->t_flags & TF_DUPSEG)) + if (!(tp->sack_flags & TSACK_F_DUPSEG)) tp->reportblk.rblk_start = p->tqe_th->th_seq; kfree(te, M_TSEGQ); atomic_add_int(&tcp_reass_qsize, -1); @@ -494,12 +496,12 @@ present: if (q == NULL || q->tqe_th->th_seq != tp->rcv_nxt) return (0); tp->rcv_nxt += q->tqe_len; - if (!(tp->t_flags & TF_DUPSEG)) { + if (!(tp->sack_flags & TSACK_F_DUPSEG)) { /* no SACK block to report since ACK advanced */ tp->reportblk.rblk_start = tp->reportblk.rblk_end; } /* no enclosing block to report since ACK advanced */ - tp->t_flags &= ~TF_ENCLOSESEG; + 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) || @@ -1699,7 +1701,8 @@ after_listen: th->th_seq + tlen, thflags); if (SEQ_GT(tp->reportblk.rblk_end, tp->rcv_nxt)) tp->reportblk.rblk_end = tp->rcv_nxt; - tp->t_flags |= (TF_DUPSEG | TF_SACKLEFT | TF_ACKNOW); + tp->sack_flags |= (TSACK_F_DUPSEG | TSACK_F_SACKLEFT); + tp->t_flags |= TF_ACKNOW; } if (thflags & TH_SYN) { thflags &= ~TH_SYN; @@ -2022,7 +2025,7 @@ fastretransmit: ++tcpstat.tcps_sndfastrexmit; tp->snd_cwnd = tp->snd_ssthresh; tp->rexmt_high = tp->snd_nxt; - tp->t_flags &= ~TF_SACKRESCUED; + tp->sack_flags &= ~TSACK_F_SACKRESCUED; if (SEQ_GT(old_snd_nxt, tp->snd_nxt)) tp->snd_nxt = old_snd_nxt; KASSERT(tp->snd_limited <= 2, @@ -2490,7 +2493,7 @@ dodata: /* XXX */ } sorwakeup(so); } else { - if (!(tp->t_flags & TF_DUPSEG)) { + if (!(tp->sack_flags & TSACK_F_DUPSEG)) { /* Initialize SACK report block. */ tp->reportblk.rblk_start = th->th_seq; tp->reportblk.rblk_end = TCP_SACK_BLKEND( @@ -3297,14 +3300,14 @@ tcp_sack_rexmt(struct tcpcb *tp, struct tcphdr *th) if (rescue) { tcpstat.tcps_sackrescue++; tp->rexmt_rescue = tp->snd_nxt; - tp->t_flags |= TF_SACKRESCUED; + tp->sack_flags |= TSACK_F_SACKRESCUED; break; } if (SEQ_LT(nextrexmt, old_snd_max) && SEQ_LT(tp->rexmt_high, tp->snd_nxt)) { tp->rexmt_high = seq_min(tp->snd_nxt, old_snd_max); if (tcp_aggressive_rescuesack && - (tp->t_flags & TF_SACKRESCUED) && + (tp->sack_flags & TSACK_F_SACKRESCUED) && SEQ_LT(tp->rexmt_rescue, tp->rexmt_high)) { /* Drag RescueRxt along with HighRxt */ tp->rexmt_rescue = tp->rexmt_high; diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c index 53339b315d..4b572d1a8d 100644 --- a/sys/netinet/tcp_sack.c +++ b/sys/netinet/tcp_sack.c @@ -261,7 +261,8 @@ tcp_sack_destroy(struct scoreboard *scb) void tcp_sack_report_cleanup(struct tcpcb *tp) { - tp->t_flags &= ~(TF_DUPSEG | TF_ENCLOSESEG | TF_SACKLEFT); + tp->sack_flags &= + ~(TSACK_F_DUPSEG | TSACK_F_ENCLOSESEG | TSACK_F_SACKLEFT); tp->reportblk.rblk_start = tp->reportblk.rblk_end; } @@ -343,9 +344,9 @@ tcp_sack_update_scoreboard(struct tcpcb *tp, struct tcpopt *to) tp->rexmt_high = tp->snd_una; rexmt_high_update = 1; } - if (tp->t_flags & TF_SACKRESCUED) { + if (tp->sack_flags & TSACK_F_SACKRESCUED) { if (SEQ_LT(tp->rexmt_rescue, tp->snd_una)) { - tp->t_flags &= ~TF_SACKRESCUED; + tp->sack_flags &= ~TSACK_F_SACKRESCUED; } else if (tcp_aggressive_rescuesack && rexmt_high_update && SEQ_LT(tp->rexmt_rescue, tp->rexmt_high)) { /* Drag RescueRxt along with HighRxt */ @@ -619,7 +620,7 @@ sendunsacked: /* Rescue retransmission */ if (tcp_do_rescuesack || tcp_do_rfc3517bis) { tcpstat.tcps_sackrescue_try++; - if (tp->t_flags & TF_SACKRESCUED) { + if (tp->sack_flags & TSACK_F_SACKRESCUED) { if (!tcp_aggressive_rescuesack) return FALSE; @@ -841,7 +842,7 @@ tcp_sack_fill_report(struct tcpcb *tp, u_char *opt, u_int *plen) TCPOLEN_SACK_ALIGNED + TCPOLEN_SACK_BLOCK, ("no room for SACK header and one block: optlen %d", optlen)); - if (tp->t_flags & TF_DUPSEG) + if (tp->sack_flags & TSACK_F_DUPSEG) tcpstat.tcps_snddsackopt++; else tcpstat.tcps_sndsackopt++; @@ -856,7 +857,7 @@ tcp_sack_fill_report(struct tcpcb *tp, u_char *opt, u_int *plen) optlen += TCPOLEN_SACK_BLOCK; hstart = tp->reportblk.rblk_start; hend = tp->reportblk.rblk_end; - if (tp->t_flags & TF_ENCLOSESEG) { + if (tp->sack_flags & TSACK_F_ENCLOSESEG) { KASSERT(TCP_MAXOLEN - optlen >= TCPOLEN_SACK_BLOCK, ("no room for enclosing SACK block: oplen %d", optlen)); @@ -869,7 +870,7 @@ tcp_sack_fill_report(struct tcpcb *tp, u_char *opt, u_int *plen) if (SEQ_GT(hstart, tp->rcv_nxt)) tcp_sack_update_reported_history(tp, hstart, hend); } - if (tcp_do_smartsack && (tp->t_flags & TF_SACKLEFT)) { + if (tcp_do_smartsack && (tp->sack_flags & TSACK_F_SACKLEFT)) { /* Fill in from left! Walk re-assembly queue. */ struct tseg_qent *q; @@ -898,7 +899,8 @@ tcp_sack_fill_report(struct tcpcb *tp, u_char *opt, u_int *plen) } } tp->reportblk.rblk_start = tp->reportblk.rblk_end; - tp->t_flags &= ~(TF_DUPSEG | TF_ENCLOSESEG | TF_SACKLEFT); + tp->sack_flags &= + ~(TSACK_F_DUPSEG | TSACK_F_ENCLOSESEG | TSACK_F_SACKLEFT); nblocks = (lp - olp - 1) / 2; *olp = htonl(TCPOPT_SACK_ALIGNED | (TCPOLEN_SACK + nblocks * TCPOLEN_SACK_BLOCK)); diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index d6362a149b..e6546bcab4 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -597,7 +597,7 @@ tcp_timer_rexmt_handler(struct tcpcb *tp) } tp->snd_nxt = tp->snd_una; tp->rexmt_high = tp->snd_una; - tp->t_flags &= ~TF_SACKRESCUED; + tp->sack_flags &= ~TSACK_F_SACKRESCUED; tp->snd_recover = tp->snd_max; /* * Force a segment to be sent. diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index f15ea56d1d..f7417d9142 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -168,7 +168,7 @@ struct tcpcb { #define TF_NOPUSH 0x00001000 /* don't push */ #define TF_LISTEN 0x00002000 /* listen(2) has been called */ #define TF_SIGNATURE 0x00004000 /* require MD5 digests (RFC2385) */ -#define TF_SACKRESCUED 0x00008000 /* sent rescue SACK recovery data */ +#define TF_UNUSED001 0x00008000 #define TF_MORETOCOME 0x00010000 /* More data to be appended to sock */ #define TF_REBASERTO 0x00020000 /* Recalculate RTO based on new RTT */ #define TF_LASTIDLE 0x00040000 /* connection was previously idle */ @@ -180,9 +180,9 @@ struct tcpcb { #define TF_EARLYREXMT 0x01000000 /* Did Early (Fast) Retransmit. */ #define TF_FORCE 0x02000000 /* Set if forcing out a byte */ #define TF_ONOUTPUTQ 0x04000000 /* on t_outputq list */ -#define TF_DUPSEG 0x08000000 /* last seg a duplicate */ -#define TF_ENCLOSESEG 0x10000000 /* enclosing SACK block */ -#define TF_SACKLEFT 0x20000000 /* send SACK blocks from left side */ +#define TF_UNUSED002 0x08000000 +#define TF_UNUSED003 0x10000000 +#define TF_UNUSED004 0x20000000 #define TF_KEEPALIVE 0x40000000 /* temporary keepalive */ #define TF_RXRESIZED 0x80000000 /* rcvbuf was resized */ tcp_seq snd_up; /* send urgent pointer */ @@ -258,6 +258,11 @@ struct tcpcb { u_long t_rexmtTS; /* timestamp of last retransmit */ u_char snd_limited; /* segments limited transmitted */ + u_int sack_flags; +#define TSACK_F_SACKRESCUED 0x0001 /* sent rescue SACK recovery data */ +#define TSACK_F_DUPSEG 0x0002 /* last seg a duplicate */ +#define TSACK_F_ENCLOSESEG 0x0004 /* enclosing SACK block */ +#define TSACK_F_SACKLEFT 0x0008 /* send SACK blocks from left side */ tcp_seq rexmt_high; /* highest seq # retransmitted + 1 */ tcp_seq rexmt_rescue; /* rescue SACKED sequence number */ tcp_seq snd_max_rexmt; /* snd_max when rexmting snd_una */ @@ -266,6 +271,7 @@ struct tcpcb { struct raw_sackblock encloseblk; int nsackhistory; struct raw_sackblock sackhistory[MAX_SACK_REPORT_BLOCKS]; /* reported */ + TAILQ_ENTRY(tcpcb) t_outputq; /* tcp_output needed list */ /* bandwith limitation */ -- 2.41.0