Commit | Line | Data |
---|---|---|
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 |
14 | m_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 |
28 | m_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 |
39 | struct mbuf * |
40 | m_get(canwait) | |
41 | int canwait; | |
42 | { | |
43 | register struct mbuf *m; | |
44 | ||
45 | COUNT(M_GET); | |
46 | MGET(m, canwait); | |
47 | return (m); | |
48 | } | |
49 | ||
cc15ab5d BJ |
50 | struct mbuf * |
51 | m_getclr(canwait) | |
52 | int canwait; | |
53 | { | |
54 | register struct mbuf *m; | |
55 | ||
56 | COUNT(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 |
65 | struct mbuf * |
66 | m_free(m) | |
67 | struct mbuf *m; | |
68 | { | |
69 | register struct mbuf *n; | |
70 | ||
71 | COUNT(M_FREE); | |
72 | MFREE(m, n); | |
73 | return (n); | |
74 | } | |
75 | ||
ae921915 | 76 | /*ARGSUSED*/ |
d80cae33 BJ |
77 | struct mbuf * |
78 | m_more(type) | |
79 | int type; | |
80 | { | |
d80cae33 BJ |
81 | register struct mbuf *m; |
82 | ||
83 | COUNT(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 | 93 | m_freem(m) |
d80cae33 BJ |
94 | register struct mbuf *m; |
95 | { | |
96 | register struct mbuf *n; | |
2b4b57cd | 97 | register int s; |
d80cae33 BJ |
98 | |
99 | COUNT(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 |
110 | m_pullup(m, len) |
111 | struct mbuf *m; | |
112 | int len; | |
113 | { | |
114 | ||
115 | return (0); | |
116 | } | |
117 | ||
118 | struct mbuf * | |
119 | m_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; | |
126 | COUNT(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 = ⊤ | |
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); | |
165 | nospace: | |
166 | printf("m_copy: no space\n"); | |
167 | m_freem(top); | |
168 | return (0); | |
d80cae33 BJ |
169 | } |
170 | ||
6d19f7ef | 171 | mbinit() |
d80cae33 BJ |
172 | { |
173 | register struct mbuf *m; | |
174 | register i; | |
175 | ||
176 | COUNT(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 | 213 | m_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 | 220 | COUNT(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*/ |
243 | m_pgfree(addr, n) | |
244 | caddr_t addr; | |
245 | int n; | |
246 | { | |
247 | ||
248 | COUNT(M_PGFREE); | |
249 | printf("m_pgfree %x %d\n", addr, n); | |
250 | } | |
251 | ||
d80cae33 BJ |
252 | m_expand() |
253 | { | |
254 | register i; | |
d80cae33 BJ |
255 | int need, needp, needs; |
256 | ||
257 | COUNT(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); | |
266 | steal: | |
8f3e7457 BJ |
267 | /* while (not enough) ask protocols to free code */ |
268 | ; | |
ae921915 | 269 | return (0); |
d80cae33 BJ |
270 | } |
271 | ||
272 | #ifdef notdef | |
273 | m_relse() | |
274 | { | |
dad64fdf | 275 | |
8f3e7457 | 276 | COUNT(M_RELSE); |
d80cae33 BJ |
277 | } |
278 | #endif | |
279 | ||
8f3e7457 BJ |
280 | m_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 |
299 | m_adj(mp, len) |
300 | struct mbuf *mp; | |
ae921915 | 301 | register int len; |
d80cae33 BJ |
302 | { |
303 | register struct mbuf *m, *n; | |
304 | ||
305 | COUNT(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 | } |