Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 Jan 2006 18:42:38 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 89731 for review
Message-ID:  <200601151842.k0FIgc4Z004693@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=89731

Change 89731 by rwatson@rwatson_zoo on 2006/01/15 18:42:19

	Refine implementation of UMA storage of ipq's.  Implement the
	resource bound in terms of a UMA zone limit, but maintain current
	sysctl semantics.

Affected files ...

.. //depot/projects/netsmp/src/sys/netinet/ip_input.c#9 edit

Differences ...

==== //depot/projects/netsmp/src/sys/netinet/ip_input.c#9 (text+ko) ====

@@ -177,16 +177,14 @@
 #define	IPQ_LOCK_INIT()	mtx_init(&ipqlock, "ipqlock", NULL, MTX_DEF)
 #define	IPQ_LOCK_ASSERT()	mtx_assert(&ipqlock, MA_OWNED)
 
-static int    nipq = 0;         /* total # of reass queues */
+static void	maxnipq_update(void);
+
+static int    maxnipq;		/* Administrative limit on # reass queues. */
+static int    nipq = 0;         /* Total # of reass queues */
 SYSCTL_INT(_net_inet_ip, OID_AUTO, fragpackets, CTLFLAG_RD,
 	&nipq, 0,
 	"Current number of IPv4 fragment reassembly queue entries");
 
-static int    maxnipq;
-SYSCTL_INT(_net_inet_ip, OID_AUTO, maxfragpackets, CTLFLAG_RW,
-	&maxnipq, 0,
-	"Maximum number of IPv4 fragment reassembly queue entries");
-
 static int    maxfragsperpacket;
 SYSCTL_INT(_net_inet_ip, OID_AUTO, maxfragsperpacket, CTLFLAG_RW,
 	&maxfragsperpacket, 0,
@@ -263,6 +261,7 @@
 	maxfragsperpacket = 16;
 	ipq_zone = uma_zcreate("ipq", sizeof(struct ipq), NULL, NULL, NULL,
 	    NULL, UMA_ALIGN_PTR, 0);
+	maxnipq_update();
 
 	/* Start ipport_tick. */
 	callout_init(&ipport_tick_callout, CALLOUT_MPSAFE);
@@ -761,6 +760,59 @@
 }
 
 /*
+ * After maxnipq has been updated, propagate the change to UMA.  The UMA zone
+ * max has slightly different semantics than the sysctl, for historical
+ * reasons.
+ */
+static void
+maxnipq_update(void)
+{
+
+	/*
+	 * -1 for unlimited allocation.
+	 */
+	if (maxnipq < 0)
+		uma_zone_set_max(ipq_zone, 0);
+	/*
+	 * Positive number for specific bound.
+	 */
+	if (maxnipq > 0)
+		uma_zone_set_max(ipq_zone, maxnipq);
+	/*
+	 * Zero specifies no further fragment queue allocation -- set the
+	 * bound very low, but rely on implementation elsewhere to actually
+	 * prevent allocation and reclaim current queues.
+	 */
+	if (maxnipq == 0)
+		uma_zone_set_max(ipq_zone, 1);
+}
+
+static int
+sysctl_maxnipq(SYSCTL_HANDLER_ARGS)
+{
+	int error, i;
+
+	i = maxnipq;
+	error = sysctl_handle_int(oidp, &i, 0, req);
+	if (error || !req->newptr)
+		return (error);
+
+	/*
+	 * XXXRW: Might be a good idea to sanity check the argument and place
+	 * an extreme upper bound.
+	 */
+	if (i < -1)
+		return (EINVAL);
+	maxnipq = i;
+	maxnipq_update();
+	return (0);
+}
+
+SYSCTL_PROC(_net_inet_ip, OID_AUTO, maxfragpackets, CTLTYPE_INT|CTLFLAG_RW,
+    NULL, 0, sysctl_maxnipq, "I",
+    "Maximum number of IPv4 fragment reassembly queue entries");
+
+/*
  * Take incoming datagram fragment and try to reassemble it into
  * whole datagram.  If the argument is the first fragment or one
  * in between the function will return NULL and store the mbuf
@@ -814,9 +866,8 @@
 	fp = NULL;
 
 	/*
-	 * Enforce upper bound on number of fragmented packets
-	 * for which we attempt reassembly;
-	 * If maxnipq is -1, accept all fragments without limitation.
+	 * Attempt to trim the number of allocated fragment queues if it
+	 * exceeds the administrative limit.
 	 */
 	if ((nipq > maxnipq) && (maxnipq > 0)) {
 		/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200601151842.k0FIgc4Z004693>