The branch main has been updated by rscheff:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=c7c325d01de4a1509e0a978f28275279de692130

commit c7c325d01de4a1509e0a978f28275279de692130
Author:     Richard Scheffenegger <[email protected]>
AuthorDate: 2024-01-24 15:42:29 +0000
Commit:     Richard Scheffenegger <[email protected]>
CommitDate: 2024-01-24 15:43:29 +0000

    tcp: pass maxseg around instead of calculating locally
    
    Improve slowpath processing (reordering, retransmissions)
    slightly by calculating maxseg only once. This typically
    saves one of two calls to tcp_maxseg().
    
    Reviewed By:           glebius, tuexen, cc, #transport
    Sponsored by:          NetApp, Inc.
    Differential Revision: https://reviews.freebsd.org/D43536
---
 sys/netinet/tcp_input.c | 37 +++++++++++++++++++++++++------------
 sys/netinet/tcp_sack.c  |  9 +++++++--
 sys/netinet/tcp_var.h   |  8 +++++---
 3 files changed, 37 insertions(+), 17 deletions(-)

diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index ed5f28490852..02b042fd3273 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1529,7 +1529,7 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct 
tcphdr *th,
        struct mbuf *mfree;
        struct tcpopt to;
        int tfo_syn;
-       u_int maxseg;
+       u_int maxseg = 0;
 
        thflags = tcp_get_flags(th);
        tp->sackhint.last_sack_ack = 0;
@@ -2596,7 +2596,8 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct 
tcphdr *th,
                                        if (V_tcp_do_prr &&
                                            IN_FASTRECOVERY(tp->t_flags) &&
                                            (tp->t_flags & TF_SACK_PERMIT)) {
-                                               tcp_do_prr_ack(tp, th, &to, 
sack_changed);
+                                               tcp_do_prr_ack(tp, th, &to,
+                                                   sack_changed, &maxseg);
                                        } else if (tcp_is_sack_recovery(tp, 
&to) &&
                                            IN_FASTRECOVERY(tp->t_flags)) {
                                                int awnd;
@@ -2801,19 +2802,24 @@ resume_partialack:
                 */
                if (IN_FASTRECOVERY(tp->t_flags)) {
                        if (SEQ_LT(th->th_ack, tp->snd_recover)) {
-                               if (tp->t_flags & TF_SACK_PERMIT)
+                               if (tp->t_flags & TF_SACK_PERMIT) {
                                        if (V_tcp_do_prr && to.to_flags & 
TOF_SACK) {
                                                tcp_timer_activate(tp, 
TT_REXMT, 0);
                                                tp->t_rtttime = 0;
-                                               tcp_do_prr_ack(tp, th, &to, 
sack_changed);
+                                               tcp_do_prr_ack(tp, th, &to,
+                                                   sack_changed, &maxseg);
                                                tp->t_flags |= TF_ACKNOW;
                                                (void) tcp_output(tp);
-                                       } else
-                                               tcp_sack_partialack(tp, th);
-                               else
+                                       } else {
+                                               tcp_sack_partialack(tp, th,
+                                                   &maxseg);
+                                       }
+                               } else {
                                        tcp_newreno_partial_ack(tp, th);
-                       } else
+                               }
+                       } else {
                                cc_post_recovery(tp, th);
+                       }
                } else if (IN_CONGRECOVERY(tp->t_flags)) {
                        if (SEQ_LT(th->th_ack, tp->snd_recover)) {
                                if (V_tcp_do_prr) {
@@ -2823,11 +2829,13 @@ resume_partialack:
                                         * During ECN cwnd reduction
                                         * always use PRR-SSRB
                                         */
-                                       tcp_do_prr_ack(tp, th, &to, 
SACK_CHANGE);
+                                       tcp_do_prr_ack(tp, th, &to, SACK_CHANGE,
+                                           &maxseg);
                                        (void) tcp_output(tp);
                                }
-                       } else
+                       } else {
                                cc_post_recovery(tp, th);
+                       }
                }
                /*
                 * If we reach this point, ACK is not a duplicate,
@@ -3946,13 +3954,18 @@ tcp_mssopt(struct in_conninfo *inc)
 }
 
 void
-tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to, 
sackstatus_t sack_changed)
+tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to,
+    sackstatus_t sack_changed, u_int *maxsegp)
 {
        int snd_cnt = 0, limit = 0, del_data = 0, pipe = 0;
-       int maxseg = tcp_maxseg(tp);
+       u_int maxseg;
 
        INP_WLOCK_ASSERT(tptoinpcb(tp));
 
+       if (*maxsegp == 0) {
+               *maxsegp = tcp_maxseg(tp);
+       }
+       maxseg = *maxsegp;
        /*
         * Compute the amount of data that this ACK is indicating
         * (del_data) and an estimate of how many bytes are in the
diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c
index f9ca83850c09..f517bb9fcdb7 100644
--- a/sys/netinet/tcp_sack.c
+++ b/sys/netinet/tcp_sack.c
@@ -936,13 +936,18 @@ tcp_resend_sackholes(struct tcpcb *tp)
  * the midst of sack recovery.
  */
 void
-tcp_sack_partialack(struct tcpcb *tp, struct tcphdr *th)
+tcp_sack_partialack(struct tcpcb *tp, struct tcphdr *th, u_int *maxsegp)
 {
        struct sackhole *temp;
        int num_segs = 1;
-       u_int maxseg = tcp_maxseg(tp);
+       u_int maxseg;
 
        INP_WLOCK_ASSERT(tptoinpcb(tp));
+
+       if (*maxsegp == 0) {
+               *maxsegp = tcp_maxseg(tp);
+       }
+       maxseg = *maxsegp;
        tcp_timer_activate(tp, TT_REXMT, 0);
        tp->t_rtttime = 0;
        /* Send one or 2 segments based on how much new data was acked. */
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index f9b3d1a5c3ee..cbe8de7988c7 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1481,14 +1481,16 @@ sackstatus_t
         tcp_sack_doack(struct tcpcb *, struct tcpopt *, tcp_seq);
 int     tcp_dsack_block_exists(struct tcpcb *);
 void    tcp_update_dsack_list(struct tcpcb *, tcp_seq, tcp_seq);
-void    tcp_update_sack_list(struct tcpcb *tp, tcp_seq rcv_laststart, tcp_seq 
rcv_lastend);
+void    tcp_update_sack_list(struct tcpcb *tp, tcp_seq rcv_laststart,
+           tcp_seq rcv_lastend);
 void    tcp_clean_dsack_blocks(struct tcpcb *tp);
 void    tcp_clean_sackreport(struct tcpcb *tp);
 void    tcp_sack_adjust(struct tcpcb *tp);
 struct sackhole *tcp_sack_output(struct tcpcb *tp, int *sack_bytes_rexmt);
-void    tcp_do_prr_ack(struct tcpcb *, struct tcphdr *, struct tcpopt *, 
sackstatus_t);
+void    tcp_do_prr_ack(struct tcpcb *, struct tcphdr *, struct tcpopt *,
+           sackstatus_t, u_int *);
 void    tcp_lost_retransmission(struct tcpcb *, struct tcphdr *);
-void    tcp_sack_partialack(struct tcpcb *, struct tcphdr *);
+void    tcp_sack_partialack(struct tcpcb *, struct tcphdr *, u_int *);
 void    tcp_resend_sackholes(struct tcpcb *tp);
 void    tcp_free_sackholes(struct tcpcb *tp);
 void    tcp_sack_lost_retransmission(struct tcpcb *, struct tcphdr *);

Reply via email to