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