2 * Mach Operating System
3 * Copyright (c) 1992 Carnegie Mellon University
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
16 * Carnegie Mellon requests users of this software to return to
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
28 * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
29 * All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. All advertising materials mentioning features or use of this software
40 * must display the following acknowledgement:
41 * This product includes software developed by the University of
42 * California, Berkeley and its contributors.
43 * 4. Neither the name of the University nor the names of its contributors
44 * may be used to endorse or promote products derived from this software
45 * without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * @(#)mbuf.h 7.14 (Berkeley) 12/5/90
66 #include <sys/malloc.h>
69 #if 0 /* not needed (yet), DO NOT DELETE! */
70 extern void mcl_free_routine();
72 extern struct mbuf
*mfree
;
75 * Mbufs are of a single size, MSIZE, which
76 * includes overhead. An mbuf may add a single "mbuf cluster" of size
77 * mbconf.mclbytes (see struct mbconf), which has no additional overhead
78 * and is used instead of the internal data area; this is done when
79 * at least MINCLSIZE of data must be stored.
82 #define MSIZE 256 /* size of an mbuf */
83 #define MLEN (MSIZE - sizeof(struct m_hdr)) /* normal data len */
84 #define MHLEN (MLEN - sizeof(struct pkthdr)) /* data len w/pkthdr */
86 #define MINCLSIZE (MHLEN + MLEN) /* smallest amount to put in cluster */
87 #define M_MAXCOMPRESS (MHLEN / 2) /* max amount to copy for compression */
90 * Mbuf cluster structure. The first word is used as a reference count when the
91 * cluster is in use and as a next pointer if on the free list.
95 struct mcluster
*mcl_next
;
96 short mcl_refcnt
; /* reference count */
98 char mcl_buf
[0]; /* variable size (mbconf.mclbytes) */
102 * Macros for type conversion
103 * mtod(m,t) - convert mbuf pointer to data pointer of correct type
104 * dtom(x) - convert data pointer within mbuf to mbuf pointer (XXX)
105 * WARNING: cannot be used with clusters
107 #define mtod(m,t) ((t)((m)->m_data))
108 #define dtom(x) ((struct mbuf *)((long)(x) & ~(MSIZE-1)))
110 /* header at beginning of each mbuf: */
112 struct mbuf
*mh_next
; /* next buffer in chain */
113 struct mbuf
*mh_nextpkt
; /* next chain in queue/record */
114 int mh_len
; /* amount of data in this mbuf */
115 caddr_t mh_data
; /* location of data */
116 short mh_type
; /* type of data in this mbuf */
117 short mh_flags
; /* flags; see below */
120 /* record/packet header in first mbuf of chain; valid if M_PKTHDR set */
122 int len
; /* total packet length */
123 struct ifnet
*rcvif
; /* rcv interface */
124 /* variables for ip and tcp reassembly */
125 caddr_t header
; /* pointer to packet header */
128 /* description of external storage mapped into mbuf, valid if M_EXT set */
130 struct mcluster
*ext_buf
; /* external buffer */
131 #if 0 /* Not used in AmiTCP/IP */
132 void (*ext_free
)(); /* free routine if not the usual */
134 u_int ext_size
; /* size of buffer, for ext_free */
141 struct pkthdr MH_pkthdr
; /* M_PKTHDR set */
143 struct m_ext MH_ext
; /* M_EXT set */
144 char MH_databuf
[MHLEN
];
147 char M_databuf
[MLEN
]; /* !M_PKTHDR, !M_EXT */
150 #define m_next m_hdr.mh_next
151 #define m_len m_hdr.mh_len
152 #define m_data m_hdr.mh_data
153 #define m_type m_hdr.mh_type
154 #define m_flags m_hdr.mh_flags
155 #define m_nextpkt m_hdr.mh_nextpkt
156 #define m_act m_nextpkt
157 #define m_pkthdr M_dat.MH.MH_pkthdr
158 #define m_ext M_dat.MH.MH_dat.MH_ext
159 #define m_pktdat M_dat.MH.MH_dat.MH_databuf
160 #define m_dat M_dat.M_databuf
164 * The M_EOR flag is not used by the TCP/IP protocols, so it is left
165 * undefined, unless you define USE_M_EOR.
167 #define M_EXT 0x0001 /* has associated external storage */
168 #define M_PKTHDR 0x0002 /* start of record */
170 #define M_EOR 0x0004 /* end of record */
172 /* mbuf pkthdr flags, also in m_flags */
173 #define M_BCAST 0x0100 /* send/received as link-level broadcast */
174 #define M_MCAST 0x0200 /* send/received as link-level multicast */
176 /* flags copied when copying m_pkthdr */
178 #define M_COPYFLAGS (M_PKTHDR|M_EOR|M_BCAST|M_MCAST)
180 #define M_COPYFLAGS (M_PKTHDR|M_BCAST|M_MCAST)
185 #define MT_FREE 0 /* should be on free list */
186 #define MT_DATA 1 /* dynamic (data) allocation */
187 #define MT_HEADER 2 /* packet header */
188 #define MT_SOCKET 3 /* socket structure */
189 #define MT_PCB 4 /* protocol control block */
190 #define MT_RTABLE 5 /* routing tables */
191 #define MT_HTABLE 6 /* IMP host tables */
192 #define MT_ATABLE 7 /* address resolution tables */
193 #define MT_SONAME 8 /* socket name */
194 #define MT_SOOPTS 10 /* socket options */
195 #define MT_FTABLE 11 /* fragment reassembly header */
196 #define MT_RIGHTS 12 /* access rights */
197 #define MT_IFADDR 13 /* interface address */
198 #define MT_CONTROL 14 /* extra-data protocol message */
199 #define MT_OOBDATA 15 /* expedited data */
200 #define MTCOUNT 16 /* TOTAL COUNT OF THE TYPES */
202 /* flags to m_get/MGET */
203 #define M_DONTWAIT M_NOWAIT
204 #define M_WAIT M_WAITOK
207 * mbuf allocation/deallocation macros:
209 * MGET(struct mbuf *m, int canwait, int type)
210 * allocates an mbuf and initializes it to contain internal data.
212 * MGETHDR(struct mbuf *m, int canwait, int type)
213 * allocates an mbuf and initializes it to contain a packet header
216 #define MGET(m, canwait, type) { \
217 spl_t ms = splimp(); \
220 mfree = (m)->m_next; \
221 (m)->m_type = (type); \
222 mbstat.m_mtypes[type]++; \
223 (m)->m_next = NULL; \
224 (m)->m_nextpkt = NULL; \
225 (m)->m_data = (m)->m_dat; \
228 (m) = m_retry((canwait), (type)); \
232 #define MGETHDR(m, canwait, type) { \
233 MGET(m, canwait, type) \
235 (m)->m_data = (m)->m_pktdat; \
236 (m)->m_flags = M_PKTHDR; \
241 * Mbuf cluster macros.
242 * MCLALLOC(struct mcluster *p, int canwait) allocates an mbuf cluster.
243 * MCLGET adds such clusters to a normal mbuf;
244 * the flag M_EXT is set upon success.
245 * MCLFREE releases a reference to a cluster allocated by MCLALLOC,
246 * freeing the cluster if the reference count has reached 0.
249 #define MCLALLOC(p, canwait) \
250 { spl_t ms = splimp(); \
252 (void)m_clalloc(mbconf.clusterchunk, (canwait)); \
253 if ((p) = mclfree) { \
255 mclfree = (p)->mcl.mcl_next; \
256 (p)->mcl.mcl_refcnt = 1; \
261 #define MCLGET(m, canwait) \
262 { MCLALLOC((m)->m_ext.ext_buf, (canwait)); \
263 if ((m)->m_ext.ext_buf != NULL) { \
264 (m)->m_data = (m)->m_ext.ext_buf->mcl_buf; \
265 (m)->m_flags |= M_EXT; \
266 (m)->m_ext.ext_size = mbconf.mclbytes; \
267 /* (m)->m_ext.ext_free = mcl_free_routine; */ \
272 { spl_t ms = splimp(); \
273 if (--((p)->mcl.mcl_refcnt) == 0) { \
274 (p)->mcl.mcl_next = mclfree; \
282 * MFREE(struct mbuf *m, struct mbuf *n)
283 * Free a single mbuf and associated external storage.
284 * Place the successor, if any, in n.
286 #define MFREE(m, n) \
287 { spl_t ms = splimp(); \
288 mbstat.m_mtypes[(m)->m_type]--; \
289 if ((m)->m_flags & M_EXT) { \
290 /* if ((m)->m_ext.ext_free) */ \
291 /* (*((m)->m_ext.ext_free))((m)->m_ext.ext_buf, */ \
292 /* (m)->m_ext.ext_size); */ \
294 MCLFREE((m)->m_ext.ext_buf); \
297 (m)->m_next = mfree; mfree = (m); \
302 * Copy mbuf pkthdr from from to to.
303 * from must have M_PKTHDR set, and to must be empty.
305 #define M_COPY_PKTHDR(to, from) { \
306 (to)->m_pkthdr = (from)->m_pkthdr; \
307 (to)->m_flags = (from)->m_flags & M_COPYFLAGS; \
308 (to)->m_data = (to)->m_pktdat; \
312 * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place
313 * an object of the specified size at the end of the mbuf, longword aligned.
315 #define M_ALIGN(m, len) \
316 { (m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1); }
318 * As above, for mbufs allocated with m_gethdr/MGETHDR
319 * or initialized by M_COPY_PKTHDR.
321 #define MH_ALIGN(m, len) \
322 { (m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1); }
325 * Compute the amount of space available
326 * before the current start of data in an mbuf.
328 #define M_LEADINGSPACE(m) \
329 ((m)->m_flags & M_EXT ? /* (m)->m_data - (m)->m_ext.ext_buf */ 0 : \
330 (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \
331 (m)->m_data - (m)->m_dat)
334 * Compute the amount of space available
335 * after the end of data in an mbuf.
337 #define M_TRAILINGSPACE(m) \
338 ((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf->mcl_buf + (m)->m_ext.ext_size - \
339 ((m)->m_data + (m)->m_len) : \
340 &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
343 * Arrange to prepend space of size plen to mbuf m.
344 * If a new mbuf must be allocated, canwait specifies whether to wait.
345 * If canwait is M_DONTWAIT and allocation fails, the original mbuf chain
346 * is freed and m is set to NULL.
348 #define M_PREPEND(m, plen, canwait) { \
349 if (M_LEADINGSPACE(m) >= (plen)) { \
350 (m)->m_data -= (plen); \
351 (m)->m_len += (plen); \
353 (m) = m_prepend((m), (plen), (canwait)); \
354 if ((m) && (m)->m_flags & M_PKTHDR) \
355 (m)->m_pkthdr.len += (plen); \
358 /* change mbuf to new type */
359 #define MCHTYPE(m, t) { \
360 mbstat.m_mtypes[(m)->m_type]--; \
361 mbstat.m_mtypes[t]++; \
365 /* length to m_copy to copy all */
366 #define M_COPYALL 1000000000
368 /* compatiblity with 4.3 */
369 #define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT)
372 * Configurable variables. These are put in a structure to ensure that they
373 * will be in sequence, since these are accessed as an array of u_longs
374 * from the <kern/amiga_config.c>.
375 * NOTE: <kern/amiga_config.c> depends on the order of these values.
378 u_long initial_mbuf_chunks
; /* # of mbuf chunks to allocate initially */
379 u_long mbufchunk
; /* # of mbufs to allocate at a time */
380 u_long clusterchunk
; /* # of clusters to allocate at a time */
381 u_long maxmem
; /* maximum memory to use (in kilobytes) */
382 u_long mclbytes
; /* size of the mbuf cluster */
389 u_long m_mbufs
; /* mbufs obtained from page pool */
390 u_long m_clusters
; /* clusters obtained from page pool */
391 u_long m_clfree
; /* free clusters */
392 u_long m_drops
; /* times failed to find space */
393 u_long m_wait
; /* times waited for space */
394 u_long m_drain
; /* times drained protocols for space */
395 u_long m_memused
; /* total amount of memory used for mbufs */
396 u_short m_mtypes
[MTCOUNT
]; /* type specific mbuf allocations */
401 * changed definitions to external declarations, storege is now defined
402 * in kern/uipc_mbuf.c
404 extern struct mcluster
*mclfree
;
405 extern struct mbconf mbconf
;
406 extern struct mbstat mbstat
;
407 extern int max_linkhdr
; /* largest link-level header */
408 extern int max_protohdr
; /* largest protocol header */
409 extern int max_hdr
; /* largest link+protocol header */
410 extern int max_datalen
; /* MHLEN - max_hdr */
412 int mb_check_conf(void *dp
, IPTR newvalue
);
416 BOOL
m_alloc(int howmany
, int canwait
);
417 BOOL
m_clalloc(int ncl
, int canwait
);
418 struct mbuf
* m_retry(int canwait
, int type
);
419 void m_reclaim(void);
420 struct mbuf
* m_get(int canwait
, int type
);
421 struct mbuf
* m_gethdr(int canwait
, int type
);
422 struct mbuf
* m_getclr(int canwait
, int type
);
423 struct mbuf
* m_free(struct mbuf
* m
);
424 void m_freem(struct mbuf
* m
);
425 struct mbuf
* m_prepend(struct mbuf
* m
, int len
, int canwait
);
426 struct mbuf
* m_copym(struct mbuf
* m
, int off0
, int len
, int wait
);
427 void m_copydata(struct mbuf
* m
, int off
, int len
, caddr_t cp
);
428 void m_cat(struct mbuf
* m
, struct mbuf
* n
);
429 void m_adj(struct mbuf
* mp
, int req_len
);
430 struct mbuf
* m_pullup(struct mbuf
* n
, int len
);
434 #endif /* !SYS_MBUF_H */