1/*- 2 * Copyright (c) 2004, 2005, 3 * Bosko Milekic <bmilekic@FreeBSD.org>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> |
29__FBSDID("$FreeBSD: head/sys/kern/kern_mbuf.c 295222 2016-02-03 23:30:17Z glebius $"); |
30 31#include "opt_param.h" 32 33#include <sys/param.h> 34#include <sys/malloc.h> 35#include <sys/types.h> 36#include <sys/systm.h> 37#include <sys/mbuf.h> --- 231 unchanged lines hidden (view full) --- 269uma_zone_t zone_clust; 270uma_zone_t zone_pack; 271uma_zone_t zone_jumbop; 272uma_zone_t zone_jumbo9; 273uma_zone_t zone_jumbo16; 274uma_zone_t zone_ext_refcnt; 275 276/* |
277 * Local prototypes. 278 */ 279static int mb_ctor_mbuf(void *, int, void *, int); 280static int mb_ctor_clust(void *, int, void *, int); 281static int mb_ctor_pack(void *, int, void *, int); 282static void mb_dtor_mbuf(void *, int, void *); 283static void mb_dtor_clust(void *, int, void *); 284static void mb_dtor_pack(void *, int, void *); 285static int mb_zinit_pack(void *, int, int); 286static void mb_zfini_pack(void *, int); 287 |
288static void mb_reclaim(uma_zone_t, int); |
289static void *mbuf_jumbo_alloc(uma_zone_t, vm_size_t, uint8_t *, int); |
290 291/* Ensure that MSIZE is a power of 2. */ 292CTASSERT((((MSIZE - 1) ^ MSIZE) + 1) >> 1 == MSIZE); 293 294/* 295 * Initialize FreeBSD Network buffer allocation. 296 */ 297static void --- 9 unchanged lines hidden (view full) --- 307 trash_init, trash_fini, 308#else 309 NULL, NULL, 310#endif 311 MSIZE - 1, UMA_ZONE_MAXBUCKET); 312 if (nmbufs > 0) 313 nmbufs = uma_zone_set_max(zone_mbuf, nmbufs); 314 uma_zone_set_warning(zone_mbuf, "kern.ipc.nmbufs limit reached"); |
315 uma_zone_set_maxaction(zone_mbuf, mb_reclaim); |
316 317 zone_clust = uma_zcreate(MBUF_CLUSTER_MEM_NAME, MCLBYTES, 318 mb_ctor_clust, mb_dtor_clust, 319#ifdef INVARIANTS 320 trash_init, trash_fini, 321#else 322 NULL, NULL, 323#endif 324 UMA_ALIGN_PTR, UMA_ZONE_REFCNT); 325 if (nmbclusters > 0) 326 nmbclusters = uma_zone_set_max(zone_clust, nmbclusters); 327 uma_zone_set_warning(zone_clust, "kern.ipc.nmbclusters limit reached"); |
328 uma_zone_set_maxaction(zone_clust, mb_reclaim); |
329 330 zone_pack = uma_zsecond_create(MBUF_PACKET_MEM_NAME, mb_ctor_pack, 331 mb_dtor_pack, mb_zinit_pack, mb_zfini_pack, zone_mbuf); 332 333 /* Make jumbo frame zone too. Page size, 9k and 16k. */ 334 zone_jumbop = uma_zcreate(MBUF_JUMBOP_MEM_NAME, MJUMPAGESIZE, 335 mb_ctor_clust, mb_dtor_clust, 336#ifdef INVARIANTS 337 trash_init, trash_fini, 338#else 339 NULL, NULL, 340#endif 341 UMA_ALIGN_PTR, UMA_ZONE_REFCNT); 342 if (nmbjumbop > 0) 343 nmbjumbop = uma_zone_set_max(zone_jumbop, nmbjumbop); 344 uma_zone_set_warning(zone_jumbop, "kern.ipc.nmbjumbop limit reached"); |
345 uma_zone_set_maxaction(zone_jumbop, mb_reclaim); |
346 347 zone_jumbo9 = uma_zcreate(MBUF_JUMBO9_MEM_NAME, MJUM9BYTES, 348 mb_ctor_clust, mb_dtor_clust, 349#ifdef INVARIANTS 350 trash_init, trash_fini, 351#else 352 NULL, NULL, 353#endif 354 UMA_ALIGN_PTR, UMA_ZONE_REFCNT); 355 uma_zone_set_allocf(zone_jumbo9, mbuf_jumbo_alloc); 356 if (nmbjumbo9 > 0) 357 nmbjumbo9 = uma_zone_set_max(zone_jumbo9, nmbjumbo9); 358 uma_zone_set_warning(zone_jumbo9, "kern.ipc.nmbjumbo9 limit reached"); |
359 uma_zone_set_maxaction(zone_jumbo9, mb_reclaim); |
360 361 zone_jumbo16 = uma_zcreate(MBUF_JUMBO16_MEM_NAME, MJUM16BYTES, 362 mb_ctor_clust, mb_dtor_clust, 363#ifdef INVARIANTS 364 trash_init, trash_fini, 365#else 366 NULL, NULL, 367#endif 368 UMA_ALIGN_PTR, UMA_ZONE_REFCNT); 369 uma_zone_set_allocf(zone_jumbo16, mbuf_jumbo_alloc); 370 if (nmbjumbo16 > 0) 371 nmbjumbo16 = uma_zone_set_max(zone_jumbo16, nmbjumbo16); 372 uma_zone_set_warning(zone_jumbo16, "kern.ipc.nmbjumbo16 limit reached"); |
373 uma_zone_set_maxaction(zone_jumbo16, mb_reclaim); |
374 375 zone_ext_refcnt = uma_zcreate(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int), 376 NULL, NULL, 377 NULL, NULL, 378 UMA_ALIGN_PTR, UMA_ZONE_ZINIT); 379 |
380 /* 381 * Hook event handler for low-memory situation, used to 382 * drain protocols and push data back to the caches (UMA 383 * later pushes it back to VM). 384 */ 385 EVENTHANDLER_REGISTER(vm_lowmem, mb_reclaim, NULL, 386 EVENTHANDLER_PRI_FIRST); 387} --- 270 unchanged lines hidden (view full) --- 658 if (error) 659 return (error); 660#endif 661 662 return (0); 663} 664 665/* |
666 * This is the protocol drain routine. Called by UMA whenever any of the 667 * mbuf zones is closed to its limit. |
668 * 669 * No locks should be held when this is called. The drain routines have to 670 * presently acquire some locks which raises the possibility of lock order 671 * reversal. 672 */ 673static void |
674mb_reclaim(uma_zone_t zone __unused, int pending __unused) |
675{ 676 struct domain *dp; 677 struct protosw *pr; 678 |
679 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK | WARN_PANIC, NULL, __func__); |
680 681 for (dp = domains; dp != NULL; dp = dp->dom_next) 682 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 683 if (pr->pr_drain != NULL) 684 (*pr->pr_drain)(); 685} |