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