Deleted Added
full compact
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 ---