Commit | Line | Data |
---|---|---|
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 |
14 | mbinit() |
15 | { | |
16 | register struct mbuf *m; | |
17 | register i; | |
18 | ||
19 | COUNT(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; | |
27 | bad: | |
28 | panic("mbinit"); | |
29 | } | |
30 | ||
31 | caddr_t | |
32 | m_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 | ||
41 | COUNT(M_CLALLOC); | |
42 | npg = ncl * CLSIZE; | |
43 | mbx = rmalloc(mbmap, npg); | |
44 | printf("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); | |
51 | printf("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 | ||
78 | m_pgfree(addr, n) | |
79 | caddr_t addr; | |
80 | int n; | |
81 | { | |
82 | ||
83 | COUNT(M_PGFREE); | |
84 | printf("m_pgfree %x %d\n", addr, n); | |
85 | } | |
86 | ||
87 | m_expand() | |
88 | { | |
89 | ||
90 | COUNT(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); | |
96 | steal: | |
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 |
106 | m_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 |
117 | m_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 |
130 | struct mbuf * |
131 | m_get(canwait) | |
132 | int canwait; | |
133 | { | |
134 | register struct mbuf *m; | |
135 | ||
136 | COUNT(M_GET); | |
137 | MGET(m, canwait); | |
138 | return (m); | |
139 | } | |
140 | ||
cc15ab5d BJ |
141 | struct mbuf * |
142 | m_getclr(canwait) | |
143 | int canwait; | |
144 | { | |
145 | register struct mbuf *m; | |
146 | ||
147 | COUNT(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 |
156 | struct mbuf * |
157 | m_free(m) | |
158 | struct mbuf *m; | |
159 | { | |
160 | register struct mbuf *n; | |
161 | ||
162 | COUNT(M_FREE); | |
163 | MFREE(m, n); | |
164 | return (n); | |
165 | } | |
166 | ||
ae921915 | 167 | /*ARGSUSED*/ |
d80cae33 BJ |
168 | struct mbuf * |
169 | m_more(type) | |
170 | int type; | |
171 | { | |
d80cae33 BJ |
172 | register struct mbuf *m; |
173 | ||
174 | COUNT(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 | 184 | m_freem(m) |
d80cae33 BJ |
185 | register struct mbuf *m; |
186 | { | |
187 | register struct mbuf *n; | |
2b4b57cd | 188 | register int s; |
d80cae33 BJ |
189 | |
190 | COUNT(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 |
203 | struct mbuf * |
204 | m_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; | |
211 | COUNT(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 = ⊤ | |
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); | |
250 | nospace: | |
251 | printf("m_copy: no space\n"); | |
252 | m_freem(top); | |
253 | return (0); | |
d80cae33 BJ |
254 | } |
255 | ||
8f3e7457 BJ |
256 | m_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 |
275 | m_adj(mp, len) |
276 | struct mbuf *mp; | |
ae921915 | 277 | register int len; |
d80cae33 BJ |
278 | { |
279 | register struct mbuf *m, *n; | |
280 | ||
281 | COUNT(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*/ | |
317 | m_pullup(m, len) | |
318 | struct mbuf *m; | |
319 | int len; | |
320 | { | |
321 | ||
322 | return (0); | |
323 | } |