PERFORCE change 89731 for review
Robert Watson
rwatson at FreeBSD.org
Sun Jan 15 10:42:40 PST 2006
http://perforce.freebsd.org/chv.cgi?CH=89731
Change 89731 by rwatson at 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)) {
/*
More information about the p4-projects
mailing list