fix soaccept
[unix-history] / usr / src / sys / kern / uipc_mbuf.c
CommitLineData
968bc2b8 1/* uipc_mbuf.c 1.22 81/12/12 */
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
7c733634
BJ
14mbinit()
15{
7c733634
BJ
16
17COUNT(MBINIT);
18 if (m_reserve(32) == 0)
19 goto bad;
20 if (m_clalloc(4, MPG_MBUFS) == 0)
21 goto bad;
22 if (m_clalloc(32, MPG_CLUSTERS) == 0)
23 goto bad;
24 return;
25bad:
26 panic("mbinit");
27}
28
29caddr_t
30m_clalloc(ncl, how)
31 register int ncl;
32 int how;
33{
34 int npg, mbx;
35 register struct mbuf *m;
36 register int i;
37 int s;
38
39COUNT(M_CLALLOC);
40 npg = ncl * CLSIZE;
41 mbx = rmalloc(mbmap, npg);
7c733634
BJ
42 if (mbx == 0)
43 return (0);
44 m = cltom(mbx / CLSIZE);
45 if (memall(&Mbmap[mbx], ncl * CLSIZE, proc, CSYS) == 0)
46 return (0);
47 vmaccess(&Mbmap[mbx], (caddr_t)m, npg);
7c733634
BJ
48 switch (how) {
49
50 case MPG_CLUSTERS:
51 s = splimp();
52 for (i = 0; i < ncl; i++) {
53 m->m_off = 0;
54 m->m_next = mclfree;
55 mclfree = m;
56 m += CLBYTES / sizeof (*m);
57 nmclfree++;
58 }
59 mbstat.m_clusters += ncl;
60 splx(s);
61 break;
62
63 case MPG_MBUFS:
64 for (i = ncl * CLBYTES / sizeof (*m); i > 0; i--) {
65 m->m_off = 0;
66 (void) m_free(m);
67 m++;
68 }
69 mbstat.m_clusters += ncl;
d2109fac 70 break;
7c733634
BJ
71 }
72 return ((caddr_t)m);
73}
74
75m_pgfree(addr, n)
76 caddr_t addr;
77 int n;
78{
79
80COUNT(M_PGFREE);
7c733634
BJ
81}
82
83m_expand()
84{
85
86COUNT(M_EXPAND);
87 if (mbstat.m_bufs >= mbstat.m_hiwat)
88 return (0);
89 if (m_clalloc(1, MPG_MBUFS) == 0)
90 goto steal;
91 return (1);
92steal:
93 /* should ask protocols to free code */
94 return (0);
95}
96
97/* NEED SOME WAY TO RELEASE SPACE */
98
99/*
100 * Space reservation routines
101 */
196d84fd
BJ
102m_reserve(mbufs)
103 int mbufs;
e1506033
BJ
104{
105
5b3fa994 106 if (mbstat.m_lowat + (mbufs>>1) > (NMBCLUSTERS-32) * CLBYTES)
e1506033 107 return (0);
eb1bc170
BJ
108 mbstat.m_hiwat += mbufs;
109 mbstat.m_lowat = mbstat.m_hiwat >> 1;
ae921915 110 return (1);
e1506033
BJ
111}
112
196d84fd
BJ
113m_release(mbufs)
114 int mbufs;
e1506033
BJ
115{
116
eb1bc170
BJ
117 mbstat.m_hiwat -= mbufs;
118 mbstat.m_lowat = mbstat.m_hiwat >> 1;
e1506033
BJ
119}
120
7c733634
BJ
121/*
122 * Space allocation routines.
123 * These are also available as macros
124 * for critical paths.
125 */
d80cae33
BJ
126struct mbuf *
127m_get(canwait)
128 int canwait;
129{
130 register struct mbuf *m;
131
132COUNT(M_GET);
133 MGET(m, canwait);
134 return (m);
135}
136
cc15ab5d
BJ
137struct mbuf *
138m_getclr(canwait)
139 int canwait;
140{
141 register struct mbuf *m;
142
143COUNT(M_GETCLR);
ae921915 144 m = m_get(canwait);
cc15ab5d
BJ
145 if (m == 0)
146 return (0);
147 m->m_off = MMINOFF;
148 bzero(mtod(m, caddr_t), MLEN);
149 return (m);
150}
151
d80cae33
BJ
152struct mbuf *
153m_free(m)
154 struct mbuf *m;
155{
156 register struct mbuf *n;
157
158COUNT(M_FREE);
159 MFREE(m, n);
160 return (n);
161}
162
ae921915 163/*ARGSUSED*/
d80cae33
BJ
164struct mbuf *
165m_more(type)
166 int type;
167{
d80cae33
BJ
168 register struct mbuf *m;
169
170COUNT(M_MORE);
171 if (!m_expand()) {
6d19f7ef 172 mbstat.m_drops++;
d80cae33
BJ
173 return (NULL);
174 }
ae921915
BJ
175#define m_more(x) (panic("m_more"), (struct mbuf *)0)
176 MGET(m, type);
d80cae33
BJ
177 return (m);
178}
179
8f3e7457 180m_freem(m)
d80cae33
BJ
181 register struct mbuf *m;
182{
183 register struct mbuf *n;
2b4b57cd 184 register int s;
d80cae33
BJ
185
186COUNT(M_FREEM);
187 if (m == NULL)
ae921915 188 return;
dad64fdf 189 s = splimp();
d80cae33 190 do {
8f3e7457 191 MFREE(m, n);
d80cae33
BJ
192 } while (m = n);
193 splx(s);
2b4b57cd
BJ
194}
195
7c733634
BJ
196/*
197 * Mbuffer utility routines.
198 */
2b4b57cd
BJ
199struct mbuf *
200m_copy(m, off, len)
201 register struct mbuf *m;
202 int off;
203 register int len;
204{
205 register struct mbuf *n, **np;
206 struct mbuf *top, *p;
207COUNT(M_COPY);
208
209 if (len == 0)
210 return (0);
211 if (off < 0 || len < 0)
212 panic("m_copy");
213 while (off > 0) {
214 if (m == 0)
215 panic("m_copy");
216 if (off < m->m_len)
217 break;
218 off -= m->m_len;
219 m = m->m_next;
220 }
221 np = &top;
222 top = 0;
223 while (len > 0) {
224 MGET(n, 1);
225 *np = n;
226 if (n == 0)
227 goto nospace;
228 if (m == 0)
229 panic("m_copy");
230 n->m_len = MIN(len, m->m_len - off);
231 if (m->m_off > MMAXOFF) {
232 p = mtod(m, struct mbuf *);
233 n->m_off = ((int)p - (int)n) + off;
0ef33f87 234 mclrefcnt[mtocl(p)]++;
2b4b57cd
BJ
235 } else {
236 n->m_off = MMINOFF;
237 bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
238 (unsigned)n->m_len);
239 }
240 len -= n->m_len;
241 off = 0;
242 m = m->m_next;
243 np = &n->m_next;
244 }
245 return (top);
246nospace:
2b4b57cd
BJ
247 m_freem(top);
248 return (0);
d80cae33
BJ
249}
250
8f3e7457
BJ
251m_cat(m, n)
252 register struct mbuf *m, *n;
253{
254
255 while (m->m_next)
256 m = m->m_next;
257 while (n)
258 if (m->m_off + m->m_len + n->m_len <= MMAXOFF) {
ae921915
BJ
259 bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
260 (u_int)n->m_len);
8f3e7457
BJ
261 m->m_len += n->m_len;
262 n = m_free(n);
263 } else {
264 m->m_next = n;
265 m = n;
266 n = m->m_next;
267 }
268}
269
d80cae33
BJ
270m_adj(mp, len)
271 struct mbuf *mp;
ae921915 272 register int len;
d80cae33
BJ
273{
274 register struct mbuf *m, *n;
275
276COUNT(M_ADJ);
277 if ((m = mp) == NULL)
278 return;
6d19f7ef 279 if (len >= 0) {
d80cae33 280 while (m != NULL && len > 0) {
6d19f7ef 281 if (m->m_len <= len) {
d80cae33
BJ
282 len -= m->m_len;
283 m->m_len = 0;
284 m = m->m_next;
6d19f7ef 285 } else {
d80cae33
BJ
286 m->m_len -= len;
287 m->m_off += len;
288 break;
289 }
290 }
6d19f7ef
BJ
291 } else {
292 /* a 2 pass algorithm might be better */
d80cae33
BJ
293 len = -len;
294 while (len > 0 && m->m_len != 0) {
d80cae33
BJ
295 while (m != NULL && m->m_len != 0) {
296 n = m;
297 m = m->m_next;
298 }
6d19f7ef 299 if (n->m_len <= len) {
d80cae33
BJ
300 len -= n->m_len;
301 n->m_len = 0;
302 m = mp;
6d19f7ef 303 } else {
d80cae33
BJ
304 n->m_len -= len;
305 break;
306 }
307 }
308 }
309}
7c733634
BJ
310
311/*ARGSUSED*/
312m_pullup(m, len)
313 struct mbuf *m;
314 int len;
315{
316
317 return (0);
318}