Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet Added sysctl tunable limits for the number of ma...



details:   https://anonhg.NetBSD.org/src/rev/a47ea329a448
branches:  trunk
changeset: 580019:a47ea329a448
user:      kurahone <kurahone%NetBSD.org@localhost>
date:      Tue Apr 05 01:07:17 2005 +0000

description:
Added sysctl tunable limits for the number of maximum SACK holes
per connection and per system.

Idea taken from FreeBSD.

diffstat:

 sys/netinet/tcp_sack.c   |  42 +++++++++++++++++++++++++++++++++++++-----
 sys/netinet/tcp_seq.h    |   4 +++-
 sys/netinet/tcp_subr.c   |   9 +++++++--
 sys/netinet/tcp_usrreq.c |  41 ++++++++++++++++++++++++++++++++++-------
 sys/netinet/tcp_var.h    |   6 +++++-
 5 files changed, 86 insertions(+), 16 deletions(-)

diffs (294 lines):

diff -r 30db4f6ec85e -r a47ea329a448 sys/netinet/tcp_sack.c
--- a/sys/netinet/tcp_sack.c    Tue Apr 05 00:21:22 2005 +0000
+++ b/sys/netinet/tcp_sack.c    Tue Apr 05 01:07:17 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tcp_sack.c,v 1.11 2005/03/18 21:25:09 kurahone Exp $ */
+/* $NetBSD: tcp_sack.c,v 1.12 2005/04/05 01:07:17 kurahone Exp $ */
 
 /*
  * Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -109,7 +109,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_sack.c,v 1.11 2005/03/18 21:25:09 kurahone Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_sack.c,v 1.12 2005/04/05 01:07:17 kurahone Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -168,9 +168,6 @@
 
 #include <machine/stdarg.h>
 
-#define SEQ_MIN(a, b)  ((SEQ_LT(a, b)) ? (a) : (b))
-#define SEQ_MAX(a, b)  ((SEQ_GT(a, b)) ? (a) : (b))
-
 /* SACK block pool. */
 POOL_INIT(sackhole_pool, sizeof(struct sackhole), 0, 0, 0, "sackholepl", NULL);
 
@@ -206,6 +203,13 @@
                return;
        }
 
+       /*
+        * If we don't want any SACK holes to be allocated, just return.
+        */
+       if (tcp_sack_globalmaxholes == 0 || tcp_sack_tp_maxholes == 0) {
+               return;
+       }
+
        /* If the ACK is outside [snd_una, snd_max], ignore the SACK options. */
        if (SEQ_LT(th->th_ack, tp->snd_una) || SEQ_GT(th->th_ack, tp->snd_max))
                return;
@@ -255,6 +259,9 @@
 
                if (TAILQ_EMPTY(&tp->snd_holes)) {
                        /* First hole. */
+                       if (tcp_sack_globalholes >= tcp_sack_globalmaxholes) {
+                               return;
+                       }
                        cur = (struct sackhole *)
                            pool_get(&sackhole_pool, PR_NOWAIT);
                        if (cur == NULL) {
@@ -265,6 +272,8 @@
                        cur->end = sack->left;
                        cur->rxmit = cur->start;
                        tp->rcv_lastsack = sack->right;
+                       tp->snd_numholes++;
+                       tcp_sack_globalholes++;
                        TAILQ_INSERT_HEAD(&tp->snd_holes, cur, sackhole_q);
                        continue; /* With next sack block */
                }
@@ -287,6 +296,8 @@
                                        /* Acks entire hole, so delete hole */
                                        tmp = cur;
                                        cur = TAILQ_NEXT(cur, sackhole_q);
+                                       tp->snd_numholes--;
+                                       tcp_sack_globalholes--;
                                        TAILQ_REMOVE(&tp->snd_holes, tmp,
                                            sackhole_q);
                                        pool_put(&sackhole_pool, tmp);
@@ -313,6 +324,12 @@
                                 * ACKs some data in middle of a hole; need to
                                 * split current hole
                                 */
+                               if (tcp_sack_globalholes >=
+                                               tcp_sack_globalmaxholes ||
+                                               tp->snd_numholes >=
+                                               tcp_sack_tp_maxholes) {
+                                       return;
+                               }
                                tmp = (struct sackhole *)
                                    pool_get(&sackhole_pool, PR_NOWAIT);
                                if (tmp == NULL) {
@@ -324,6 +341,8 @@
                                tmp->rxmit = SEQ_MAX(cur->rxmit, tmp->start);
                                cur->end = sack->left;
                                cur->rxmit = SEQ_MIN(cur->rxmit, cur->end);
+                               tp->snd_numholes++;
+                               tcp_sack_globalholes++;
                                TAILQ_INSERT_AFTER(&tp->snd_holes, cur, tmp,
                                                sackhole_q);
                                cur = tmp;
@@ -336,6 +355,12 @@
                        /*
                         * Need to append new hole at end.
                         */
+                       if (tcp_sack_globalholes >=
+                                       tcp_sack_globalmaxholes ||
+                                       tp->snd_numholes >=
+                                       tcp_sack_tp_maxholes) {
+                               return;
+                       }
                        tmp = (struct sackhole *)
                            pool_get(&sackhole_pool, PR_NOWAIT);
                        if (tmp == NULL)
@@ -343,6 +368,8 @@
                        tmp->start = tp->rcv_lastsack;
                        tmp->end = sack->left;
                        tmp->rxmit = tmp->start;
+                       tp->snd_numholes++;
+                       tcp_sack_globalholes++;
                        TAILQ_INSERT_TAIL(&tp->snd_holes, tmp, sackhole_q);
                        cur = tmp;
                }
@@ -365,6 +392,8 @@
                if (SEQ_LEQ(cur->end, lastack)) {
                        tmp = cur;
                        cur = TAILQ_NEXT(cur, sackhole_q);
+                       tp->snd_numholes--;
+                       tcp_sack_globalholes--;
                        TAILQ_REMOVE(&tp->snd_holes, tmp, sackhole_q);
                        pool_put(&sackhole_pool, tmp);
                } else if (SEQ_LT(cur->start, lastack)) {
@@ -386,9 +415,12 @@
        /* Free up the SACK hole list. */
        while (!TAILQ_EMPTY(&tp->snd_holes)) {
                sack = TAILQ_FIRST(&tp->snd_holes);
+               tcp_sack_globalholes--;
                TAILQ_REMOVE(&tp->snd_holes, sack, sackhole_q);
                pool_put(&sackhole_pool, sack);
        }
+
+       tp->snd_numholes = 0;
 }
 
 /*
diff -r 30db4f6ec85e -r a47ea329a448 sys/netinet/tcp_seq.h
--- a/sys/netinet/tcp_seq.h     Tue Apr 05 00:21:22 2005 +0000
+++ b/sys/netinet/tcp_seq.h     Tue Apr 05 01:07:17 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tcp_seq.h,v 1.14 2005/02/16 15:00:47 briggs Exp $      */
+/*     $NetBSD: tcp_seq.h,v 1.15 2005/04/05 01:07:17 kurahone Exp $    */
 
 /*
  * Copyright (c) 1982, 1986, 1993, 1995
@@ -43,6 +43,8 @@
 #define        SEQ_LEQ(a,b)    ((int)((a)-(b)) <= 0)
 #define        SEQ_GT(a,b)     ((int)((a)-(b)) > 0)
 #define        SEQ_GEQ(a,b)    ((int)((a)-(b)) >= 0)
+#define SEQ_MIN(a, b)  ((SEQ_LT(a, b)) ? (a) : (b))
+#define SEQ_MAX(a, b)  ((SEQ_GT(a, b)) ? (a) : (b))
 
 #define        SEQ_SUB(a,b)    ((long)((a)-(b)))
 
diff -r 30db4f6ec85e -r a47ea329a448 sys/netinet/tcp_subr.c
--- a/sys/netinet/tcp_subr.c    Tue Apr 05 00:21:22 2005 +0000
+++ b/sys/netinet/tcp_subr.c    Tue Apr 05 01:07:17 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tcp_subr.c,v 1.188 2005/03/29 20:10:16 yamt Exp $      */
+/*     $NetBSD: tcp_subr.c,v 1.189 2005/04/05 01:07:17 kurahone Exp $  */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -98,7 +98,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.188 2005/03/29 20:10:16 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.189 2005/04/05 01:07:17 kurahone Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -201,6 +201,10 @@
 int    tcp_rst_ppslim = 100;   /* 100pps */
 int    tcp_ackdrop_ppslim = 100;       /* 100pps */
 int    tcp_do_loopback_cksum = 0;
+int    tcp_sack_tp_maxholes = 32;
+int    tcp_sack_globalmaxholes = 1024;
+int    tcp_sack_globalholes = 0;
+
 
 /* tcb hash */
 #ifndef TCBHASHSIZE
@@ -907,6 +911,7 @@
 
        .snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT,
        .snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT,
+       .snd_numholes = 0,
 
        .t_partialacks = -1,
 };
diff -r 30db4f6ec85e -r a47ea329a448 sys/netinet/tcp_usrreq.c
--- a/sys/netinet/tcp_usrreq.c  Tue Apr 05 00:21:22 2005 +0000
+++ b/sys/netinet/tcp_usrreq.c  Tue Apr 05 01:07:17 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tcp_usrreq.c,v 1.101 2005/03/30 11:09:58 yamt Exp $    */
+/*     $NetBSD: tcp_usrreq.c,v 1.102 2005/04/05 01:07:17 kurahone Exp $        */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -100,7 +100,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.101 2005/03/30 11:09:58 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.102 2005/04/05 01:07:17 kurahone Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -1364,6 +1364,7 @@
 sysctl_net_inet_tcp_setup2(struct sysctllog **clog, int pf, const char *pfname,
                           const char *tcpname)
 {
+       struct sysctlnode *sack_node;
 
        sysctl_createv(clog, 0, NULL, NULL,
                       CTLFLAG_PERMANENT,
@@ -1444,11 +1445,11 @@
                       SYSCTL_DESCR("Use interface MTU for calculating MSS"),
                       NULL, 0, &tcp_mss_ifmtu, 0,
                       CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSS_IFMTU, CTL_EOL);
-       sysctl_createv(clog, 0, NULL, NULL,
-                      CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
-                      CTLTYPE_INT, "sack",
-                      SYSCTL_DESCR("Enable RFC2018 Selective ACKnowledgement"),
-                      NULL, 0, &tcp_do_sack, 0,
+       sysctl_createv(clog, 0, NULL, &sack_node,
+                      CTLFLAG_PERMANENT,
+                      CTLTYPE_NODE, "sack",
+                      SYSCTL_DESCR("RFC2018 Selective ACKnowledgement tunables"),
+                      NULL, 0, NULL, 0,
                       CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_EOL);
        sysctl_createv(clog, 0, NULL, NULL,
                       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
@@ -1574,6 +1575,32 @@
                       sysctl_inpcblist, 0, &tcbtable, 0,
                       CTL_NET, pf, IPPROTO_TCP, CTL_CREATE,
                       CTL_EOL);
+
+       /* SACK gets it's own little subtree. */
+       sysctl_createv(clog, 0, NULL, &sack_node,
+                      CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+                      CTLTYPE_INT, "enable",
+                      SYSCTL_DESCR("Enable RFC2018 Selective ACKnowledgement"),
+                      NULL, 0, &tcp_do_sack, 0,
+                      CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL);
+       sysctl_createv(clog, 0, NULL, &sack_node,
+                      CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+                      CTLTYPE_INT, "maxholes",
+                      SYSCTL_DESCR("Maximum number of TCP SACK holes allowed per connection"),
+                      NULL, 0, &tcp_sack_tp_maxholes, 0,
+                      CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL);
+       sysctl_createv(clog, 0, NULL, &sack_node,
+                      CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+                      CTLTYPE_INT, "globalmaxholes",
+                      SYSCTL_DESCR("Global maximum number of TCP SACK holes"),
+                      NULL, 0, &tcp_sack_globalmaxholes, 0,
+                      CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL);
+       sysctl_createv(clog, 0, NULL, &sack_node,
+                      CTLFLAG_PERMANENT,
+                      CTLTYPE_INT, "globalholes",
+                      SYSCTL_DESCR("Global number of TCP SACK holes"),
+                      NULL, 0, &tcp_sack_globalholes, 0,
+                      CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL);
 }
 
 /*
diff -r 30db4f6ec85e -r a47ea329a448 sys/netinet/tcp_var.h
--- a/sys/netinet/tcp_var.h     Tue Apr 05 00:21:22 2005 +0000
+++ b/sys/netinet/tcp_var.h     Tue Apr 05 01:07:17 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tcp_var.h,v 1.124 2005/03/29 20:10:16 yamt Exp $       */
+/*     $NetBSD: tcp_var.h,v 1.125 2005/04/05 01:07:17 kurahone Exp $   */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -294,6 +294,7 @@
        struct sackblk rcv_dsack_block; /* RX D-SACK block. */
        struct ipqehead timeq;          /* time sequenced queue. */
        struct sackhead snd_holes;      /* TX SACK holes. */
+       int     snd_numholes;           /* Number of TX SACK holes. */
        tcp_seq rcv_lastsack;           /* last seq number(+1) sack'd by rcv'r*/
        tcp_seq sack_newdata;           /* New data xmitted in this recovery
                                           episode starts at this seq number*/
@@ -719,6 +720,9 @@
 extern int tcp_syn_bucket_limit;/* max entries per hash bucket */
 extern int tcp_log_refused;    /* log refused connections */
 extern int tcp_do_loopback_cksum;/* do TCP checksum on loopback? */
+extern int tcp_sack_tp_maxholes;       /* Max holes per connection. */
+extern int tcp_sack_globalmaxholes;    /* Max holes per system. */
+extern int tcp_sack_globalholes;       /* Number of holes present. */
 
 extern int tcp_rst_ppslim;
 extern int tcp_ackdrop_ppslim;



Home | Main Index | Thread Index | Old Index