use -X on profiled .o files (to retain statics) and -x on regular .o files
[unix-history] / usr / src / sys / kern / uipc_mbuf.c
CommitLineData
0ef33f87 1/* uipc_mbuf.c 1.17 81/11/26 */
d80cae33
BJ
2
3#include "../h/param.h"
4#include "../h/dir.h"
5#include "../h/user.h"
6#include "../h/proc.h"
7#include "../h/pte.h"
8#include "../h/cmap.h"
9#include "../h/map.h"
e6dd2097 10#include "../h/mbuf.h"
0ef33f87 11#include "../net/in_systm.h" /* XXX */
d80cae33
BJ
12#include "../h/vm.h"
13
196d84fd
BJ
14m_reserve(mbufs)
15 int mbufs;
e1506033
BJ
16{
17
eb1bc170
BJ
18/*
19 printf("reserve %d\n", mbufs);
20*/
0ef33f87 21 if (mbstat.m_lowat + (mbufs>>1) > (NMBPAGES-32) * CLBYTES)
e1506033 22 return (0);
eb1bc170
BJ
23 mbstat.m_hiwat += mbufs;
24 mbstat.m_lowat = mbstat.m_hiwat >> 1;
ae921915 25 return (1);
e1506033
BJ
26}
27
196d84fd
BJ
28m_release(mbufs)
29 int mbufs;
e1506033
BJ
30{
31
eb1bc170
BJ
32/*
33 printf("release %d\n", mbufs);
34*/
35 mbstat.m_hiwat -= mbufs;
36 mbstat.m_lowat = mbstat.m_hiwat >> 1;
e1506033
BJ
37}
38
d80cae33
BJ
39struct mbuf *
40m_get(canwait)
41 int canwait;
42{
43 register struct mbuf *m;
44
45COUNT(M_GET);
46 MGET(m, canwait);
47 return (m);
48}
49
cc15ab5d
BJ
50struct mbuf *
51m_getclr(canwait)
52 int canwait;
53{
54 register struct mbuf *m;
55
56COUNT(M_GETCLR);
ae921915 57 m = m_get(canwait);
cc15ab5d
BJ
58 if (m == 0)
59 return (0);
60 m->m_off = MMINOFF;
61 bzero(mtod(m, caddr_t), MLEN);
62 return (m);
63}
64
d80cae33
BJ
65struct mbuf *
66m_free(m)
67 struct mbuf *m;
68{
69 register struct mbuf *n;
70
71COUNT(M_FREE);
72 MFREE(m, n);
73 return (n);
74}
75
ae921915 76/*ARGSUSED*/
d80cae33
BJ
77struct mbuf *
78m_more(type)
79 int type;
80{
d80cae33
BJ
81 register struct mbuf *m;
82
83COUNT(M_MORE);
84 if (!m_expand()) {
6d19f7ef 85 mbstat.m_drops++;
d80cae33
BJ
86 return (NULL);
87 }
ae921915
BJ
88#define m_more(x) (panic("m_more"), (struct mbuf *)0)
89 MGET(m, type);
d80cae33
BJ
90 return (m);
91}
92
8f3e7457 93m_freem(m)
d80cae33
BJ
94 register struct mbuf *m;
95{
96 register struct mbuf *n;
2b4b57cd 97 register int s;
d80cae33
BJ
98
99COUNT(M_FREEM);
100 if (m == NULL)
ae921915 101 return;
dad64fdf 102 s = splimp();
d80cae33 103 do {
8f3e7457 104 MFREE(m, n);
d80cae33
BJ
105 } while (m = n);
106 splx(s);
2b4b57cd
BJ
107}
108
4ad99bae 109/*ARGSUSED*/
2b4b57cd
BJ
110m_pullup(m, len)
111 struct mbuf *m;
112 int len;
113{
114
115 return (0);
116}
117
118struct mbuf *
119m_copy(m, off, len)
120 register struct mbuf *m;
121 int off;
122 register int len;
123{
124 register struct mbuf *n, **np;
125 struct mbuf *top, *p;
126COUNT(M_COPY);
127
128 if (len == 0)
129 return (0);
130 if (off < 0 || len < 0)
131 panic("m_copy");
132 while (off > 0) {
133 if (m == 0)
134 panic("m_copy");
135 if (off < m->m_len)
136 break;
137 off -= m->m_len;
138 m = m->m_next;
139 }
140 np = &top;
141 top = 0;
142 while (len > 0) {
143 MGET(n, 1);
144 *np = n;
145 if (n == 0)
146 goto nospace;
147 if (m == 0)
148 panic("m_copy");
149 n->m_len = MIN(len, m->m_len - off);
150 if (m->m_off > MMAXOFF) {
151 p = mtod(m, struct mbuf *);
152 n->m_off = ((int)p - (int)n) + off;
0ef33f87 153 mclrefcnt[mtocl(p)]++;
2b4b57cd
BJ
154 } else {
155 n->m_off = MMINOFF;
156 bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
157 (unsigned)n->m_len);
158 }
159 len -= n->m_len;
160 off = 0;
161 m = m->m_next;
162 np = &n->m_next;
163 }
164 return (top);
165nospace:
166 printf("m_copy: no space\n");
167 m_freem(top);
168 return (0);
d80cae33
BJ
169}
170
6d19f7ef 171mbinit()
d80cae33
BJ
172{
173 register struct mbuf *m;
174 register i;
175
176COUNT(MBUFINIT);
6d19f7ef 177 m = (struct mbuf *)&mbutl[0]; /* ->start of buffer virt mem */
ae921915
BJ
178 (void) vmemall(&Mbmap[0], 2, proc, CSYS);
179 vmaccess(&Mbmap[0], (caddr_t)m, 2);
0ef33f87 180 for (i=0; i < CLBYTES / sizeof (struct mbuf); i++) {
80de89dc 181 m->m_off = 0;
2752c877 182 (void) m_free(m);
d80cae33
BJ
183 m++;
184 }
0ef33f87 185 (void) m_pgalloc(3);
dad64fdf
BJ
186 mbstat.m_pages = 4;
187 mbstat.m_bufs = 32;
188 mbstat.m_lowat = 16;
189 mbstat.m_hiwat = 32;
ae921915 190 { int j,k,n;
8f3e7457
BJ
191 n = 32;
192 k = n << 1;
6d19f7ef 193 if ((i = rmalloc(mbmap, n)) == 0)
ae921915 194 panic("mbinit");
8f3e7457 195 j = i<<1;
0ef33f87 196 m = cltom(i);
8f3e7457 197 /* should use vmemall sometimes */
6d19f7ef 198 if (memall(&Mbmap[j], k, proc, CSYS) == 0) {
8f3e7457
BJ
199 printf("botch\n");
200 return;
201 }
6d19f7ef 202 vmaccess(&Mbmap[j], (caddr_t)m, k);
8f3e7457
BJ
203 for (j=0; j < n; j++) {
204 m->m_off = 0;
0ef33f87
BJ
205 m->m_next = mclfree;
206 mclfree = m;
207 m += CLBYTES / sizeof (*m);
208 nmclfree++;
8f3e7457
BJ
209 }
210 }
d80cae33
BJ
211}
212
0ef33f87 213m_pgalloc(n)
d80cae33
BJ
214 register int n;
215{
216 register i, j, k;
217 register struct mbuf *m;
218 int bufs, s;
219
0ef33f87 220COUNT(M_PGALLOC);
d80cae33 221 k = n << 1;
6d19f7ef 222 if ((i = rmalloc(mbmap, n)) == 0)
d80cae33
BJ
223 return (0);
224 j = i<<1;
0ef33f87 225 m = cltom(i);
d80cae33 226 /* should use vmemall sometimes */
6d19f7ef 227 if (memall(&Mbmap[j], k, proc, CSYS) == 0)
d80cae33 228 return (0);
6d19f7ef 229 vmaccess(&Mbmap[j], (caddr_t)m, k);
d80cae33 230 bufs = n << 3;
dad64fdf 231 s = splimp();
d80cae33 232 for (j=0; j < bufs; j++) {
80de89dc 233 m->m_off = 0;
2752c877 234 (void) m_free(m);
d80cae33
BJ
235 m++;
236 }
237 splx(s);
dad64fdf 238 mbstat.m_pages += n;
d80cae33
BJ
239 return (1);
240}
241
0ef33f87
BJ
242/*ARGSUSED*/
243m_pgfree(addr, n)
244 caddr_t addr;
245 int n;
246{
247
248COUNT(M_PGFREE);
249 printf("m_pgfree %x %d\n", addr, n);
250}
251
d80cae33
BJ
252m_expand()
253{
254 register i;
d80cae33
BJ
255 int need, needp, needs;
256
257COUNT(M_EXPAND);
dad64fdf
BJ
258 needs = need = mbstat.m_hiwat - mbstat.m_bufs;
259 needp = need >> 3;
0ef33f87 260 if (m_pgalloc(needp))
d80cae33 261 return (1);
0ef33f87
BJ
262 for (i=0; i < needp; i++, need -= CLBYTES / sizeof (struct mbuf))
263 if (m_pgalloc(1) == 0)
d80cae33
BJ
264 goto steal;
265 return (need < needs);
266steal:
8f3e7457
BJ
267 /* while (not enough) ask protocols to free code */
268 ;
ae921915 269 return (0);
d80cae33
BJ
270}
271
272#ifdef notdef
273m_relse()
274{
dad64fdf 275
8f3e7457 276COUNT(M_RELSE);
d80cae33
BJ
277}
278#endif
279
8f3e7457
BJ
280m_cat(m, n)
281 register struct mbuf *m, *n;
282{
283
284 while (m->m_next)
285 m = m->m_next;
286 while (n)
287 if (m->m_off + m->m_len + n->m_len <= MMAXOFF) {
ae921915
BJ
288 bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
289 (u_int)n->m_len);
8f3e7457
BJ
290 m->m_len += n->m_len;
291 n = m_free(n);
292 } else {
293 m->m_next = n;
294 m = n;
295 n = m->m_next;
296 }
297}
298
d80cae33
BJ
299m_adj(mp, len)
300 struct mbuf *mp;
ae921915 301 register int len;
d80cae33
BJ
302{
303 register struct mbuf *m, *n;
304
305COUNT(M_ADJ);
306 if ((m = mp) == NULL)
307 return;
6d19f7ef 308 if (len >= 0) {
d80cae33 309 while (m != NULL && len > 0) {
6d19f7ef 310 if (m->m_len <= len) {
d80cae33
BJ
311 len -= m->m_len;
312 m->m_len = 0;
313 m = m->m_next;
6d19f7ef 314 } else {
d80cae33
BJ
315 m->m_len -= len;
316 m->m_off += len;
317 break;
318 }
319 }
6d19f7ef
BJ
320 } else {
321 /* a 2 pass algorithm might be better */
d80cae33
BJ
322 len = -len;
323 while (len > 0 && m->m_len != 0) {
d80cae33
BJ
324 while (m != NULL && m->m_len != 0) {
325 n = m;
326 m = m->m_next;
327 }
6d19f7ef 328 if (n->m_len <= len) {
d80cae33
BJ
329 len -= n->m_len;
330 n->m_len = 0;
331 m = mp;
6d19f7ef 332 } else {
d80cae33
BJ
333 n->m_len -= len;
334 break;
335 }
336 }
337 }
338}