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