summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_mbuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_mbuf.c')
-rw-r--r--sys/kern/kern_mbuf.c94
1 files changed, 69 insertions, 25 deletions
diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c
index f8fd0d7..fe91e3e 100644
--- a/sys/kern/kern_mbuf.c
+++ b/sys/kern/kern_mbuf.c
@@ -96,6 +96,7 @@ __FBSDID("$FreeBSD$");
*
*/
+int nmbufs; /* limits number of mbufs */
int nmbclusters; /* limits number of mbuf clusters */
int nmbjumbop; /* limits number of page size jumbo clusters */
int nmbjumbo9; /* limits number of 9k jumbo clusters */
@@ -106,36 +107,38 @@ struct mbstat mbstat;
* tunable_mbinit() has to be run before init_maxsockets() thus
* the SYSINIT order below is SI_ORDER_MIDDLE while init_maxsockets()
* runs at SI_ORDER_ANY.
+ *
+ * NB: This has to be done before VM init.
*/
static void
tunable_mbinit(void *dummy)
{
- /* This has to be done before VM init. */
TUNABLE_INT_FETCH("kern.ipc.nmbclusters", &nmbclusters);
- if (nmbclusters == 0) {
-#ifdef VM_AUTOTUNE_NMBCLUSTERS
- nmbclusters = VM_AUTOTUNE_NMBCLUSTERS;
-#else
- nmbclusters = 1024 + maxusers * 64;
-#endif
-#ifdef VM_MAX_AUTOTUNE_NMBCLUSTERS
- if (nmbclusters > VM_MAX_AUTOTUNE_NMBCLUSTERS)
- nmbclusters = VM_MAX_AUTOTUNE_NMBCLUSTERS;
-#endif
- }
+ if (nmbclusters == 0)
+ nmbclusters = maxmbufmem / MCLBYTES / 4;
TUNABLE_INT_FETCH("kern.ipc.nmbjumbop", &nmbjumbop);
if (nmbjumbop == 0)
- nmbjumbop = nmbclusters / 2;
+ nmbjumbop = maxmbufmem / MJUMPAGESIZE / 4;
TUNABLE_INT_FETCH("kern.ipc.nmbjumbo9", &nmbjumbo9);
if (nmbjumbo9 == 0)
- nmbjumbo9 = nmbclusters / 4;
+ nmbjumbo9 = maxmbufmem / MJUM9BYTES / 6;
TUNABLE_INT_FETCH("kern.ipc.nmbjumbo16", &nmbjumbo16);
if (nmbjumbo16 == 0)
- nmbjumbo16 = nmbclusters / 8;
+ nmbjumbo16 = maxmbufmem / MJUM16BYTES / 6;
+
+ /*
+ * We need at least as many mbufs as we have clusters of
+ * the various types added together.
+ */
+ TUNABLE_INT_FETCH("kern.ipc.nmbufs", &nmbufs);
+ if (nmbufs < nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16)
+ nmbufs = lmax(maxmbufmem / MSIZE / 5,
+ nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16);
+
}
SYSINIT(tunable_mbinit, SI_SUB_TUNABLES, SI_ORDER_MIDDLE, tunable_mbinit, NULL);
@@ -147,9 +150,11 @@ sysctl_nmbclusters(SYSCTL_HANDLER_ARGS)
newnmbclusters = nmbclusters;
error = sysctl_handle_int(oidp, &newnmbclusters, 0, req);
if (error == 0 && req->newptr) {
- if (newnmbclusters > nmbclusters) {
+ if (newnmbclusters > nmbclusters &&
+ nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) {
nmbclusters = newnmbclusters;
uma_zone_set_max(zone_clust, nmbclusters);
+ nmbclusters = uma_zone_get_max(zone_clust);
EVENTHANDLER_INVOKE(nmbclusters_change);
} else
error = EINVAL;
@@ -168,9 +173,11 @@ sysctl_nmbjumbop(SYSCTL_HANDLER_ARGS)
newnmbjumbop = nmbjumbop;
error = sysctl_handle_int(oidp, &newnmbjumbop, 0, req);
if (error == 0 && req->newptr) {
- if (newnmbjumbop> nmbjumbop) {
+ if (newnmbjumbop > nmbjumbop &&
+ nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) {
nmbjumbop = newnmbjumbop;
uma_zone_set_max(zone_jumbop, nmbjumbop);
+ nmbjumbop = uma_zone_get_max(zone_jumbop);
} else
error = EINVAL;
}
@@ -189,9 +196,11 @@ sysctl_nmbjumbo9(SYSCTL_HANDLER_ARGS)
newnmbjumbo9 = nmbjumbo9;
error = sysctl_handle_int(oidp, &newnmbjumbo9, 0, req);
if (error == 0 && req->newptr) {
- if (newnmbjumbo9> nmbjumbo9) {
+ if (newnmbjumbo9 > nmbjumbo9&&
+ nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) {
nmbjumbo9 = newnmbjumbo9;
uma_zone_set_max(zone_jumbo9, nmbjumbo9);
+ nmbjumbo9 = uma_zone_get_max(zone_jumbo9);
} else
error = EINVAL;
}
@@ -209,9 +218,11 @@ sysctl_nmbjumbo16(SYSCTL_HANDLER_ARGS)
newnmbjumbo16 = nmbjumbo16;
error = sysctl_handle_int(oidp, &newnmbjumbo16, 0, req);
if (error == 0 && req->newptr) {
- if (newnmbjumbo16> nmbjumbo16) {
+ if (newnmbjumbo16 > nmbjumbo16 &&
+ nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) {
nmbjumbo16 = newnmbjumbo16;
uma_zone_set_max(zone_jumbo16, nmbjumbo16);
+ nmbjumbo16 = uma_zone_get_max(zone_jumbo16);
} else
error = EINVAL;
}
@@ -221,6 +232,27 @@ SYSCTL_PROC(_kern_ipc, OID_AUTO, nmbjumbo16, CTLTYPE_INT|CTLFLAG_RW,
&nmbjumbo16, 0, sysctl_nmbjumbo16, "IU",
"Maximum number of mbuf 16k jumbo clusters allowed");
+static int
+sysctl_nmbufs(SYSCTL_HANDLER_ARGS)
+{
+ int error, newnmbufs;
+
+ newnmbufs = nmbufs;
+ error = sysctl_handle_int(oidp, &newnmbufs, 0, req);
+ if (error == 0 && req->newptr) {
+ if (newnmbufs > nmbufs) {
+ nmbufs = newnmbufs;
+ uma_zone_set_max(zone_mbuf, nmbufs);
+ nmbufs = uma_zone_get_max(zone_mbuf);
+ EVENTHANDLER_INVOKE(nmbufs_change);
+ } else
+ error = EINVAL;
+ }
+ return (error);
+}
+SYSCTL_PROC(_kern_ipc, OID_AUTO, nmbuf, CTLTYPE_INT|CTLFLAG_RW,
+&nmbufs, 0, sysctl_nmbufs, "IU",
+ "Maximum number of mbufs allowed");
SYSCTL_STRUCT(_kern_ipc, OID_AUTO, mbstat, CTLFLAG_RD, &mbstat, mbstat,
@@ -275,6 +307,10 @@ mbuf_init(void *dummy)
NULL, NULL,
#endif
MSIZE - 1, UMA_ZONE_MAXBUCKET);
+ if (nmbufs > 0) {
+ uma_zone_set_max(zone_mbuf, nmbufs);
+ nmbufs = uma_zone_get_max(zone_mbuf);
+ }
zone_clust = uma_zcreate(MBUF_CLUSTER_MEM_NAME, MCLBYTES,
mb_ctor_clust, mb_dtor_clust,
@@ -284,8 +320,10 @@ mbuf_init(void *dummy)
NULL, NULL,
#endif
UMA_ALIGN_PTR, UMA_ZONE_REFCNT);
- if (nmbclusters > 0)
+ if (nmbclusters > 0) {
uma_zone_set_max(zone_clust, nmbclusters);
+ nmbclusters = uma_zone_get_max(zone_clust);
+ }
zone_pack = uma_zsecond_create(MBUF_PACKET_MEM_NAME, mb_ctor_pack,
mb_dtor_pack, mb_zinit_pack, mb_zfini_pack, zone_mbuf);
@@ -299,8 +337,10 @@ mbuf_init(void *dummy)
NULL, NULL,
#endif
UMA_ALIGN_PTR, UMA_ZONE_REFCNT);
- if (nmbjumbop > 0)
+ if (nmbjumbop > 0) {
uma_zone_set_max(zone_jumbop, nmbjumbop);
+ nmbjumbop = uma_zone_get_max(zone_jumbop);
+ }
zone_jumbo9 = uma_zcreate(MBUF_JUMBO9_MEM_NAME, MJUM9BYTES,
mb_ctor_clust, mb_dtor_clust,
@@ -310,9 +350,11 @@ mbuf_init(void *dummy)
NULL, NULL,
#endif
UMA_ALIGN_PTR, UMA_ZONE_REFCNT);
- if (nmbjumbo9 > 0)
- uma_zone_set_max(zone_jumbo9, nmbjumbo9);
uma_zone_set_allocf(zone_jumbo9, mbuf_jumbo_alloc);
+ if (nmbjumbo9 > 0) {
+ uma_zone_set_max(zone_jumbo9, nmbjumbo9);
+ nmbjumbo9 = uma_zone_get_max(zone_jumbo9);
+ }
zone_jumbo16 = uma_zcreate(MBUF_JUMBO16_MEM_NAME, MJUM16BYTES,
mb_ctor_clust, mb_dtor_clust,
@@ -322,9 +364,11 @@ mbuf_init(void *dummy)
NULL, NULL,
#endif
UMA_ALIGN_PTR, UMA_ZONE_REFCNT);
- if (nmbjumbo16 > 0)
- uma_zone_set_max(zone_jumbo16, nmbjumbo16);
uma_zone_set_allocf(zone_jumbo16, mbuf_jumbo_alloc);
+ if (nmbjumbo16 > 0) {
+ uma_zone_set_max(zone_jumbo16, nmbjumbo16);
+ nmbjumbo16 = uma_zone_get_max(zone_jumbo16);
+ }
zone_ext_refcnt = uma_zcreate(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int),
NULL, NULL,
OpenPOWER on IntegriCloud