uipc_mbuf.c (75105) | uipc_mbuf.c (75112) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1988, 1991, 1993 3 * The Regents of the University of California. 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 --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 | 1/* 2 * Copyright (c) 1982, 1986, 1988, 1991, 1993 3 * The Regents of the University of California. 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 --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 |
34 * $FreeBSD: head/sys/kern/uipc_mbuf.c 75105 2001-04-03 03:15:11Z alfred $ | 34 * $FreeBSD: head/sys/kern/uipc_mbuf.c 75112 2001-04-03 04:50:13Z bmilekic $ |
35 */ 36 37#include "opt_param.h" 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/malloc.h> 41#include <sys/mbuf.h> 42#include <sys/mutex.h> | 35 */ 36 37#include "opt_param.h" 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/malloc.h> 41#include <sys/mbuf.h> 42#include <sys/mutex.h> |
43#include <sys/condvar.h> |
|
43#include <sys/kernel.h> 44#include <sys/sysctl.h> 45#include <sys/domain.h> 46#include <sys/protosw.h> 47#include <vm/vm.h> 48#include <vm/vm_kern.h> 49#include <vm/vm_extern.h> 50 --- 39 unchanged lines hidden (view full) --- 90SYSCTL_OPAQUE(_kern_ipc, OID_AUTO, mbtypes, CTLFLAG_RD, mbtypes, 91 sizeof(mbtypes), "LU", ""); 92SYSCTL_INT(_kern_ipc, KIPC_NMBCLUSTERS, nmbclusters, CTLFLAG_RD, 93 &nmbclusters, 0, "Maximum number of mbuf clusters available"); 94SYSCTL_INT(_kern_ipc, OID_AUTO, nmbufs, CTLFLAG_RD, &nmbufs, 0, 95 "Maximum number of mbufs available"); 96SYSCTL_INT(_kern_ipc, OID_AUTO, nmbcnt, CTLFLAG_RD, &nmbcnt, 0, 97 "Maximum number of ext_buf counters available"); | 44#include <sys/kernel.h> 45#include <sys/sysctl.h> 46#include <sys/domain.h> 47#include <sys/protosw.h> 48#include <vm/vm.h> 49#include <vm/vm_kern.h> 50#include <vm/vm_extern.h> 51 --- 39 unchanged lines hidden (view full) --- 91SYSCTL_OPAQUE(_kern_ipc, OID_AUTO, mbtypes, CTLFLAG_RD, mbtypes, 92 sizeof(mbtypes), "LU", ""); 93SYSCTL_INT(_kern_ipc, KIPC_NMBCLUSTERS, nmbclusters, CTLFLAG_RD, 94 &nmbclusters, 0, "Maximum number of mbuf clusters available"); 95SYSCTL_INT(_kern_ipc, OID_AUTO, nmbufs, CTLFLAG_RD, &nmbufs, 0, 96 "Maximum number of mbufs available"); 97SYSCTL_INT(_kern_ipc, OID_AUTO, nmbcnt, CTLFLAG_RD, &nmbcnt, 0, 98 "Maximum number of ext_buf counters available"); |
99 |
|
98#ifndef NMBCLUSTERS 99#define NMBCLUSTERS (512 + MAXUSERS * 16) 100#endif | 100#ifndef NMBCLUSTERS 101#define NMBCLUSTERS (512 + MAXUSERS * 16) 102#endif |
103 |
|
101TUNABLE_INT_DECL("kern.ipc.nmbclusters", NMBCLUSTERS, nmbclusters); 102TUNABLE_INT_DECL("kern.ipc.nmbufs", NMBCLUSTERS * 4, nmbufs); 103TUNABLE_INT_DECL("kern.ipc.nmbcnt", EXT_COUNTERS, nmbcnt); 104 105static void m_reclaim(void); 106 107/* Initial allocation numbers */ 108#define NCL_INIT 2 --- 23 unchanged lines hidden (view full) --- 132 133 /* 134 * Initialize the free list headers, and setup locks for lists. 135 */ 136 mmbfree.m_head = NULL; 137 mclfree.m_head = NULL; 138 mcntfree.m_head = NULL; 139 mtx_init(&mbuf_mtx, "mbuf free list lock", MTX_DEF); | 104TUNABLE_INT_DECL("kern.ipc.nmbclusters", NMBCLUSTERS, nmbclusters); 105TUNABLE_INT_DECL("kern.ipc.nmbufs", NMBCLUSTERS * 4, nmbufs); 106TUNABLE_INT_DECL("kern.ipc.nmbcnt", EXT_COUNTERS, nmbcnt); 107 108static void m_reclaim(void); 109 110/* Initial allocation numbers */ 111#define NCL_INIT 2 --- 23 unchanged lines hidden (view full) --- 135 136 /* 137 * Initialize the free list headers, and setup locks for lists. 138 */ 139 mmbfree.m_head = NULL; 140 mclfree.m_head = NULL; 141 mcntfree.m_head = NULL; 142 mtx_init(&mbuf_mtx, "mbuf free list lock", MTX_DEF); |
143 cv_init(&mmbfree.m_starved, "mbuf free list starved cv"); 144 cv_init(&mclfree.m_starved, "mbuf cluster free list starved cv"); |
|
140 141 /* 142 * Initialize mbuf subsystem (sysctl exported) statistics structure. 143 */ 144 mbstat.m_msize = MSIZE; 145 mbstat.m_mclbytes = MCLBYTES; 146 mbstat.m_minclsize = MINCLSIZE; 147 mbstat.m_mlen = MLEN; --- 130 unchanged lines hidden (view full) --- 278 279/* 280 * Once the mb_map has been exhausted and if the call to the allocation macros 281 * (or, in some cases, functions) is with M_TRYWAIT, then it is necessary to 282 * rely solely on reclaimed mbufs. 283 * 284 * Here we request for the protocols to free up some resources and, if we 285 * still cannot get anything, then we wait for an mbuf to be freed for a | 145 146 /* 147 * Initialize mbuf subsystem (sysctl exported) statistics structure. 148 */ 149 mbstat.m_msize = MSIZE; 150 mbstat.m_mclbytes = MCLBYTES; 151 mbstat.m_minclsize = MINCLSIZE; 152 mbstat.m_mlen = MLEN; --- 130 unchanged lines hidden (view full) --- 283 284/* 285 * Once the mb_map has been exhausted and if the call to the allocation macros 286 * (or, in some cases, functions) is with M_TRYWAIT, then it is necessary to 287 * rely solely on reclaimed mbufs. 288 * 289 * Here we request for the protocols to free up some resources and, if we 290 * still cannot get anything, then we wait for an mbuf to be freed for a |
286 * designated (mbuf_wait) time. | 291 * designated (mbuf_wait) time, at most. |
287 * 288 * Must be called with the mmbfree mutex held. 289 */ 290struct mbuf * 291m_mballoc_wait(void) 292{ 293 struct mbuf *p = NULL; 294 --- 9 unchanged lines hidden (view full) --- 304 */ 305 mtx_unlock(&mbuf_mtx); 306 m_reclaim(); 307 308 mtx_lock(&mbuf_mtx); 309 _MGET(p, M_DONTWAIT); 310 311 if (p == NULL) { | 292 * 293 * Must be called with the mmbfree mutex held. 294 */ 295struct mbuf * 296m_mballoc_wait(void) 297{ 298 struct mbuf *p = NULL; 299 --- 9 unchanged lines hidden (view full) --- 309 */ 310 mtx_unlock(&mbuf_mtx); 311 m_reclaim(); 312 313 mtx_lock(&mbuf_mtx); 314 _MGET(p, M_DONTWAIT); 315 316 if (p == NULL) { |
317 int retval; 318 |
|
312 m_mballoc_wid++; | 319 m_mballoc_wid++; |
313 msleep(&m_mballoc_wid, &mbuf_mtx, PVM, "mballc", | 320 retval = cv_timedwait(&mmbfree.m_starved, &mbuf_mtx, |
314 mbuf_wait); 315 m_mballoc_wid--; 316 317 /* | 321 mbuf_wait); 322 m_mballoc_wid--; 323 324 /* |
318 * Try again (one last time). 319 * 320 * We retry to fetch _even_ if the sleep timed out. This 321 * is left this way, purposely, in the [unlikely] case 322 * that an mbuf was freed but the sleep was not awoken 323 * in time. 324 * 325 * If the sleep didn't time out (i.e. we got woken up) then 326 * we have the lock so we just grab an mbuf, hopefully. | 325 * If we got signaled (i.e. didn't time out), allocate. |
327 */ | 326 */ |
328 _MGET(p, M_DONTWAIT); | 327 if (retval == 0) 328 _MGET(p, M_DONTWAIT); |
329 } 330 | 329 } 330 |
331 /* If we waited and got something... */ | |
332 if (p != NULL) { 333 mbstat.m_wait++; 334 if (mmbfree.m_head != NULL) | 331 if (p != NULL) { 332 mbstat.m_wait++; 333 if (mmbfree.m_head != NULL) |
335 MBWAKEUP(m_mballoc_wid); | 334 MBWAKEUP(m_mballoc_wid, &mmbfree.m_starved); |
336 } 337 338 return (p); 339} 340 341/* 342 * Allocate some number of mbuf clusters 343 * and place on cluster free list. --- 40 unchanged lines hidden (view full) --- 384 } 385 mbstat.m_clusters += ncl; 386 return (1); 387} 388 389/* 390 * Once the mb_map submap has been exhausted and the allocation is called with 391 * M_TRYWAIT, we rely on the mclfree list. If nothing is free, we will | 335 } 336 337 return (p); 338} 339 340/* 341 * Allocate some number of mbuf clusters 342 * and place on cluster free list. --- 40 unchanged lines hidden (view full) --- 383 } 384 mbstat.m_clusters += ncl; 385 return (1); 386} 387 388/* 389 * Once the mb_map submap has been exhausted and the allocation is called with 390 * M_TRYWAIT, we rely on the mclfree list. If nothing is free, we will |
392 * sleep for a designated amount of time (mbuf_wait) or until we're woken up 393 * due to sudden mcluster availability. | 391 * block on a cv for a designated amount of time (mbuf_wait) or until we're 392 * signaled due to sudden mcluster availability. |
394 * 395 * Must be called with the mclfree lock held. 396 */ 397caddr_t 398m_clalloc_wait(void) 399{ 400 caddr_t p = NULL; | 393 * 394 * Must be called with the mclfree lock held. 395 */ 396caddr_t 397m_clalloc_wait(void) 398{ 399 caddr_t p = NULL; |
400 int retval; |
|
401 402 m_clalloc_wid++; | 401 402 m_clalloc_wid++; |
403 msleep(&m_clalloc_wid, &mbuf_mtx, PVM, "mclalc", mbuf_wait); | 403 retval = cv_timedwait(&mclfree.m_starved, &mbuf_mtx, mbuf_wait); |
404 m_clalloc_wid--; 405 406 /* 407 * Now that we (think) that we've got something, try again. 408 */ | 404 m_clalloc_wid--; 405 406 /* 407 * Now that we (think) that we've got something, try again. 408 */ |
409 _MCLALLOC(p, M_DONTWAIT); | 409 if (retval == 0) 410 _MCLALLOC(p, M_DONTWAIT); |
410 | 411 |
411 /* If we waited and got something ... */ | |
412 if (p != NULL) { 413 mbstat.m_wait++; 414 if (mclfree.m_head != NULL) | 412 if (p != NULL) { 413 mbstat.m_wait++; 414 if (mclfree.m_head != NULL) |
415 MBWAKEUP(m_clalloc_wid); | 415 MBWAKEUP(m_clalloc_wid, &mclfree.m_starved); |
416 } 417 418 return (p); 419} 420 421/* 422 * m_reclaim: drain protocols in hopes to free up some resources... 423 * --- 4 unchanged lines hidden (view full) --- 428 */ 429static void 430m_reclaim(void) 431{ 432 struct domain *dp; 433 struct protosw *pr; 434 435#ifdef WITNESS | 416 } 417 418 return (p); 419} 420 421/* 422 * m_reclaim: drain protocols in hopes to free up some resources... 423 * --- 4 unchanged lines hidden (view full) --- 428 */ 429static void 430m_reclaim(void) 431{ 432 struct domain *dp; 433 struct protosw *pr; 434 435#ifdef WITNESS |
436 KASSERT(witness_list(CURPROC) == 0, | 436 KASSERT(witness_list(curproc) == 0, |
437 ("m_reclaim called with locks held")); 438#endif 439 440 for (dp = domains; dp; dp = dp->dom_next) 441 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 442 if (pr->pr_drain) 443 (*pr->pr_drain)(); 444 mbstat.m_drain++; --- 757 unchanged lines hidden --- | 437 ("m_reclaim called with locks held")); 438#endif 439 440 for (dp = domains; dp; dp = dp->dom_next) 441 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 442 if (pr->pr_drain) 443 (*pr->pr_drain)(); 444 mbstat.m_drain++; --- 757 unchanged lines hidden --- |