error value from ATTACH; u.u_count==0 break in send
[unix-history] / usr / src / sys / kern / uipc_mbuf.c
CommitLineData
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
14m_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
26m_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
35struct mbuf *
36m_get(canwait)
37 int canwait;
38{
39 register struct mbuf *m;
40
41COUNT(M_GET);
42 MGET(m, canwait);
43 return (m);
44}
45
cc15ab5d
BJ
46struct mbuf *
47m_getclr(canwait)
48 int canwait;
49{
50 register struct mbuf *m;
51
52COUNT(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
61struct mbuf *
62m_free(m)
63 struct mbuf *m;
64{
65 register struct mbuf *n;
66
67COUNT(M_FREE);
68 MFREE(m, n);
69 return (n);
70}
71
ae921915 72/*ARGSUSED*/
d80cae33
BJ
73struct mbuf *
74m_more(type)
75 int type;
76{
d80cae33
BJ
77 register struct mbuf *m;
78
79COUNT(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 89m_freem(m)
d80cae33
BJ
90 register struct mbuf *m;
91{
92 register struct mbuf *n;
2b4b57cd 93 register int s;
d80cae33
BJ
94
95COUNT(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
106m_pullup(m, len)
107 struct mbuf *m;
108 int len;
109{
110
111 return (0);
112}
113
114struct mbuf *
115m_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;
122COUNT(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 = &top;
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);
161nospace:
162 printf("m_copy: no space\n");
163 m_freem(top);
164 return (0);
d80cae33
BJ
165}
166
6d19f7ef 167mbinit()
d80cae33
BJ
168{
169 register struct mbuf *m;
170 register i;
171
172COUNT(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
209pg_alloc(n)
210 register int n;
211{
212 register i, j, k;
213 register struct mbuf *m;
214 int bufs, s;
215
216COUNT(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
238m_expand()
239{
240 register i;
d80cae33
BJ
241 int need, needp, needs;
242
243COUNT(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);
252steal:
8f3e7457
BJ
253 /* while (not enough) ask protocols to free code */
254 ;
ae921915 255 return (0);
d80cae33
BJ
256}
257
258#ifdef notdef
259m_relse()
260{
dad64fdf 261
8f3e7457 262COUNT(M_RELSE);
d80cae33
BJ
263}
264#endif
265
8f3e7457
BJ
266m_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
285m_adj(mp, len)
286 struct mbuf *mp;
ae921915 287 register int len;
d80cae33
BJ
288{
289 register struct mbuf *m, *n;
290
291COUNT(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}