diff options
Diffstat (limited to 'freebsd/sys/kern/kern_mbuf.c')
-rw-r--r-- | freebsd/sys/kern/kern_mbuf.c | 137 |
1 files changed, 97 insertions, 40 deletions
diff --git a/freebsd/sys/kern/kern_mbuf.c b/freebsd/sys/kern/kern_mbuf.c index 98cfb1f0..74e7aa10 100644 --- a/freebsd/sys/kern/kern_mbuf.c +++ b/freebsd/sys/kern/kern_mbuf.c @@ -2,7 +2,7 @@ /*- * Copyright (c) 2004, 2005, - * Bosko Milekic <bmilekic@FreeBSD.org>. All rights reserved. + * Bosko Milekic <bmilekic@FreeBSD.org>. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -49,9 +49,13 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_extern.h> #include <vm/vm_kern.h> #include <vm/vm_page.h> +#include <vm/vm_map.h> #include <vm/uma.h> #include <vm/uma_int.h> #include <vm/uma_dbg.h> +#ifdef __rtems__ +#include <rtems/bsd/bsd.h> +#endif /* __rtems__ */ /* * In FreeBSD, Mbufs and Mbuf Clusters are allocated from UMA @@ -78,7 +82,7 @@ __FBSDID("$FreeBSD$"); * [ Cluster Zone ] [ Zone ] [ Mbuf Master Zone ] * | \________ | * [ Cluster Keg ] \ / - * | [ Mbuf Keg ] + * | [ Mbuf Keg ] * [ Cluster Slabs ] | * | [ Mbuf Slabs ] * \____________(VM)_________________/ @@ -98,39 +102,69 @@ __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 */ int nmbjumbo16; /* limits number of 16k jumbo clusters */ struct mbstat mbstat; +static quad_t maxmbufmem; /* overall real memory limit for all mbufs */ + +SYSCTL_QUAD(_kern_ipc, OID_AUTO, maxmbufmem, CTLFLAG_RDTUN, &maxmbufmem, 0, + "Maximum real memory allocateable to various mbuf types"); + /* - * 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. + * tunable_mbinit() has to be run before any mbuf allocations are done. */ static void tunable_mbinit(void *dummy) { +#ifndef __rtems__ + quad_t realmem; + + /* + * The default limit for all mbuf related memory is 1/2 of all + * available kernel memory (physical or kmem). + * At most it can be 3/4 of available kernel memory. + */ + realmem = qmin((quad_t)physmem * PAGE_SIZE, + vm_map_max(kmem_map) - vm_map_min(kmem_map)); + maxmbufmem = realmem / 2; + TUNABLE_QUAD_FETCH("kern.ipc.maxmbufmem", &maxmbufmem); + if (maxmbufmem > realmem / 4 * 3) + maxmbufmem = realmem / 4 * 3; +#else /* __rtems__ */ + maxmbufmem = rtems_bsd_get_allocator_domain_size( + RTEMS_BSD_ALLOCATOR_DOMAIN_MBUF); +#endif /* __rtems__ */ - /* This has to be done before VM init. */ TUNABLE_INT_FETCH("kern.ipc.nmbclusters", &nmbclusters); if (nmbclusters == 0) - nmbclusters = 1024 + maxusers * 64; + 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); +SYSINIT(tunable_mbinit, SI_SUB_KMEM, SI_ORDER_MIDDLE, tunable_mbinit, NULL); static int sysctl_nmbclusters(SYSCTL_HANDLER_ARGS) @@ -138,11 +172,12 @@ sysctl_nmbclusters(SYSCTL_HANDLER_ARGS) int error, newnmbclusters; newnmbclusters = nmbclusters; - error = sysctl_handle_int(oidp, &newnmbclusters, 0, req); - if (error == 0 && req->newptr) { - if (newnmbclusters > nmbclusters) { + error = sysctl_handle_int(oidp, &newnmbclusters, 0, req); + if (error == 0 && req->newptr && newnmbclusters != nmbclusters) { + if (newnmbclusters > nmbclusters && + nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) { nmbclusters = newnmbclusters; - uma_zone_set_max(zone_clust, nmbclusters); + nmbclusters = uma_zone_set_max(zone_clust, nmbclusters); #ifndef __rtems__ EVENTHANDLER_INVOKE(nmbclusters_change); #endif /* __rtems__ */ @@ -161,11 +196,12 @@ sysctl_nmbjumbop(SYSCTL_HANDLER_ARGS) int error, newnmbjumbop; newnmbjumbop = nmbjumbop; - error = sysctl_handle_int(oidp, &newnmbjumbop, 0, req); - if (error == 0 && req->newptr) { - if (newnmbjumbop> nmbjumbop) { + error = sysctl_handle_int(oidp, &newnmbjumbop, 0, req); + if (error == 0 && req->newptr && newnmbjumbop != nmbjumbop) { + if (newnmbjumbop > nmbjumbop && + nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) { nmbjumbop = newnmbjumbop; - uma_zone_set_max(zone_jumbop, nmbjumbop); + nmbjumbop = uma_zone_set_max(zone_jumbop, nmbjumbop); } else error = EINVAL; } @@ -173,8 +209,7 @@ sysctl_nmbjumbop(SYSCTL_HANDLER_ARGS) } SYSCTL_PROC(_kern_ipc, OID_AUTO, nmbjumbop, CTLTYPE_INT|CTLFLAG_RW, &nmbjumbop, 0, sysctl_nmbjumbop, "IU", - "Maximum number of mbuf page size jumbo clusters allowed"); - + "Maximum number of mbuf page size jumbo clusters allowed"); static int sysctl_nmbjumbo9(SYSCTL_HANDLER_ARGS) @@ -182,11 +217,12 @@ sysctl_nmbjumbo9(SYSCTL_HANDLER_ARGS) int error, newnmbjumbo9; newnmbjumbo9 = nmbjumbo9; - error = sysctl_handle_int(oidp, &newnmbjumbo9, 0, req); - if (error == 0 && req->newptr) { - if (newnmbjumbo9> nmbjumbo9) { + error = sysctl_handle_int(oidp, &newnmbjumbo9, 0, req); + if (error == 0 && req->newptr && newnmbjumbo9 != nmbjumbo9) { + if (newnmbjumbo9 > nmbjumbo9 && + nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) { nmbjumbo9 = newnmbjumbo9; - uma_zone_set_max(zone_jumbo9, nmbjumbo9); + nmbjumbo9 = uma_zone_set_max(zone_jumbo9, nmbjumbo9); } else error = EINVAL; } @@ -194,7 +230,7 @@ sysctl_nmbjumbo9(SYSCTL_HANDLER_ARGS) } SYSCTL_PROC(_kern_ipc, OID_AUTO, nmbjumbo9, CTLTYPE_INT|CTLFLAG_RW, &nmbjumbo9, 0, sysctl_nmbjumbo9, "IU", - "Maximum number of mbuf 9k jumbo clusters allowed"); + "Maximum number of mbuf 9k jumbo clusters allowed"); static int sysctl_nmbjumbo16(SYSCTL_HANDLER_ARGS) @@ -202,11 +238,12 @@ sysctl_nmbjumbo16(SYSCTL_HANDLER_ARGS) int error, newnmbjumbo16; newnmbjumbo16 = nmbjumbo16; - error = sysctl_handle_int(oidp, &newnmbjumbo16, 0, req); - if (error == 0 && req->newptr) { - if (newnmbjumbo16> nmbjumbo16) { + error = sysctl_handle_int(oidp, &newnmbjumbo16, 0, req); + if (error == 0 && req->newptr && newnmbjumbo16 != nmbjumbo16) { + if (newnmbjumbo16 > nmbjumbo16 && + nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) { nmbjumbo16 = newnmbjumbo16; - uma_zone_set_max(zone_jumbo16, nmbjumbo16); + nmbjumbo16 = uma_zone_set_max(zone_jumbo16, nmbjumbo16); } else error = EINVAL; } @@ -216,7 +253,26 @@ 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 && newnmbufs != nmbufs) { + if (newnmbufs > nmbufs) { + nmbufs = newnmbufs; + nmbufs = uma_zone_set_max(zone_mbuf, nmbufs); + EVENTHANDLER_INVOKE(nmbufs_change); + } else + error = EINVAL; + } + return (error); +} +SYSCTL_PROC(_kern_ipc, OID_AUTO, nmbufs, 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, "Mbuf general information and statistics"); @@ -245,7 +301,6 @@ static int mb_zinit_pack(void *, int, int); static void mb_zfini_pack(void *, int); static void mb_reclaim(void *); -static void mbuf_init(void *); static void *mbuf_jumbo_alloc(uma_zone_t, int, uint8_t *, int); /* Ensure that MSIZE doesn't break dtom() - it must be a power of 2 */ @@ -254,7 +309,6 @@ CTASSERT((((MSIZE - 1) ^ MSIZE) + 1) >> 1 == MSIZE); /* * Initialize FreeBSD Network buffer allocation. */ -SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbuf_init, NULL); static void mbuf_init(void *dummy) { @@ -270,6 +324,8 @@ mbuf_init(void *dummy) NULL, NULL, #endif MSIZE - 1, UMA_ZONE_MAXBUCKET); + if (nmbufs > 0) + nmbufs = uma_zone_set_max(zone_mbuf, nmbufs); zone_clust = uma_zcreate(MBUF_CLUSTER_MEM_NAME, MCLBYTES, mb_ctor_clust, mb_dtor_clust, @@ -280,7 +336,7 @@ mbuf_init(void *dummy) #endif UMA_ALIGN_PTR, UMA_ZONE_REFCNT); if (nmbclusters > 0) - uma_zone_set_max(zone_clust, nmbclusters); + nmbclusters = uma_zone_set_max(zone_clust, nmbclusters); zone_pack = uma_zsecond_create(MBUF_PACKET_MEM_NAME, mb_ctor_pack, mb_dtor_pack, mb_zinit_pack, mb_zfini_pack, zone_mbuf); @@ -295,7 +351,7 @@ mbuf_init(void *dummy) #endif UMA_ALIGN_PTR, UMA_ZONE_REFCNT); if (nmbjumbop > 0) - uma_zone_set_max(zone_jumbop, nmbjumbop); + nmbjumbop = uma_zone_set_max(zone_jumbop, nmbjumbop); zone_jumbo9 = uma_zcreate(MBUF_JUMBO9_MEM_NAME, MJUM9BYTES, mb_ctor_clust, mb_dtor_clust, @@ -305,9 +361,9 @@ 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) + nmbjumbo9 = uma_zone_set_max(zone_jumbo9, nmbjumbo9); zone_jumbo16 = uma_zcreate(MBUF_JUMBO16_MEM_NAME, MJUM16BYTES, mb_ctor_clust, mb_dtor_clust, @@ -317,9 +373,9 @@ 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) + nmbjumbo16 = uma_zone_set_max(zone_jumbo16, nmbjumbo16); zone_ext_refcnt = uma_zcreate(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int), NULL, NULL, @@ -357,6 +413,7 @@ mbuf_init(void *dummy) mbstat.sf_iocnt = 0; mbstat.sf_allocwait = mbstat.sf_allocfail = 0; } +SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbuf_init, NULL); /* * UMA backend page allocator for the jumbo frame zones. @@ -445,7 +502,7 @@ static void mb_dtor_mbuf(void *mem, int size, void *arg) { struct mbuf *m; - unsigned long flags; + unsigned long flags; m = (struct mbuf *)mem; flags = (unsigned long)arg; |