uipc_mbuf.c (64048) | uipc_mbuf.c (64837) |
---|---|
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 64048 2000-07-31 09:24:32Z alfred $ | 34 * $FreeBSD: head/sys/kern/uipc_mbuf.c 64837 2000-08-19 08:32:59Z dwmalone $ |
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/kernel.h> --- 8 unchanged lines hidden (view full) --- 51#ifdef INVARIANTS 52#include <machine/cpu.h> 53#endif 54 55static void mbinit __P((void *)); 56SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbinit, NULL) 57 58struct mbuf *mbutl; | 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/kernel.h> --- 8 unchanged lines hidden (view full) --- 51#ifdef INVARIANTS 52#include <machine/cpu.h> 53#endif 54 55static void mbinit __P((void *)); 56SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbinit, NULL) 57 58struct mbuf *mbutl; |
59char *mclrefcnt; | |
60struct mbstat mbstat; 61u_long mbtypes[MT_NTYPES]; 62struct mbuf *mmbfree; 63union mcluster *mclfree; | 59struct mbstat mbstat; 60u_long mbtypes[MT_NTYPES]; 61struct mbuf *mmbfree; 62union mcluster *mclfree; |
63union mext_refcnt *mext_refcnt_free; |
|
64int max_linkhdr; 65int max_protohdr; 66int max_hdr; 67int max_datalen; 68int nmbclusters; 69int nmbufs; 70u_int m_mballoc_wid = 0; 71u_int m_clalloc_wid = 0; --- 18 unchanged lines hidden (view full) --- 90#ifndef NMBCLUSTERS 91#define NMBCLUSTERS (512 + MAXUSERS * 16) 92#endif 93TUNABLE_INT_DECL("kern.ipc.nmbclusters", NMBCLUSTERS, nmbclusters); 94TUNABLE_INT_DECL("kern.ipc.nmbufs", NMBCLUSTERS * 4, nmbufs); 95 96static void m_reclaim __P((void)); 97 | 64int max_linkhdr; 65int max_protohdr; 66int max_hdr; 67int max_datalen; 68int nmbclusters; 69int nmbufs; 70u_int m_mballoc_wid = 0; 71u_int m_clalloc_wid = 0; --- 18 unchanged lines hidden (view full) --- 90#ifndef NMBCLUSTERS 91#define NMBCLUSTERS (512 + MAXUSERS * 16) 92#endif 93TUNABLE_INT_DECL("kern.ipc.nmbclusters", NMBCLUSTERS, nmbclusters); 94TUNABLE_INT_DECL("kern.ipc.nmbufs", NMBCLUSTERS * 4, nmbufs); 95 96static void m_reclaim __P((void)); 97 |
98/* "number of clusters of pages" */ 99#define NCL_INIT 1 100 | 98#define NCL_INIT 2 |
101#define NMB_INIT 16 | 99#define NMB_INIT 16 |
100#define REF_INIT (NMBCLUSTERS * 2) |
|
102 103/* ARGSUSED*/ 104static void 105mbinit(dummy) 106 void *dummy; 107{ 108 int s; 109 | 101 102/* ARGSUSED*/ 103static void 104mbinit(dummy) 105 void *dummy; 106{ 107 int s; 108 |
110 mmbfree = NULL; mclfree = NULL; | 109 mmbfree = NULL; 110 mclfree = NULL; 111 mext_refcnt_free = NULL; 112 |
111 mbstat.m_msize = MSIZE; 112 mbstat.m_mclbytes = MCLBYTES; 113 mbstat.m_minclsize = MINCLSIZE; 114 mbstat.m_mlen = MLEN; 115 mbstat.m_mhlen = MHLEN; 116 117 s = splimp(); | 113 mbstat.m_msize = MSIZE; 114 mbstat.m_mclbytes = MCLBYTES; 115 mbstat.m_minclsize = MINCLSIZE; 116 mbstat.m_mlen = MLEN; 117 mbstat.m_mhlen = MHLEN; 118 119 s = splimp(); |
120 if (m_alloc_ref(REF_INIT) == 0) 121 goto bad; |
|
118 if (m_mballoc(NMB_INIT, M_DONTWAIT) == 0) 119 goto bad; 120#if MCLBYTES <= PAGE_SIZE 121 if (m_clalloc(NCL_INIT, M_DONTWAIT) == 0) 122 goto bad; 123#else 124 /* It's OK to call contigmalloc in this context. */ 125 if (m_clalloc(16, M_WAIT) == 0) 126 goto bad; 127#endif 128 splx(s); 129 return; 130bad: | 122 if (m_mballoc(NMB_INIT, M_DONTWAIT) == 0) 123 goto bad; 124#if MCLBYTES <= PAGE_SIZE 125 if (m_clalloc(NCL_INIT, M_DONTWAIT) == 0) 126 goto bad; 127#else 128 /* It's OK to call contigmalloc in this context. */ 129 if (m_clalloc(16, M_WAIT) == 0) 130 goto bad; 131#endif 132 splx(s); 133 return; 134bad: |
131 panic("mbinit"); | 135 panic("mbinit: failed to initialize mbuf subsystem!"); |
132} 133 134/* | 136} 137 138/* |
139 * Allocate at least nmb reference count structs and place them 140 * on the ref cnt free list. 141 * Must be called at splimp. 142 */ 143int 144m_alloc_ref(nmb) 145 u_int nmb; 146{ 147 caddr_t p; 148 u_int nbytes; 149 int i; 150 151 /* 152 * XXX: 153 * We don't cap the amount of memory that can be used 154 * by the reference counters, like we do for mbufs and 155 * mbuf clusters. The reason is that we don't really expect 156 * to have to be allocating too many of these guys with m_alloc_ref(), 157 * and if we are, we're probably not out of the woods anyway, 158 * so leave this way for now. 159 */ 160 161 if (mb_map_full) 162 return (0); 163 164 nbytes = round_page(nmb * sizeof(union mext_refcnt)); 165 if ((p = (caddr_t)kmem_malloc(mb_map, nbytes, M_NOWAIT)) == NULL) 166 return (0); 167 nmb = nbytes / sizeof(union mext_refcnt); 168 169 for (i = 0; i < nmb; i++) { 170 ((union mext_refcnt *)p)->next_ref = mext_refcnt_free; 171 mext_refcnt_free = (union mext_refcnt *)p; 172 p += sizeof(union mext_refcnt); 173 mbstat.m_refree++; 174 } 175 mbstat.m_refcnt += nmb; 176 177 return (1); 178} 179 180/* |
|
135 * Allocate at least nmb mbufs and place on mbuf free list. 136 * Must be called at splimp. 137 */ 138/* ARGSUSED */ 139int 140m_mballoc(nmb, how) 141 register int nmb; 142 int how; --- 215 unchanged lines hidden (view full) --- 358 if ((tsleep(&m_clalloc_wid, PVM, "mclalc", mbuf_wait)) == EWOULDBLOCK) 359 m_clalloc_wid--; 360 361 /* 362 * Now that we (think) that we've got something, we will redo and 363 * MGET, but avoid getting into another instance of m_clalloc_wait() 364 */ 365 p = NULL; | 181 * Allocate at least nmb mbufs and place on mbuf free list. 182 * Must be called at splimp. 183 */ 184/* ARGSUSED */ 185int 186m_mballoc(nmb, how) 187 register int nmb; 188 int how; --- 215 unchanged lines hidden (view full) --- 404 if ((tsleep(&m_clalloc_wid, PVM, "mclalc", mbuf_wait)) == EWOULDBLOCK) 405 m_clalloc_wid--; 406 407 /* 408 * Now that we (think) that we've got something, we will redo and 409 * MGET, but avoid getting into another instance of m_clalloc_wait() 410 */ 411 p = NULL; |
366 MCLALLOC(p, M_DONTWAIT); | 412 _MCLALLOC(p, M_DONTWAIT); |
367 368 s = splimp(); 369 if (p != NULL) { /* We waited and got something... */ 370 mbstat.m_wait++; 371 /* Wake up another if we have more free. */ 372 if (mclfree != NULL) 373 MCLWAKEUP(); 374 } --- 244 unchanged lines hidden (view full) --- 619 n->m_pkthdr.len -= off0; 620 else 621 n->m_pkthdr.len = len; 622 copyhdr = 0; 623 } 624 n->m_len = min(len, m->m_len - off); 625 if (m->m_flags & M_EXT) { 626 n->m_data = m->m_data + off; | 413 414 s = splimp(); 415 if (p != NULL) { /* We waited and got something... */ 416 mbstat.m_wait++; 417 /* Wake up another if we have more free. */ 418 if (mclfree != NULL) 419 MCLWAKEUP(); 420 } --- 244 unchanged lines hidden (view full) --- 665 n->m_pkthdr.len -= off0; 666 else 667 n->m_pkthdr.len = len; 668 copyhdr = 0; 669 } 670 n->m_len = min(len, m->m_len - off); 671 if (m->m_flags & M_EXT) { 672 n->m_data = m->m_data + off; |
627 if(!m->m_ext.ext_ref) 628 mclrefcnt[mtocl(m->m_ext.ext_buf)]++; 629 else 630 (*(m->m_ext.ext_ref))(m->m_ext.ext_buf, 631 m->m_ext.ext_size); | |
632 n->m_ext = m->m_ext; 633 n->m_flags |= M_EXT; | 673 n->m_ext = m->m_ext; 674 n->m_flags |= M_EXT; |
675 MEXT_ADD_REF(m); |
|
634 } else 635 bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t), 636 (unsigned)n->m_len); 637 if (len != M_COPYALL) 638 len -= n->m_len; 639 off = 0; 640 m = m->m_next; 641 np = &n->m_next; --- 24 unchanged lines hidden (view full) --- 666 top = n; 667 if (!n) 668 goto nospace; 669 670 M_COPY_PKTHDR(n, m); 671 n->m_len = m->m_len; 672 if (m->m_flags & M_EXT) { 673 n->m_data = m->m_data; | 676 } else 677 bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t), 678 (unsigned)n->m_len); 679 if (len != M_COPYALL) 680 len -= n->m_len; 681 off = 0; 682 m = m->m_next; 683 np = &n->m_next; --- 24 unchanged lines hidden (view full) --- 708 top = n; 709 if (!n) 710 goto nospace; 711 712 M_COPY_PKTHDR(n, m); 713 n->m_len = m->m_len; 714 if (m->m_flags & M_EXT) { 715 n->m_data = m->m_data; |
674 if(!m->m_ext.ext_ref) 675 mclrefcnt[mtocl(m->m_ext.ext_buf)]++; 676 else 677 (*(m->m_ext.ext_ref))(m->m_ext.ext_buf, 678 m->m_ext.ext_size); | |
679 n->m_ext = m->m_ext; 680 n->m_flags |= M_EXT; | 716 n->m_ext = m->m_ext; 717 n->m_flags |= M_EXT; |
718 MEXT_ADD_REF(m); |
|
681 } else { 682 bcopy(mtod(m, char *), mtod(n, char *), n->m_len); 683 } 684 685 m = m->m_next; 686 while (m) { 687 MGET(o, how, m->m_type); 688 if (!o) 689 goto nospace; 690 691 n->m_next = o; 692 n = n->m_next; 693 694 n->m_len = m->m_len; 695 if (m->m_flags & M_EXT) { 696 n->m_data = m->m_data; | 719 } else { 720 bcopy(mtod(m, char *), mtod(n, char *), n->m_len); 721 } 722 723 m = m->m_next; 724 while (m) { 725 MGET(o, how, m->m_type); 726 if (!o) 727 goto nospace; 728 729 n->m_next = o; 730 n = n->m_next; 731 732 n->m_len = m->m_len; 733 if (m->m_flags & M_EXT) { 734 n->m_data = m->m_data; |
697 if(!m->m_ext.ext_ref) 698 mclrefcnt[mtocl(m->m_ext.ext_buf)]++; 699 else 700 (*(m->m_ext.ext_ref))(m->m_ext.ext_buf, 701 m->m_ext.ext_size); | |
702 n->m_ext = m->m_ext; 703 n->m_flags |= M_EXT; | 735 n->m_ext = m->m_ext; 736 n->m_flags |= M_EXT; |
737 MEXT_ADD_REF(m); |
|
704 } else { 705 bcopy(mtod(m, char *), mtod(n, char *), n->m_len); 706 } 707 708 m = m->m_next; 709 } 710 return top; 711nospace: --- 325 unchanged lines hidden (view full) --- 1037 if (n == 0) 1038 return (0); 1039 M_ALIGN(n, remain); 1040 } 1041extpacket: 1042 if (m->m_flags & M_EXT) { 1043 n->m_flags |= M_EXT; 1044 n->m_ext = m->m_ext; | 738 } else { 739 bcopy(mtod(m, char *), mtod(n, char *), n->m_len); 740 } 741 742 m = m->m_next; 743 } 744 return top; 745nospace: --- 325 unchanged lines hidden (view full) --- 1071 if (n == 0) 1072 return (0); 1073 M_ALIGN(n, remain); 1074 } 1075extpacket: 1076 if (m->m_flags & M_EXT) { 1077 n->m_flags |= M_EXT; 1078 n->m_ext = m->m_ext; |
1045 if(!m->m_ext.ext_ref) 1046 mclrefcnt[mtocl(m->m_ext.ext_buf)]++; 1047 else 1048 (*(m->m_ext.ext_ref))(m->m_ext.ext_buf, 1049 m->m_ext.ext_size); | 1079 MEXT_ADD_REF(m); |
1050 m->m_ext.ext_size = 0; /* For Accounting XXXXXX danger */ 1051 n->m_data = m->m_data + len; 1052 } else { 1053 bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain); 1054 } 1055 n->m_len = remain; 1056 m->m_len = len; 1057 n->m_next = m->m_next; --- 141 unchanged lines hidden --- | 1080 m->m_ext.ext_size = 0; /* For Accounting XXXXXX danger */ 1081 n->m_data = m->m_data + len; 1082 } else { 1083 bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain); 1084 } 1085 n->m_len = remain; 1086 m->m_len = len; 1087 n->m_next = m->m_next; --- 141 unchanged lines hidden --- |