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