]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/uipc_mbuf.c
xnu-517.3.15.tar.gz
[apple/xnu.git] / bsd / kern / uipc_mbuf.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
26 /*
27 * Copyright (c) 1982, 1986, 1988, 1991, 1993
28 * The Regents of the University of California. All rights reserved.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by the University of
41 * California, Berkeley and its contributors.
42 * 4. Neither the name of the University nor the names of its contributors
43 * may be used to endorse or promote products derived from this software
44 * without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 *
58 * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
59 */
60 /* HISTORY
61 *
62 * 10/15/97 Annette DeSchon (deschon@apple.com)
63 * Fixed bug in which all cluster mbufs were broken up
64 * into regular mbufs: Some clusters are now reserved.
65 * When a cluster is needed, regular mbufs are no longer
66 * used. (Radar 1683621)
67 * 20-May-95 Mac Gillon (mgillon) at NeXT
68 * New version based on 4.4
69 */
70
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/malloc.h>
74 #include <sys/mbuf.h>
75 #include <sys/kernel.h>
76 #include <sys/syslog.h>
77 #include <sys/protosw.h>
78 #include <sys/domain.h>
79 #include <net/netisr.h>
80
81 #include <kern/queue.h>
82 #include <kern/kern_types.h>
83 #include <kern/sched_prim.h>
84
85 #include <IOKit/IOMapper.h>
86
87 #define _MCLREF(p) (++mclrefcnt[mtocl(p)])
88 #define _MCLUNREF(p) (--mclrefcnt[mtocl(p)] == 0)
89 #define _M_CLEAR_PKTHDR(mbuf_ptr) (mbuf_ptr)->m_pkthdr.rcvif = NULL; \
90 (mbuf_ptr)->m_pkthdr.len = 0; \
91 (mbuf_ptr)->m_pkthdr.header = NULL; \
92 (mbuf_ptr)->m_pkthdr.csum_flags = 0; \
93 (mbuf_ptr)->m_pkthdr.csum_data = 0; \
94 (mbuf_ptr)->m_pkthdr.aux = (struct mbuf*)NULL; \
95 (mbuf_ptr)->m_pkthdr.reserved_1 = 0; \
96 (mbuf_ptr)->m_pkthdr.vlan_tag = 0; \
97 (mbuf_ptr)->m_pkthdr.reserved2 = NULL;
98
99 extern pmap_t kernel_pmap; /* The kernel's pmap */
100 /* kernel translater */
101 extern ppnum_t pmap_find_phys(pmap_t pmap, addr64_t va);
102
103 decl_simple_lock_data(, mbuf_slock);
104 struct mbuf *mfree; /* mbuf free list */
105 struct mbuf *mfreelater; /* mbuf deallocation list */
106 extern vm_map_t mb_map; /* special map */
107 int m_want; /* sleepers on mbufs */
108 extern int nmbclusters; /* max number of mapped clusters */
109 short *mclrefcnt; /* mapped cluster reference counts */
110 int *mcl_paddr;
111 static ppnum_t mcl_paddr_base; /* Handle returned by IOMapper::iovmAlloc() */
112 union mcluster *mclfree; /* mapped cluster free list */
113 int max_linkhdr; /* largest link-level header */
114 int max_protohdr; /* largest protocol header */
115 int max_hdr; /* largest link+protocol header */
116 int max_datalen; /* MHLEN - max_hdr */
117 struct mbstat mbstat; /* statistics */
118 union mcluster *mbutl; /* first mapped cluster address */
119 union mcluster *embutl; /* ending virtual address of mclusters */
120
121 static int nclpp; /* # clusters per physical page */
122 static char mbfail[] = "mbuf not mapped";
123
124 static int m_howmany();
125
126 /* The number of cluster mbufs that are allocated, to start. */
127 #define MINCL max(16, 2)
128
129 static int mbuf_expand_thread_wakeup = 0;
130 static int mbuf_expand_mcl = 0;
131 static int mbuf_expand_thread_initialized = 0;
132
133 static void mbuf_expand_thread_init(void);
134
135 #if 0
136 static int mfree_munge = 0;
137 #if 0
138 #define _MFREE_MUNGE(m) { \
139 if (mfree_munge) \
140 { int i; \
141 vm_offset_t *element = (vm_offset_t *)(m); \
142 for (i = 0; \
143 i < sizeof(struct mbuf)/sizeof(vm_offset_t); \
144 i++) \
145 (element)[i] = 0xdeadbeef; \
146 } \
147 }
148 #else
149 void
150 munge_mbuf(struct mbuf *m)
151 {
152 int i;
153 vm_offset_t *element = (vm_offset_t *)(m);
154 for (i = 0;
155 i < sizeof(struct mbuf)/sizeof(vm_offset_t);
156 i++)
157 (element)[i] = 0xdeadbeef;
158 }
159 #define _MFREE_MUNGE(m) { \
160 if (mfree_munge) \
161 munge_mbuf(m); \
162 }
163 #endif
164 #else
165 #define _MFREE_MUNGE(m)
166 #endif
167
168
169 #define _MINTGET(m, type) { \
170 MBUF_LOCK(); \
171 if (((m) = mfree) != 0) { \
172 MCHECK(m); \
173 ++mclrefcnt[mtocl(m)]; \
174 mbstat.m_mtypes[MT_FREE]--; \
175 mbstat.m_mtypes[(type)]++; \
176 mfree = (m)->m_next; \
177 } \
178 MBUF_UNLOCK(); \
179 }
180
181
182 void
183 mbinit()
184 {
185 int s,m;
186 int initmcl = 32;
187 int mcl_pages;
188
189 if (nclpp)
190 return;
191 nclpp = round_page_32(MCLBYTES) / MCLBYTES; /* see mbufgc() */
192 if (nclpp < 1) nclpp = 1;
193 MBUF_LOCKINIT();
194 // NETISR_LOCKINIT();
195
196 mbstat.m_msize = MSIZE;
197 mbstat.m_mclbytes = MCLBYTES;
198 mbstat.m_minclsize = MINCLSIZE;
199 mbstat.m_mlen = MLEN;
200 mbstat.m_mhlen = MHLEN;
201
202 if (nmbclusters == 0)
203 nmbclusters = NMBCLUSTERS;
204 MALLOC(mclrefcnt, short *, nmbclusters * sizeof (short),
205 M_TEMP, M_WAITOK);
206 if (mclrefcnt == 0)
207 panic("mbinit");
208 for (m = 0; m < nmbclusters; m++)
209 mclrefcnt[m] = -1;
210
211 /* Calculate the number of pages assigned to the cluster pool */
212 mcl_pages = nmbclusters/(PAGE_SIZE/CLBYTES);
213 MALLOC(mcl_paddr, int *, mcl_pages * sizeof(int), M_TEMP, M_WAITOK);
214 if (mcl_paddr == 0)
215 panic("mbinit1");
216 /* Register with the I/O Bus mapper */
217 mcl_paddr_base = IOMapperIOVMAlloc(mcl_pages);
218 bzero((char *)mcl_paddr, mcl_pages * sizeof(int));
219
220 embutl = (union mcluster *)((unsigned char *)mbutl + (nmbclusters * MCLBYTES));
221
222 PE_parse_boot_arg("initmcl", &initmcl);
223
224 if (m_clalloc(max(PAGE_SIZE/CLBYTES, 1) * initmcl, M_WAIT) == 0)
225 goto bad;
226 MBUF_UNLOCK();
227
228 (void) kernel_thread(kernel_task, mbuf_expand_thread_init);
229
230 return;
231 bad:
232 panic("mbinit");
233 }
234
235 /*
236 * Allocate some number of mbuf clusters
237 * and place on cluster free list.
238 */
239 /* ARGSUSED */
240 m_clalloc(ncl, nowait)
241 register int ncl;
242 int nowait;
243 {
244 register union mcluster *mcl;
245 register int i;
246 vm_size_t size;
247 static char doing_alloc;
248
249 /*
250 * Honor the caller's wish to block or not block.
251 * We have a way to grow the pool asynchronously,
252 * by kicking the dlil_input_thread.
253 */
254 if ((i = m_howmany()) <= 0)
255 goto out;
256
257 if ((nowait == M_DONTWAIT))
258 goto out;
259
260 if (ncl < i)
261 ncl = i;
262 size = round_page_32(ncl * MCLBYTES);
263 mcl = (union mcluster *)kmem_mb_alloc(mb_map, size);
264
265 if (mcl == 0 && ncl > 1) {
266 size = round_page_32(MCLBYTES); /* Try for 1 if failed */
267 mcl = (union mcluster *)kmem_mb_alloc(mb_map, size);
268 }
269
270 if (mcl) {
271 MBUF_LOCK();
272 ncl = size / MCLBYTES;
273 for (i = 0; i < ncl; i++) {
274 if (++mclrefcnt[mtocl(mcl)] != 0)
275 panic("m_clalloc already there");
276 if (((int)mcl & PAGE_MASK) == 0) {
277 ppnum_t offset = ((char *)mcl - (char *)mbutl)/PAGE_SIZE;
278 ppnum_t new_page = pmap_find_phys(kernel_pmap, (vm_address_t) mcl);
279
280 /*
281 * In the case of no mapper being available
282 * the following code nops and returns the
283 * input page, if there is a mapper the I/O
284 * page appropriate is returned.
285 */
286 new_page = IOMapperInsertPage(mcl_paddr_base, offset, new_page);
287 mcl_paddr[offset] = new_page << 12;
288 }
289
290 mcl->mcl_next = mclfree;
291 mclfree = mcl++;
292 }
293 mbstat.m_clfree += ncl;
294 mbstat.m_clusters += ncl;
295 return (ncl);
296 } /* else ... */
297 out:
298 MBUF_LOCK();
299
300 /*
301 * When non-blocking we kick the dlil thread if we havve to grow the
302 * pool or if the number of free clusters is less than requested.
303 */
304 if ((nowait == M_DONTWAIT) && (i > 0 || ncl >= mbstat.m_clfree)) {
305 mbuf_expand_mcl = 1;
306 if (mbuf_expand_thread_initialized)
307 wakeup((caddr_t)&mbuf_expand_thread_wakeup);
308 }
309
310 if (mbstat.m_clfree >= ncl)
311 return 1;
312
313 return 0;
314 }
315
316 /*
317 * Add more free mbufs by cutting up a cluster.
318 */
319 m_expand(canwait)
320 int canwait;
321 {
322 register caddr_t mcl;
323
324 if (mbstat.m_clfree < (mbstat.m_clusters >> 4))
325 /* 1/16th of the total number of cluster mbufs allocated is
326 reserved for large packets. The number reserved must
327 always be < 1/2, or future allocation will be prevented.
328 */
329 return 0;
330
331 MCLALLOC(mcl, canwait);
332 if (mcl) {
333 register struct mbuf *m = (struct mbuf *)mcl;
334 register int i = NMBPCL;
335 MBUF_LOCK();
336 mbstat.m_mtypes[MT_FREE] += i;
337 mbstat.m_mbufs += i;
338 while (i--) {
339 _MFREE_MUNGE(m);
340 m->m_type = MT_FREE;
341 m->m_next = mfree;
342 mfree = m++;
343 }
344 i = m_want;
345 m_want = 0;
346 MBUF_UNLOCK();
347 if (i) wakeup((caddr_t)&mfree);
348 return 1;
349 }
350 return 0;
351 }
352
353 /*
354 * When MGET failes, ask protocols to free space when short of memory,
355 * then re-attempt to allocate an mbuf.
356 */
357 struct mbuf *
358 m_retry(canwait, type)
359 int canwait, type;
360 {
361 register struct mbuf *m;
362 int wait, s;
363 funnel_t * fnl;
364 int fnl_switch = 0;
365 boolean_t funnel_state;
366
367 for (;;) {
368 (void) m_expand(canwait);
369 _MINTGET(m, type);
370 if (m) {
371 (m)->m_next = (m)->m_nextpkt = 0;
372 (m)->m_type = (type);
373 (m)->m_data = (m)->m_dat;
374 (m)->m_flags = 0;
375 }
376 if (m || canwait == M_DONTWAIT)
377 break;
378 MBUF_LOCK();
379 wait = m_want++;
380 mbuf_expand_mcl = 1;
381 if (wait == 0)
382 mbstat.m_drain++;
383 else
384 mbstat.m_wait++;
385 MBUF_UNLOCK();
386
387 if (mbuf_expand_thread_initialized)
388 wakeup((caddr_t)&mbuf_expand_thread_wakeup);
389
390 /*
391 * Need to be inside network funnel for m_reclaim because it calls into the
392 * socket domains and tsleep end-up calling splhigh
393 */
394 fnl = thread_funnel_get();
395 if (wait == 0 && fnl == network_flock) {
396 m_reclaim();
397 } else if (fnl != THR_FUNNEL_NULL) {
398 /* Sleep with a small timeout as insurance */
399 (void) tsleep((caddr_t)&mfree, PZERO-1, "m_retry", hz);
400 } else {
401 /* We are called from a non-BSD context: use mach primitives */
402 u_int64_t abstime = 0;
403
404 assert_wait((event_t)&mfree, THREAD_UNINT);
405 clock_interval_to_deadline(hz, NSEC_PER_SEC / hz, &abstime);
406 thread_set_timer_deadline(abstime);
407 if (thread_block(THREAD_CONTINUE_NULL) != THREAD_TIMED_OUT)
408 thread_cancel_timer();
409 }
410 }
411 if (m == 0)
412 mbstat.m_drops++;
413 return (m);
414 }
415
416 /*
417 * As above; retry an MGETHDR.
418 */
419 struct mbuf *
420 m_retryhdr(canwait, type)
421 int canwait, type;
422 {
423 register struct mbuf *m;
424
425 if (m = m_retry(canwait, type)) {
426 m->m_flags |= M_PKTHDR;
427 m->m_data = m->m_pktdat;
428 _M_CLEAR_PKTHDR(m);
429 }
430 return (m);
431 }
432
433 m_reclaim()
434 {
435 register struct domain *dp;
436 register struct protosw *pr;
437
438 for (dp = domains; dp; dp = dp->dom_next)
439 for (pr = dp->dom_protosw; pr; pr = pr->pr_next)
440 if (pr->pr_drain)
441 (*pr->pr_drain)();
442 mbstat.m_drain++;
443 }
444
445 /*
446 * Space allocation routines.
447 * These are also available as macros
448 * for critical paths.
449 */
450 struct mbuf *
451 m_get(nowait, type)
452 int nowait, type;
453 {
454 register struct mbuf *m;
455
456 _MINTGET(m, type);
457 if (m) {
458 m->m_next = m->m_nextpkt = 0;
459 m->m_type = type;
460 m->m_data = m->m_dat;
461 m->m_flags = 0;
462 } else
463 (m) = m_retry(nowait, type);
464
465 return (m);
466 }
467
468 struct mbuf *
469 m_gethdr(nowait, type)
470 int nowait, type;
471 {
472 register struct mbuf *m;
473
474 _MINTGET(m, type);
475 if (m) {
476 m->m_next = m->m_nextpkt = 0;
477 m->m_type = type;
478 m->m_data = m->m_pktdat;
479 m->m_flags = M_PKTHDR;
480 _M_CLEAR_PKTHDR(m)
481 } else
482 m = m_retryhdr(nowait, type);
483
484 return m;
485 }
486
487 struct mbuf *
488 m_getclr(nowait, type)
489 int nowait, type;
490 {
491 register struct mbuf *m;
492
493 MGET(m, nowait, type);
494 if (m == 0)
495 return (0);
496 bzero(mtod(m, caddr_t), MLEN);
497 return (m);
498 }
499
500 struct mbuf *
501 m_free(m)
502 struct mbuf *m;
503 {
504 struct mbuf *n = m->m_next;
505 int i, s;
506
507 if (m->m_type == MT_FREE)
508 panic("freeing free mbuf");
509
510 /* Free the aux data if there is any */
511 if ((m->m_flags & M_PKTHDR) && m->m_pkthdr.aux)
512 {
513 m_freem(m->m_pkthdr.aux);
514 }
515
516 MBUF_LOCK();
517 if ((m->m_flags & M_EXT))
518 {
519 if (MCLHASREFERENCE(m)) {
520 remque((queue_t)&m->m_ext.ext_refs);
521 } else if (m->m_ext.ext_free == NULL) {
522 union mcluster *mcl= (union mcluster *)m->m_ext.ext_buf;
523 if (_MCLUNREF(mcl)) {
524 mcl->mcl_next = mclfree;
525 mclfree = mcl;
526 ++mbstat.m_clfree;
527 }
528 #ifdef COMMENT_OUT
529 /* *** Since m_split() increments "mclrefcnt[mtocl(m->m_ext.ext_buf)]",
530 and AppleTalk ADSP uses m_split(), this incorrect sanity check
531 caused a panic.
532 *** */
533 else /* sanity check - not referenced this way */
534 panic("m_free m_ext cluster not free");
535 #endif
536 } else {
537 (*(m->m_ext.ext_free))(m->m_ext.ext_buf,
538 m->m_ext.ext_size, m->m_ext.ext_arg);
539 }
540 }
541 mbstat.m_mtypes[m->m_type]--;
542 (void) _MCLUNREF(m);
543 _MFREE_MUNGE(m);
544 m->m_type = MT_FREE;
545 mbstat.m_mtypes[m->m_type]++;
546 m->m_flags = 0;
547 m->m_next = mfree;
548 m->m_len = 0;
549 mfree = m;
550 i = m_want;
551 m_want = 0;
552 MBUF_UNLOCK();
553 if (i) wakeup((caddr_t)&mfree);
554 return (n);
555 }
556
557 /* m_mclget() add an mbuf cluster to a normal mbuf */
558 struct mbuf *
559 m_mclget(m, nowait)
560 struct mbuf *m;
561 int nowait;
562 {
563 MCLALLOC(m->m_ext.ext_buf, nowait);
564 if (m->m_ext.ext_buf) {
565 m->m_data = m->m_ext.ext_buf;
566 m->m_flags |= M_EXT;
567 m->m_ext.ext_size = MCLBYTES;
568 m->m_ext.ext_free = 0;
569 m->m_ext.ext_refs.forward = m->m_ext.ext_refs.backward =
570 &m->m_ext.ext_refs;
571 }
572
573 return m;
574 }
575
576 /* m_mclalloc() allocate an mbuf cluster */
577 caddr_t
578 m_mclalloc( nowait)
579 int nowait;
580 {
581 caddr_t p;
582
583 (void)m_clalloc(1, nowait);
584 if ((p = (caddr_t)mclfree)) {
585 ++mclrefcnt[mtocl(p)];
586 mbstat.m_clfree--;
587 mclfree = ((union mcluster *)p)->mcl_next;
588 } else {
589 mbstat.m_drops++;
590 }
591 MBUF_UNLOCK();
592
593 return p;
594 }
595
596 /* m_mclfree() releases a reference to a cluster allocated by MCLALLOC,
597 * freeing the cluster if the reference count has reached 0. */
598 void
599 m_mclfree(p)
600 caddr_t p;
601 {
602 MBUF_LOCK();
603 if (--mclrefcnt[mtocl(p)] == 0) {
604 ((union mcluster *)(p))->mcl_next = mclfree;
605 mclfree = (union mcluster *)(p);
606 mbstat.m_clfree++;
607 }
608 MBUF_UNLOCK();
609 }
610
611 /* mcl_hasreference() checks if a cluster of an mbuf is referenced by another mbuf */
612 int
613 m_mclhasreference(m)
614 struct mbuf *m;
615 {
616 return (m->m_ext.ext_refs.forward != &(m->m_ext.ext_refs));
617 }
618
619 /* */
620 void
621 m_copy_pkthdr(to, from)
622 struct mbuf *to, *from;
623 {
624 to->m_pkthdr = from->m_pkthdr;
625 from->m_pkthdr.aux = (struct mbuf *)NULL;
626 to->m_flags = from->m_flags & M_COPYFLAGS;
627 to->m_data = (to)->m_pktdat;
628 }
629
630 /* Best effort to get a mbuf cluster + pkthdr under one lock.
631 * If we don't have them avail, just bail out and use the regular
632 * path.
633 * Used by drivers to allocated packets on receive ring.
634 */
635 struct mbuf *
636 m_getpacket(void)
637 {
638 struct mbuf *m;
639 m_clalloc(1, M_DONTWAIT); /* takes the MBUF_LOCK, but doesn't release it... */
640 if ((mfree != 0) && (mclfree != 0)) { /* mbuf + cluster are available */
641 m = mfree;
642 mfree = m->m_next;
643 MCHECK(m);
644 ++mclrefcnt[mtocl(m)];
645 mbstat.m_mtypes[MT_FREE]--;
646 mbstat.m_mtypes[MT_DATA]++;
647 m->m_ext.ext_buf = (caddr_t)mclfree; /* get the cluster */
648 ++mclrefcnt[mtocl(m->m_ext.ext_buf)];
649 mbstat.m_clfree--;
650 mclfree = ((union mcluster *)(m->m_ext.ext_buf))->mcl_next;
651
652 m->m_next = m->m_nextpkt = 0;
653 m->m_type = MT_DATA;
654 m->m_data = m->m_ext.ext_buf;
655 m->m_flags = M_PKTHDR | M_EXT;
656 _M_CLEAR_PKTHDR(m)
657 m->m_ext.ext_free = 0;
658 m->m_ext.ext_size = MCLBYTES;
659 m->m_ext.ext_refs.forward = m->m_ext.ext_refs.backward =
660 &m->m_ext.ext_refs;
661 MBUF_UNLOCK();
662 }
663 else { /* slow path: either mbuf or cluster need to be allocated anyway */
664 MBUF_UNLOCK();
665
666 MGETHDR(m, M_WAITOK, MT_DATA );
667
668 if ( m == 0 )
669 return (NULL);
670
671 MCLGET( m, M_WAITOK );
672 if ( ( m->m_flags & M_EXT ) == 0 )
673 {
674 m_free(m); m = 0;
675 }
676 }
677 return (m);
678 }
679
680
681 /*
682 * return a list of mbuf hdrs that point to clusters...
683 * try for num_needed, if this can't be met, return whatever
684 * number were available... set up the first num_with_pkthdrs
685 * with mbuf hdrs configured as packet headers... these are
686 * chained on the m_nextpkt field... any packets requested beyond
687 * this are chained onto the last packet header's m_next field.
688 */
689 struct mbuf *
690 m_getpackets(int num_needed, int num_with_pkthdrs, int how)
691 {
692 struct mbuf *m;
693 struct mbuf **np, *top;
694
695 top = NULL;
696 np = &top;
697
698 m_clalloc(num_needed, how); /* takes the MBUF_LOCK, but doesn't release it... */
699
700 while (num_needed--) {
701 if (mfree && mclfree) { /* mbuf + cluster are available */
702 m = mfree;
703 MCHECK(m);
704 mfree = m->m_next;
705 ++mclrefcnt[mtocl(m)];
706 mbstat.m_mtypes[MT_FREE]--;
707 mbstat.m_mtypes[MT_DATA]++;
708 m->m_ext.ext_buf = (caddr_t)mclfree; /* get the cluster */
709 ++mclrefcnt[mtocl(m->m_ext.ext_buf)];
710 mbstat.m_clfree--;
711 mclfree = ((union mcluster *)(m->m_ext.ext_buf))->mcl_next;
712
713 m->m_next = m->m_nextpkt = 0;
714 m->m_type = MT_DATA;
715 m->m_data = m->m_ext.ext_buf;
716 m->m_ext.ext_free = 0;
717 m->m_ext.ext_size = MCLBYTES;
718 m->m_ext.ext_refs.forward = m->m_ext.ext_refs.backward = &m->m_ext.ext_refs;
719
720 if (num_with_pkthdrs == 0)
721 m->m_flags = M_EXT;
722 else {
723 m->m_flags = M_PKTHDR | M_EXT;
724 _M_CLEAR_PKTHDR(m);
725
726 num_with_pkthdrs--;
727 }
728
729 } else {
730
731 MBUF_UNLOCK();
732
733 if (num_with_pkthdrs == 0) {
734 MGET(m, how, MT_DATA );
735 } else {
736 MGETHDR(m, how, MT_DATA);
737
738 num_with_pkthdrs--;
739 }
740 if (m == 0)
741 return(top);
742
743 MCLGET(m, how);
744 if ((m->m_flags & M_EXT) == 0) {
745 m_free(m);
746 return(top);
747 }
748 MBUF_LOCK();
749 }
750 *np = m;
751
752 if (num_with_pkthdrs)
753 np = &m->m_nextpkt;
754 else
755 np = &m->m_next;
756 }
757 MBUF_UNLOCK();
758
759 return (top);
760 }
761
762
763 /*
764 * return a list of mbuf hdrs set up as packet hdrs
765 * chained together on the m_nextpkt field
766 */
767 struct mbuf *
768 m_getpackethdrs(int num_needed, int how)
769 {
770 struct mbuf *m;
771 struct mbuf **np, *top;
772
773 top = NULL;
774 np = &top;
775
776 MBUF_LOCK();
777
778 while (num_needed--) {
779 if (m = mfree) { /* mbufs are available */
780 MCHECK(m);
781 mfree = m->m_next;
782 ++mclrefcnt[mtocl(m)];
783 mbstat.m_mtypes[MT_FREE]--;
784 mbstat.m_mtypes[MT_DATA]++;
785
786 m->m_next = m->m_nextpkt = 0;
787 m->m_type = MT_DATA;
788 m->m_flags = M_PKTHDR;
789 m->m_data = m->m_pktdat;
790 _M_CLEAR_PKTHDR(m);
791
792 } else {
793
794 MBUF_UNLOCK();
795
796 m = m_retryhdr(how, MT_DATA);
797
798 if (m == 0)
799 return(top);
800
801 MBUF_LOCK();
802 }
803 *np = m;
804 np = &m->m_nextpkt;
805 }
806 MBUF_UNLOCK();
807
808 return (top);
809 }
810
811
812 /* free and mbuf list (m_nextpkt) while following m_next under one lock.
813 * returns the count for mbufs packets freed. Used by the drivers.
814 */
815 int
816 m_freem_list(m)
817 struct mbuf *m;
818 {
819 struct mbuf *nextpkt;
820 int i, count=0;
821
822 MBUF_LOCK();
823
824 while (m) {
825 if (m)
826 nextpkt = m->m_nextpkt; /* chain of linked mbufs from driver */
827 else
828 nextpkt = 0;
829
830 count++;
831
832 while (m) { /* free the mbuf chain (like mfreem) */
833
834 struct mbuf *n;
835
836 /* Free the aux data if there is any */
837 if ((m->m_flags & M_PKTHDR) && m->m_pkthdr.aux) {
838 /*
839 * Treat the current m as the nextpkt and set m
840 * to the aux data. Preserve nextpkt in m->m_nextpkt.
841 * This lets us free the aux data in this loop
842 * without having to call m_freem recursively,
843 * which wouldn't work because we've still got
844 * the lock.
845 */
846 m->m_nextpkt = nextpkt;
847 nextpkt = m;
848 m = nextpkt->m_pkthdr.aux;
849 nextpkt->m_pkthdr.aux = NULL;
850 }
851
852 n = m->m_next;
853
854 if (n && n->m_nextpkt)
855 panic("m_freem_list: m_nextpkt of m_next != NULL");
856 if (m->m_type == MT_FREE)
857 panic("freeing free mbuf");
858
859 if (m->m_flags & M_EXT) {
860 if (MCLHASREFERENCE(m)) {
861 remque((queue_t)&m->m_ext.ext_refs);
862 } else if (m->m_ext.ext_free == NULL) {
863 union mcluster *mcl= (union mcluster *)m->m_ext.ext_buf;
864 if (_MCLUNREF(mcl)) {
865 mcl->mcl_next = mclfree;
866 mclfree = mcl;
867 ++mbstat.m_clfree;
868 }
869 } else {
870 (*(m->m_ext.ext_free))(m->m_ext.ext_buf,
871 m->m_ext.ext_size, m->m_ext.ext_arg);
872 }
873 }
874 mbstat.m_mtypes[m->m_type]--;
875 (void) _MCLUNREF(m);
876 _MFREE_MUNGE(m);
877 mbstat.m_mtypes[MT_FREE]++;
878 m->m_type = MT_FREE;
879 m->m_flags = 0;
880 m->m_len = 0;
881 m->m_next = mfree;
882 mfree = m;
883 m = n;
884 }
885 m = nextpkt; /* bump m with saved nextpkt if any */
886 }
887 if (i = m_want)
888 m_want = 0;
889
890 MBUF_UNLOCK();
891
892 if (i)
893 wakeup((caddr_t)&mfree);
894
895 return (count);
896 }
897
898 void
899 m_freem(m)
900 register struct mbuf *m;
901 {
902 while (m)
903 m = m_free(m);
904 }
905
906 /*
907 * Mbuffer utility routines.
908 */
909 /*
910 * Compute the amount of space available
911 * before the current start of data in an mbuf.
912 */
913 m_leadingspace(m)
914 register struct mbuf *m;
915 {
916 if (m->m_flags & M_EXT) {
917 if (MCLHASREFERENCE(m))
918 return(0);
919 return (m->m_data - m->m_ext.ext_buf);
920 }
921 if (m->m_flags & M_PKTHDR)
922 return (m->m_data - m->m_pktdat);
923 return (m->m_data - m->m_dat);
924 }
925
926 /*
927 * Compute the amount of space available
928 * after the end of data in an mbuf.
929 */
930 m_trailingspace(m)
931 register struct mbuf *m;
932 {
933 if (m->m_flags & M_EXT) {
934 if (MCLHASREFERENCE(m))
935 return(0);
936 return (m->m_ext.ext_buf + m->m_ext.ext_size -
937 (m->m_data + m->m_len));
938 }
939 return (&m->m_dat[MLEN] - (m->m_data + m->m_len));
940 }
941
942 /*
943 * Lesser-used path for M_PREPEND:
944 * allocate new mbuf to prepend to chain,
945 * copy junk along.
946 * Does not adjust packet header length.
947 */
948 struct mbuf *
949 m_prepend(m, len, how)
950 register struct mbuf *m;
951 int len, how;
952 {
953 struct mbuf *mn;
954
955 MGET(mn, how, m->m_type);
956 if (mn == (struct mbuf *)NULL) {
957 m_freem(m);
958 return ((struct mbuf *)NULL);
959 }
960 if (m->m_flags & M_PKTHDR) {
961 M_COPY_PKTHDR(mn, m);
962 m->m_flags &= ~M_PKTHDR;
963 }
964 mn->m_next = m;
965 m = mn;
966 if (len < MHLEN)
967 MH_ALIGN(m, len);
968 m->m_len = len;
969 return (m);
970 }
971
972 /*
973 * Replacement for old M_PREPEND macro:
974 * allocate new mbuf to prepend to chain,
975 * copy junk along, and adjust length.
976 *
977 */
978 struct mbuf *
979 m_prepend_2(m, len, how)
980 register struct mbuf *m;
981 int len, how;
982 {
983 if (M_LEADINGSPACE(m) >= len) {
984 m->m_data -= len;
985 m->m_len += len;
986 } else {
987 m = m_prepend(m, len, how);
988 }
989 if ((m) && (m->m_flags & M_PKTHDR))
990 m->m_pkthdr.len += len;
991 return (m);
992 }
993
994 /*
995 * Make a copy of an mbuf chain starting "off0" bytes from the beginning,
996 * continuing for "len" bytes. If len is M_COPYALL, copy to end of mbuf.
997 * The wait parameter is a choice of M_WAIT/M_DONTWAIT from caller.
998 */
999 int MCFail;
1000
1001 struct mbuf *
1002 m_copym(m, off0, len, wait)
1003 register struct mbuf *m;
1004 int off0, wait;
1005 register int len;
1006 {
1007 register struct mbuf *n, **np;
1008 register int off = off0;
1009 struct mbuf *top;
1010 int copyhdr = 0;
1011
1012 if (off < 0 || len < 0)
1013 panic("m_copym");
1014 if (off == 0 && m->m_flags & M_PKTHDR)
1015 copyhdr = 1;
1016
1017 while (off >= m->m_len) {
1018 if (m == 0)
1019 panic("m_copym");
1020 off -= m->m_len;
1021 m = m->m_next;
1022 }
1023 np = &top;
1024 top = 0;
1025
1026 MBUF_LOCK();
1027
1028 while (len > 0) {
1029 if (m == 0) {
1030 if (len != M_COPYALL)
1031 panic("m_copym");
1032 break;
1033 }
1034 if (n = mfree) {
1035 MCHECK(n);
1036 ++mclrefcnt[mtocl(n)];
1037 mbstat.m_mtypes[MT_FREE]--;
1038 mbstat.m_mtypes[m->m_type]++;
1039 mfree = n->m_next;
1040 n->m_next = n->m_nextpkt = 0;
1041 n->m_type = m->m_type;
1042 n->m_data = n->m_dat;
1043 n->m_flags = 0;
1044 } else {
1045 MBUF_UNLOCK();
1046 n = m_retry(wait, m->m_type);
1047 MBUF_LOCK();
1048 }
1049 *np = n;
1050
1051 if (n == 0)
1052 goto nospace;
1053 if (copyhdr) {
1054 M_COPY_PKTHDR(n, m);
1055 if (len == M_COPYALL)
1056 n->m_pkthdr.len -= off0;
1057 else
1058 n->m_pkthdr.len = len;
1059 copyhdr = 0;
1060 }
1061 if (len == M_COPYALL) {
1062 if (min(len, (m->m_len - off)) == len) {
1063 printf("m->m_len %d - off %d = %d, %d\n",
1064 m->m_len, off, m->m_len - off,
1065 min(len, (m->m_len - off)));
1066 }
1067 }
1068 n->m_len = min(len, (m->m_len - off));
1069 if (n->m_len == M_COPYALL) {
1070 printf("n->m_len == M_COPYALL, fixing\n");
1071 n->m_len = MHLEN;
1072 }
1073 if (m->m_flags & M_EXT) {
1074 n->m_ext = m->m_ext;
1075 insque((queue_t)&n->m_ext.ext_refs, (queue_t)&m->m_ext.ext_refs);
1076 n->m_data = m->m_data + off;
1077 n->m_flags |= M_EXT;
1078 } else {
1079 bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
1080 (unsigned)n->m_len);
1081 }
1082 if (len != M_COPYALL)
1083 len -= n->m_len;
1084 off = 0;
1085 m = m->m_next;
1086 np = &n->m_next;
1087 }
1088 MBUF_UNLOCK();
1089
1090 if (top == 0)
1091 MCFail++;
1092
1093 return (top);
1094 nospace:
1095 MBUF_UNLOCK();
1096
1097 m_freem(top);
1098 MCFail++;
1099 return (0);
1100 }
1101
1102
1103 /*
1104 * equivilent to m_copym except that all necessary
1105 * mbuf hdrs are allocated within this routine
1106 * also, the last mbuf and offset accessed are passed
1107 * out and can be passed back in to avoid having to
1108 * rescan the entire mbuf list (normally hung off of the socket)
1109 */
1110 struct mbuf *
1111 m_copym_with_hdrs(m, off0, len, wait, m_last, m_off)
1112 register struct mbuf *m;
1113 int off0, wait;
1114 register int len;
1115 struct mbuf **m_last;
1116 int *m_off;
1117 {
1118 register struct mbuf *n, **np;
1119 register int off = off0;
1120 struct mbuf *top = 0;
1121 int copyhdr = 0;
1122 int type;
1123
1124 if (off == 0 && m->m_flags & M_PKTHDR)
1125 copyhdr = 1;
1126
1127 if (*m_last) {
1128 m = *m_last;
1129 off = *m_off;
1130 } else {
1131 while (off >= m->m_len) {
1132 off -= m->m_len;
1133 m = m->m_next;
1134 }
1135 }
1136 MBUF_LOCK();
1137
1138 while (len > 0) {
1139 if (top == 0)
1140 type = MT_HEADER;
1141 else {
1142 if (m == 0)
1143 panic("m_gethdr_and_copym");
1144 type = m->m_type;
1145 }
1146 if (n = mfree) {
1147 MCHECK(n);
1148 ++mclrefcnt[mtocl(n)];
1149 mbstat.m_mtypes[MT_FREE]--;
1150 mbstat.m_mtypes[type]++;
1151 mfree = n->m_next;
1152 n->m_next = n->m_nextpkt = 0;
1153 n->m_type = type;
1154
1155 if (top) {
1156 n->m_data = n->m_dat;
1157 n->m_flags = 0;
1158 } else {
1159 n->m_data = n->m_pktdat;
1160 n->m_flags = M_PKTHDR;
1161 _M_CLEAR_PKTHDR(n);
1162 }
1163 } else {
1164 MBUF_UNLOCK();
1165 if (top)
1166 n = m_retry(wait, type);
1167 else
1168 n = m_retryhdr(wait, type);
1169 MBUF_LOCK();
1170 }
1171 if (n == 0)
1172 goto nospace;
1173 if (top == 0) {
1174 top = n;
1175 np = &top->m_next;
1176 continue;
1177 } else
1178 *np = n;
1179
1180 if (copyhdr) {
1181 M_COPY_PKTHDR(n, m);
1182 n->m_pkthdr.len = len;
1183 copyhdr = 0;
1184 }
1185 n->m_len = min(len, (m->m_len - off));
1186
1187 if (m->m_flags & M_EXT) {
1188 n->m_ext = m->m_ext;
1189 insque((queue_t)&n->m_ext.ext_refs, (queue_t)&m->m_ext.ext_refs);
1190 n->m_data = m->m_data + off;
1191 n->m_flags |= M_EXT;
1192 } else {
1193 bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
1194 (unsigned)n->m_len);
1195 }
1196 len -= n->m_len;
1197
1198 if (len == 0) {
1199 if ((off + n->m_len) == m->m_len) {
1200 *m_last = m->m_next;
1201 *m_off = 0;
1202 } else {
1203 *m_last = m;
1204 *m_off = off + n->m_len;
1205 }
1206 break;
1207 }
1208 off = 0;
1209 m = m->m_next;
1210 np = &n->m_next;
1211 }
1212 MBUF_UNLOCK();
1213
1214 return (top);
1215 nospace:
1216 MBUF_UNLOCK();
1217
1218 if (top)
1219 m_freem(top);
1220 MCFail++;
1221 return (0);
1222 }
1223
1224
1225 /*
1226 * Copy data from an mbuf chain starting "off" bytes from the beginning,
1227 * continuing for "len" bytes, into the indicated buffer.
1228 */
1229 void m_copydata(m, off, len, cp)
1230 register struct mbuf *m;
1231 register int off;
1232 register int len;
1233 caddr_t cp;
1234 {
1235 register unsigned count;
1236
1237 if (off < 0 || len < 0)
1238 panic("m_copydata");
1239 while (off > 0) {
1240 if (m == 0)
1241 panic("m_copydata");
1242 if (off < m->m_len)
1243 break;
1244 off -= m->m_len;
1245 m = m->m_next;
1246 }
1247 while (len > 0) {
1248 if (m == 0)
1249 panic("m_copydata");
1250 count = min(m->m_len - off, len);
1251 bcopy(mtod(m, caddr_t) + off, cp, count);
1252 len -= count;
1253 cp += count;
1254 off = 0;
1255 m = m->m_next;
1256 }
1257 }
1258
1259 /*
1260 * Concatenate mbuf chain n to m.
1261 * Both chains must be of the same type (e.g. MT_DATA).
1262 * Any m_pkthdr is not updated.
1263 */
1264 void m_cat(m, n)
1265 register struct mbuf *m, *n;
1266 {
1267 while (m->m_next)
1268 m = m->m_next;
1269 while (n) {
1270 if (m->m_flags & M_EXT ||
1271 m->m_data + m->m_len + n->m_len >= &m->m_dat[MLEN]) {
1272 /* just join the two chains */
1273 m->m_next = n;
1274 return;
1275 }
1276 /* splat the data from one into the other */
1277 bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
1278 (u_int)n->m_len);
1279 m->m_len += n->m_len;
1280 n = m_free(n);
1281 }
1282 }
1283
1284 void
1285 m_adj(mp, req_len)
1286 struct mbuf *mp;
1287 int req_len;
1288 {
1289 register int len = req_len;
1290 register struct mbuf *m;
1291 register count;
1292
1293 if ((m = mp) == NULL)
1294 return;
1295 if (len >= 0) {
1296 /*
1297 * Trim from head.
1298 */
1299 while (m != NULL && len > 0) {
1300 if (m->m_len <= len) {
1301 len -= m->m_len;
1302 m->m_len = 0;
1303 m = m->m_next;
1304 } else {
1305 m->m_len -= len;
1306 m->m_data += len;
1307 len = 0;
1308 }
1309 }
1310 m = mp;
1311 if (m->m_flags & M_PKTHDR)
1312 m->m_pkthdr.len -= (req_len - len);
1313 } else {
1314 /*
1315 * Trim from tail. Scan the mbuf chain,
1316 * calculating its length and finding the last mbuf.
1317 * If the adjustment only affects this mbuf, then just
1318 * adjust and return. Otherwise, rescan and truncate
1319 * after the remaining size.
1320 */
1321 len = -len;
1322 count = 0;
1323 for (;;) {
1324 count += m->m_len;
1325 if (m->m_next == (struct mbuf *)0)
1326 break;
1327 m = m->m_next;
1328 }
1329 if (m->m_len >= len) {
1330 m->m_len -= len;
1331 m = mp;
1332 if (m->m_flags & M_PKTHDR)
1333 m->m_pkthdr.len -= len;
1334 return;
1335 }
1336 count -= len;
1337 if (count < 0)
1338 count = 0;
1339 /*
1340 * Correct length for chain is "count".
1341 * Find the mbuf with last data, adjust its length,
1342 * and toss data from remaining mbufs on chain.
1343 */
1344 m = mp;
1345 if (m->m_flags & M_PKTHDR)
1346 m->m_pkthdr.len = count;
1347 for (; m; m = m->m_next) {
1348 if (m->m_len >= count) {
1349 m->m_len = count;
1350 break;
1351 }
1352 count -= m->m_len;
1353 }
1354 while (m = m->m_next)
1355 m->m_len = 0;
1356 }
1357 }
1358
1359 /*
1360 * Rearange an mbuf chain so that len bytes are contiguous
1361 * and in the data area of an mbuf (so that mtod and dtom
1362 * will work for a structure of size len). Returns the resulting
1363 * mbuf chain on success, frees it and returns null on failure.
1364 * If there is room, it will add up to max_protohdr-len extra bytes to the
1365 * contiguous region in an attempt to avoid being called next time.
1366 */
1367 int MPFail;
1368
1369 struct mbuf *
1370 m_pullup(n, len)
1371 register struct mbuf *n;
1372 int len;
1373 {
1374 register struct mbuf *m;
1375 register int count;
1376 int space;
1377
1378 /*
1379 * If first mbuf has no cluster, and has room for len bytes
1380 * without shifting current data, pullup into it,
1381 * otherwise allocate a new mbuf to prepend to the chain.
1382 */
1383 if ((n->m_flags & M_EXT) == 0 &&
1384 n->m_data + len < &n->m_dat[MLEN] && n->m_next) {
1385 if (n->m_len >= len)
1386 return (n);
1387 m = n;
1388 n = n->m_next;
1389 len -= m->m_len;
1390 } else {
1391 if (len > MHLEN)
1392 goto bad;
1393 MGET(m, M_DONTWAIT, n->m_type);
1394 if (m == 0)
1395 goto bad;
1396 m->m_len = 0;
1397 if (n->m_flags & M_PKTHDR) {
1398 M_COPY_PKTHDR(m, n);
1399 n->m_flags &= ~M_PKTHDR;
1400 }
1401 }
1402 space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
1403 do {
1404 count = min(min(max(len, max_protohdr), space), n->m_len);
1405 bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
1406 (unsigned)count);
1407 len -= count;
1408 m->m_len += count;
1409 n->m_len -= count;
1410 space -= count;
1411 if (n->m_len)
1412 n->m_data += count;
1413 else
1414 n = m_free(n);
1415 } while (len > 0 && n);
1416 if (len > 0) {
1417 (void) m_free(m);
1418 goto bad;
1419 }
1420 m->m_next = n;
1421 return (m);
1422 bad:
1423 m_freem(n);
1424 MPFail++;
1425 return (0);
1426 }
1427
1428 /*
1429 * Partition an mbuf chain in two pieces, returning the tail --
1430 * all but the first len0 bytes. In case of failure, it returns NULL and
1431 * attempts to restore the chain to its original state.
1432 */
1433 struct mbuf *
1434 m_split(m0, len0, wait)
1435 register struct mbuf *m0;
1436 int len0, wait;
1437 {
1438 register struct mbuf *m, *n;
1439 unsigned len = len0, remain;
1440
1441 for (m = m0; m && len > m->m_len; m = m->m_next)
1442 len -= m->m_len;
1443 if (m == 0)
1444 return (0);
1445 remain = m->m_len - len;
1446 if (m0->m_flags & M_PKTHDR) {
1447 MGETHDR(n, wait, m0->m_type);
1448 if (n == 0)
1449 return (0);
1450 n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
1451 n->m_pkthdr.len = m0->m_pkthdr.len - len0;
1452 m0->m_pkthdr.len = len0;
1453 if (m->m_flags & M_EXT)
1454 goto extpacket;
1455 if (remain > MHLEN) {
1456 /* m can't be the lead packet */
1457 MH_ALIGN(n, 0);
1458 n->m_next = m_split(m, len, wait);
1459 if (n->m_next == 0) {
1460 (void) m_free(n);
1461 return (0);
1462 } else
1463 return (n);
1464 } else
1465 MH_ALIGN(n, remain);
1466 } else if (remain == 0) {
1467 n = m->m_next;
1468 m->m_next = 0;
1469 return (n);
1470 } else {
1471 MGET(n, wait, m->m_type);
1472 if (n == 0)
1473 return (0);
1474 M_ALIGN(n, remain);
1475 }
1476 extpacket:
1477 if (m->m_flags & M_EXT) {
1478 n->m_flags |= M_EXT;
1479 MBUF_LOCK();
1480 n->m_ext = m->m_ext;
1481 insque((queue_t)&n->m_ext.ext_refs, (queue_t)&m->m_ext.ext_refs);
1482 MBUF_UNLOCK();
1483 n->m_data = m->m_data + len;
1484 } else {
1485 bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain);
1486 }
1487 n->m_len = remain;
1488 m->m_len = len;
1489 n->m_next = m->m_next;
1490 m->m_next = 0;
1491 return (n);
1492 }
1493 /*
1494 * Routine to copy from device local memory into mbufs.
1495 */
1496 struct mbuf *
1497 m_devget(buf, totlen, off0, ifp, copy)
1498 char *buf;
1499 int totlen, off0;
1500 struct ifnet *ifp;
1501 void (*copy)();
1502 {
1503 register struct mbuf *m;
1504 struct mbuf *top = 0, **mp = &top;
1505 register int off = off0, len;
1506 register char *cp;
1507 char *epkt;
1508
1509 cp = buf;
1510 epkt = cp + totlen;
1511 if (off) {
1512 /*
1513 * If 'off' is non-zero, packet is trailer-encapsulated,
1514 * so we have to skip the type and length fields.
1515 */
1516 cp += off + 2 * sizeof(u_int16_t);
1517 totlen -= 2 * sizeof(u_int16_t);
1518 }
1519 MGETHDR(m, M_DONTWAIT, MT_DATA);
1520 if (m == 0)
1521 return (0);
1522 m->m_pkthdr.rcvif = ifp;
1523 m->m_pkthdr.len = totlen;
1524 m->m_len = MHLEN;
1525
1526 while (totlen > 0) {
1527 if (top) {
1528 MGET(m, M_DONTWAIT, MT_DATA);
1529 if (m == 0) {
1530 m_freem(top);
1531 return (0);
1532 }
1533 m->m_len = MLEN;
1534 }
1535 len = min(totlen, epkt - cp);
1536 if (len >= MINCLSIZE) {
1537 MCLGET(m, M_DONTWAIT);
1538 if (m->m_flags & M_EXT)
1539 m->m_len = len = min(len, MCLBYTES);
1540 else {
1541 /* give up when it's out of cluster mbufs */
1542 if (top)
1543 m_freem(top);
1544 m_freem(m);
1545 return (0);
1546 }
1547 } else {
1548 /*
1549 * Place initial small packet/header at end of mbuf.
1550 */
1551 if (len < m->m_len) {
1552 if (top == 0 && len + max_linkhdr <= m->m_len)
1553 m->m_data += max_linkhdr;
1554 m->m_len = len;
1555 } else
1556 len = m->m_len;
1557 }
1558 if (copy)
1559 copy(cp, mtod(m, caddr_t), (unsigned)len);
1560 else
1561 bcopy(cp, mtod(m, caddr_t), (unsigned)len);
1562 cp += len;
1563 *mp = m;
1564 mp = &m->m_next;
1565 totlen -= len;
1566 if (cp == epkt)
1567 cp = buf;
1568 }
1569 return (top);
1570 }
1571
1572 /*
1573 * Cluster freelist allocation check. The mbuf lock must be held.
1574 * Ensure hysteresis between hi/lo.
1575 */
1576 static int
1577 m_howmany()
1578 {
1579 register int i;
1580
1581 /* Under minimum */
1582 if (mbstat.m_clusters < MINCL)
1583 return (MINCL - mbstat.m_clusters);
1584 /* Too few (free < 1/2 total) and not over maximum */
1585 if (mbstat.m_clusters < nmbclusters &&
1586 (i = ((mbstat.m_clusters >> 1) - mbstat.m_clfree)) > 0)
1587 return i;
1588 return 0;
1589 }
1590
1591
1592 /*
1593 * Copy data from a buffer back into the indicated mbuf chain,
1594 * starting "off" bytes from the beginning, extending the mbuf
1595 * chain if necessary.
1596 */
1597 void
1598 m_copyback(m0, off, len, cp)
1599 struct mbuf *m0;
1600 register int off;
1601 register int len;
1602 caddr_t cp;
1603 {
1604 register int mlen;
1605 register struct mbuf *m = m0, *n;
1606 int totlen = 0;
1607
1608 if (m0 == 0)
1609 return;
1610 while (off > (mlen = m->m_len)) {
1611 off -= mlen;
1612 totlen += mlen;
1613 if (m->m_next == 0) {
1614 n = m_getclr(M_DONTWAIT, m->m_type);
1615 if (n == 0)
1616 goto out;
1617 n->m_len = min(MLEN, len + off);
1618 m->m_next = n;
1619 }
1620 m = m->m_next;
1621 }
1622 while (len > 0) {
1623 mlen = min (m->m_len - off, len);
1624 bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);
1625 cp += mlen;
1626 len -= mlen;
1627 mlen += off;
1628 off = 0;
1629 totlen += mlen;
1630 if (len == 0)
1631 break;
1632 if (m->m_next == 0) {
1633 n = m_get(M_DONTWAIT, m->m_type);
1634 if (n == 0)
1635 break;
1636 n->m_len = min(MLEN, len);
1637 m->m_next = n;
1638 }
1639 m = m->m_next;
1640 }
1641 out: if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
1642 m->m_pkthdr.len = totlen;
1643 }
1644
1645
1646 char *mcl_to_paddr(register char *addr) {
1647 register int base_phys;
1648
1649 if (addr < (char *)mbutl || addr >= (char *)embutl)
1650 return (0);
1651 base_phys = mcl_paddr[(addr - (char *)mbutl) >> PAGE_SHIFT];
1652
1653 if (base_phys == 0)
1654 return (0);
1655 return ((char *)((int)base_phys | ((int)addr & PAGE_MASK)));
1656 }
1657
1658 /*
1659 * Dup the mbuf chain passed in. The whole thing. No cute additional cruft.
1660 * And really copy the thing. That way, we don't "precompute" checksums
1661 * for unsuspecting consumers.
1662 * Assumption: m->m_nextpkt == 0.
1663 * Trick: for small packets, don't dup into a cluster. That way received
1664 * packets don't take up too much room in the sockbuf (cf. sbspace()).
1665 */
1666 int MDFail;
1667
1668 struct mbuf *
1669 m_dup(register struct mbuf *m, int how)
1670 { register struct mbuf *n, **np;
1671 struct mbuf *top;
1672 int copyhdr = 0;
1673
1674 np = &top;
1675 top = 0;
1676 if (m->m_flags & M_PKTHDR)
1677 copyhdr = 1;
1678
1679 /*
1680 * Quick check: if we have one mbuf and its data fits in an
1681 * mbuf with packet header, just copy and go.
1682 */
1683 if (m->m_next == NULL)
1684 { /* Then just move the data into an mbuf and be done... */
1685 if (copyhdr)
1686 { if (m->m_pkthdr.len <= MHLEN)
1687 { if ((n = m_gethdr(how, m->m_type)) == NULL)
1688 return(NULL);
1689 n->m_len = m->m_len;
1690 n->m_flags |= (m->m_flags & M_COPYFLAGS);
1691 n->m_pkthdr.len = m->m_pkthdr.len;
1692 n->m_pkthdr.rcvif = m->m_pkthdr.rcvif;
1693 n->m_pkthdr.header = NULL;
1694 n->m_pkthdr.csum_flags = 0;
1695 n->m_pkthdr.csum_data = 0;
1696 n->m_pkthdr.aux = NULL;
1697 n->m_pkthdr.vlan_tag = 0;
1698 n->m_pkthdr.reserved_1 = 0;
1699 n->m_pkthdr.reserved2 = 0;
1700 bcopy(m->m_data, n->m_data, m->m_pkthdr.len);
1701 return(n);
1702 }
1703 } else if (m->m_len <= MLEN)
1704 { if ((n = m_get(how, m->m_type)) == NULL)
1705 return(NULL);
1706 bcopy(m->m_data, n->m_data, m->m_len);
1707 n->m_len = m->m_len;
1708 return(n);
1709 }
1710 }
1711 while (m)
1712 {
1713 #if BLUE_DEBUG
1714 kprintf("<%x: %x, %x, %x\n", m, m->m_flags, m->m_len,
1715 m->m_data);
1716 #endif
1717 if (copyhdr)
1718 n = m_gethdr(how, m->m_type);
1719 else
1720 n = m_get(how, m->m_type);
1721 if (n == 0)
1722 goto nospace;
1723 if (m->m_flags & M_EXT)
1724 { MCLGET(n, how);
1725 if ((n->m_flags & M_EXT) == 0)
1726 goto nospace;
1727 }
1728 *np = n;
1729 if (copyhdr)
1730 { /* Don't use M_COPY_PKTHDR: preserve m_data */
1731 n->m_pkthdr = m->m_pkthdr;
1732 n->m_flags |= (m->m_flags & M_COPYFLAGS);
1733 copyhdr = 0;
1734 if ((n->m_flags & M_EXT) == 0)
1735 n->m_data = n->m_pktdat;
1736 }
1737 n->m_len = m->m_len;
1738 /*
1739 * Get the dup on the same bdry as the original
1740 * Assume that the two mbufs have the same offset to data area
1741 * (up to word bdries)
1742 */
1743 bcopy(mtod(m, caddr_t), mtod(n, caddr_t), (unsigned)n->m_len);
1744 m = m->m_next;
1745 np = &n->m_next;
1746 #if BLUE_DEBUG
1747 kprintf(">%x: %x, %x, %x\n", n, n->m_flags, n->m_len,
1748 n->m_data);
1749 #endif
1750 }
1751
1752 if (top == 0)
1753 MDFail++;
1754 return (top);
1755 nospace:
1756 m_freem(top);
1757 MDFail++;
1758 return (0);
1759 }
1760
1761 int
1762 m_mclref(struct mbuf *p)
1763 {
1764 return (_MCLREF(p));
1765 }
1766
1767 int
1768 m_mclunref(struct mbuf *p)
1769 {
1770 return (_MCLUNREF(p));
1771 }
1772
1773 /* change mbuf to new type */
1774 void
1775 m_mchtype(struct mbuf *m, int t)
1776 {
1777 MBUF_LOCK();
1778 mbstat.m_mtypes[(m)->m_type]--;
1779 mbstat.m_mtypes[t]++;
1780 (m)->m_type = t;
1781 MBUF_UNLOCK();
1782 }
1783
1784 void *m_mtod(struct mbuf *m)
1785 {
1786 return ((m)->m_data);
1787 }
1788
1789 struct mbuf *m_dtom(void *x)
1790 {
1791 return ((struct mbuf *)((u_long)(x) & ~(MSIZE-1)));
1792 }
1793
1794 int m_mtocl(void *x)
1795 {
1796 return (((char *)(x) - (char *)mbutl) / sizeof(union mcluster));
1797 }
1798
1799 union mcluster *m_cltom(int x)
1800 {
1801 return ((union mcluster *)(mbutl + (x)));
1802 }
1803
1804
1805 void m_mcheck(struct mbuf *m)
1806 {
1807 if (m->m_type != MT_FREE)
1808 panic("mget MCHECK: m_type=%x m=%x", m->m_type, m);
1809 }
1810
1811 void
1812 mbuf_expand_thread(void)
1813 {
1814 while (1) {
1815 int expand_mcl;
1816 MBUF_LOCK();
1817 expand_mcl = mbuf_expand_mcl;
1818 mbuf_expand_mcl = 0;
1819 MBUF_UNLOCK();
1820 if (expand_mcl) {
1821 caddr_t p;
1822 MCLALLOC(p, M_WAIT);
1823 if (p) MCLFREE(p);
1824 }
1825 assert_wait(&mbuf_expand_thread_wakeup, THREAD_UNINT);
1826 (void) thread_block(mbuf_expand_thread);
1827 }
1828 }
1829
1830 void
1831 mbuf_expand_thread_init(void)
1832 {
1833 mbuf_expand_thread_initialized++;
1834 mbuf_expand_thread();
1835 }
1836