2 * Copyright (c) 1997-1998 University of Utah and the Flux Group.
5 * This file is part of the Flux OSKit. The OSKit is free software, also known
6 * as "open source;" you can redistribute it and/or modify it under the terms
7 * of the GNU General Public License (GPL), version 2, as published by the Free
8 * Software Foundation (FSF). To explore alternate licensing terms, contact
9 * the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271.
11 * The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GPL for more details. You should have
14 * received a copy of the GPL along with the OSKit; see the file COPYING. If
15 * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
18 * Copyright (c) 1982, 1986, 1988, 1991, 1993
19 * The Regents of the University of California. All rights reserved.
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
24 * 1. Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * 3. All advertising materials mentioning features or use of this software
30 * must display the following acknowledgement:
31 * This product includes software developed by the University of
32 * California, Berkeley and its contributors.
33 * 4. Neither the name of the University nor the names of its contributors
34 * may be used to endorse or promote products derived from this software
35 * without specific prior written permission.
37 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
38 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
52 #include <sys/param.h>
53 #include <sys/systm.h>
55 #include <sys/malloc.h>
58 #include <sys/kernel.h>
59 #include <sys/syslog.h>
60 #include <sys/domain.h>
61 #include <sys/protosw.h>
67 extern vm_map_t mb_map
;
78 #define NCL_INIT (4096/CLBYTES)
84 if (m_clalloc(NCL_INIT
, M_DONTWAIT
) == 0)
94 * Allocate some number of mbuf clusters
95 * and place on cluster free list.
96 * Must be called at splimp.
100 m_clalloc(ncl
, nowait
)
112 * Once we run out of map space, it will be impossible
113 * to get any more (nothing is ever freed back to the
121 //printf("kmem_malloc(%d)\n", npg);
123 p
= (caddr_t
)kmem_malloc(mb_map
, ctob(npg
),
124 nowait
? M_NOWAIT
: M_WAITOK
);
126 //printf("kmem_malloc done\n");
129 * Either the map is now full, or this is nowait and there
135 ncl
= ncl
* CLBYTES
/ MCLBYTES
;
136 for (i
= 0; i
< ncl
; i
++) {
137 ((union mcluster
*)p
)->mcl_next
= mclfree
;
138 //printf( "Freeing %x onto the free list\n", p);
139 mclfree
= (union mcluster
*)p
;
143 mbstat
.m_clusters
+= ncl
;
144 //printf( "done with m_clalloc\n");
150 * When MGET failes, ask protocols to free space when short of memory,
151 * then re-attempt to allocate an mbuf.
157 register struct mbuf
*m
;
161 * I'm getting rid of the utterly ugly redefinition of m_retry
162 * - same for m_retryhdr below
167 MGET_DONT_RECURSE(m
, i
, t
);
177 * As above; retry an MGETHDR.
183 register struct mbuf
*m
;
189 MGETHDR_DONT_RECURSE(m
, i
, t
);
201 register struct domain
*dp
;
202 register struct protosw
*pr
;
205 for (dp
= domains
; dp
; dp
= dp
->dom_next
) {
206 for (pr
= dp
->dom_protosw
; pr
< dp
->dom_protoswNPROTOSW
; pr
++) {
217 * Space allocation routines.
218 * These are also available as macros
219 * for critical paths.
225 register struct mbuf
*m
;
227 MGET(m
, nowait
, type
);
232 m_gethdr(nowait
, type
)
235 register struct mbuf
*m
;
237 MGETHDR(m
, nowait
, type
);
242 m_getclr(nowait
, type
)
245 register struct mbuf
*m
;
247 MGET(m
, nowait
, type
);
250 bzero(mtod(m
, caddr_t
), MLEN
);
258 register struct mbuf
*n
;
266 register struct mbuf
*m
;
268 register struct mbuf
*n
;
279 * Mbuffer utility routines.
283 * Lesser-used path for M_PREPEND:
284 * allocate new mbuf to prepend to chain,
288 m_prepend(m
, len
, how
)
289 register struct mbuf
*m
;
294 MGET(mn
, how
, m
->m_type
);
295 if (mn
== (struct mbuf
*)NULL
) {
297 return ((struct mbuf
*)NULL
);
299 if (m
->m_flags
& M_PKTHDR
) {
300 M_COPY_PKTHDR(mn
, m
);
301 m
->m_flags
&= ~M_PKTHDR
;
312 * Make a copy of an mbuf chain starting "off0" bytes from the beginning,
313 * continuing for "len" bytes. If len is M_COPYALL, copy to end of mbuf.
314 * The wait parameter is a choice of M_WAIT/M_DONTWAIT from caller.
319 m_copym(m
, off0
, len
, wait
)
320 register struct mbuf
*m
;
324 register struct mbuf
*n
, **np
;
325 register int off
= off0
;
329 if (off
< 0 || len
< 0)
330 panic("m_copym: off %d, len %d", off
, len
);
331 if (off
== 0 && m
->m_flags
& M_PKTHDR
)
335 panic("m_copym: %d", off
);
345 if (len
!= M_COPYALL
)
349 MGET(n
, wait
, m
->m_type
);
355 if (len
== M_COPYALL
)
356 n
->m_pkthdr
.len
-= off0
;
358 n
->m_pkthdr
.len
= len
;
361 n
->m_len
= min(len
, m
->m_len
- off
);
363 if (m
->m_flags
& M_EXT
) {
364 n
->m_data
= m
->m_data
+ off
;
366 oskit_bufio_addref(m
->m_ext
.ext_bufio
);
369 mclrefcnt
[mtocl(m
->m_ext
.ext_buf
)]++;
375 bcopy(mtod(m
, caddr_t
)+off
, mtod(n
, caddr_t
),
377 if (len
!= M_COPYALL
)
393 * Copy data from an mbuf chain starting "off" bytes from the beginning,
394 * continuing for "len" bytes, into the indicated buffer.
397 m_copydata(m
, off
, len
, cp
)
398 register struct mbuf
*m
;
403 register unsigned count
;
405 if (off
< 0 || len
< 0)
418 count
= min(m
->m_len
- off
, len
);
419 OS_DbgPrint(OSK_MID_TRACE
,("count %d len %d\n", count
, len
));
420 bcopy(mtod(m
, caddr_t
) + off
, cp
, count
);
429 * Concatenate mbuf chain n to m.
430 * Both chains must be of the same type (e.g. MT_DATA).
431 * Any m_pkthdr is not updated.
435 register struct mbuf
*m
, *n
;
440 if (m
->m_flags
& M_EXT
||
441 m
->m_data
+ m
->m_len
+ n
->m_len
>= &m
->m_dat
[MLEN
]) {
442 /* just join the two chains */
446 /* splat the data from one into the other */
447 bcopy(mtod(n
, caddr_t
), mtod(m
, caddr_t
) + m
->m_len
,
449 m
->m_len
+= n
->m_len
;
459 register int len
= req_len
;
460 register struct mbuf
*m
;
463 if ((m
= mp
) == NULL
)
469 while (m
!= NULL
&& len
> 0) {
470 if (m
->m_len
<= len
) {
481 if (mp
->m_flags
& M_PKTHDR
)
482 m
->m_pkthdr
.len
-= (req_len
- len
);
485 * Trim from tail. Scan the mbuf chain,
486 * calculating its length and finding the last mbuf.
487 * If the adjustment only affects this mbuf, then just
488 * adjust and return. Otherwise, rescan and truncate
489 * after the remaining size.
495 if (m
->m_next
== (struct mbuf
*)0)
499 if (m
->m_len
>= len
) {
501 if (mp
->m_flags
& M_PKTHDR
)
502 mp
->m_pkthdr
.len
-= len
;
509 * Correct length for chain is "count".
510 * Find the mbuf with last data, adjust its length,
511 * and toss data from remaining mbufs on chain.
514 if (m
->m_flags
& M_PKTHDR
)
515 m
->m_pkthdr
.len
= count
;
516 for (; m
; m
= m
->m_next
) {
517 if (m
->m_len
>= count
) {
524 (m
= m
->m_next
) ->m_len
= 0;
529 * Rearange an mbuf chain so that len bytes are contiguous
530 * and in the data area of an mbuf (so that mtod and dtom
531 * will work for a structure of size len). Returns the resulting
532 * mbuf chain on success, frees it and returns null on failure.
533 * If there is room, it will add up to max_protohdr-len extra bytes to the
534 * contiguous region in an attempt to avoid being called next time.
540 register struct mbuf
*n
;
543 register struct mbuf
*m
;
548 * If first mbuf has no cluster, and has room for len bytes
549 * without shifting current data, pullup into it,
550 * otherwise allocate a new mbuf to prepend to the chain.
552 if ((n
->m_flags
& M_EXT
) == 0 &&
553 n
->m_data
+ len
< &n
->m_dat
[MLEN
] && n
->m_next
) {
562 MGET(m
, M_DONTWAIT
, n
->m_type
);
566 if (n
->m_flags
& M_PKTHDR
) {
568 n
->m_flags
&= ~M_PKTHDR
;
571 space
= &m
->m_dat
[MLEN
] - (m
->m_data
+ m
->m_len
);
573 count
= min(min(max(len
, max_protohdr
), space
), n
->m_len
);
574 bcopy(mtod(n
, caddr_t
), mtod(m
, caddr_t
) + m
->m_len
,
584 } while (len
> 0 && n
);
598 * Partition an mbuf chain in two pieces, returning the tail --
599 * all but the first len0 bytes. In case of failure, it returns NULL and
600 * attempts to restore the chain to its original state.
603 m_split(m0
, len0
, wait
)
604 register struct mbuf
*m0
;
607 register struct mbuf
*m
, *n
;
608 unsigned len
= len0
, remain
;
610 for (m
= m0
; m
&& len
> m
->m_len
; m
= m
->m_next
)
614 remain
= m
->m_len
- len
;
615 if (m0
->m_flags
& M_PKTHDR
) {
616 MGETHDR(n
, wait
, m0
->m_type
);
619 n
->m_pkthdr
.rcvif
= m0
->m_pkthdr
.rcvif
;
620 n
->m_pkthdr
.len
= m0
->m_pkthdr
.len
- len0
;
621 m0
->m_pkthdr
.len
= len0
;
622 if (m
->m_flags
& M_EXT
)
624 if (remain
> MHLEN
) {
625 /* m can't be the lead packet */
627 n
->m_next
= m_split(m
, len
, wait
);
628 if (n
->m_next
== 0) {
635 } else if (remain
== 0) {
640 MGET(n
, wait
, m
->m_type
);
646 if (m
->m_flags
& M_EXT
) {
650 oskit_bufio_addref(m
->m_ext
.ext_bufio
);
652 mclrefcnt
[mtocl(m
->m_ext
.ext_buf
)]++;
654 m
->m_ext
.ext_size
= 0; /* For Accounting XXXXXX danger */
655 n
->m_data
= m
->m_data
+ len
;
657 bcopy(mtod(m
, caddr_t
) + len
, mtod(n
, caddr_t
), remain
);
661 n
->m_next
= m
->m_next
;
666 #if !defined(OSKIT) || defined(__REACTOS__)
667 /* currently not OS Kit approved, and shouldn't be needed in the first place */
670 * Routine to copy from device local memory into mbufs.
673 m_devget(buf
, totlen
, off0
, ifp
, copy
)
679 register struct mbuf
*m
;
680 struct mbuf
*top
= 0, **mp
= &top
;
681 register int off
= off0
, len
;
688 cp
+= off
+ 2 * sizeof(u_short
);
689 totlen
-= 2 * sizeof(u_short
);
691 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
695 m
->m_pkthdr
.rcvif
= ifp
;
697 m
->m_pkthdr
.rcvif
= 0;
699 m
->m_pkthdr
.len
= totlen
;
704 MGET(m
, M_DONTWAIT
, MT_DATA
);
711 len
= min(totlen
, epkt
- cp
);
712 if (len
>= MINCLSIZE
) {
713 MCLGET(m
, M_DONTWAIT
);
714 if (m
->m_flags
& M_EXT
)
715 m
->m_len
= len
= min(len
, MCLBYTES
);
720 * Place initial small packet/header at end of mbuf.
722 if (len
< m
->m_len
) {
723 if (top
== 0 && len
+ max_linkhdr
<= m
->m_len
)
724 m
->m_data
+= max_linkhdr
;
730 copy(cp
, mtod(m
, caddr_t
), (unsigned)len
);
733 memcpy(mtod(m
, caddr_t
), cp
, len
);
735 bcopy(cp
, mtod(m
, caddr_t
), (unsigned)len
);
750 * Copy data from a buffer back into the indicated mbuf chain,
751 * starting "off" bytes from the beginning, extending the mbuf
752 * chain if necessary.
755 m_copyback(m0
, off
, len
, cp
)
762 register struct mbuf
*m
= m0
, *n
;
767 while (off
> (mlen
= m
->m_len
)) {
770 if (m
->m_next
== 0) {
771 n
= m_getclr(M_DONTWAIT
, m
->m_type
);
774 n
->m_len
= min(MLEN
, len
+ off
);
780 mlen
= min (m
->m_len
- off
, len
);
781 bcopy(cp
, off
+ mtod(m
, caddr_t
), (unsigned)mlen
);
789 if (m
->m_next
== 0) {
790 n
= m_get(M_DONTWAIT
, m
->m_type
);
793 n
->m_len
= min(MLEN
, len
);
798 out
: if (((m
= m0
)->m_flags
& M_PKTHDR
) && (m
->m_pkthdr
.len
< totlen
))
799 m
->m_pkthdr
.len
= totlen
;