xref: /original-bsd/sys/sys/mbuf.h (revision b7bd495c)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)mbuf.h	7.8.1.1 (Berkeley) 10/06/87
7  */
8 
9 /*
10  * Constants related to memory allocator.
11  */
12 #define	MSIZE		128			/* size of an mbuf */
13 
14 #if CLBYTES > 1024
15 #define	MCLBYTES	1024
16 #define	MCLSHIFT	10
17 #define	MCLOFSET	(MCLBYTES - 1)
18 #else
19 #define	MCLBYTES	CLBYTES
20 #define	MCLSHIFT	CLSHIFT
21 #define	MCLOFSET	CLOFSET
22 #endif
23 
24 #define	MMINOFF		12			/* mbuf header length */
25 #define	MTAIL		4
26 #define	MMAXOFF		(MSIZE-MTAIL)		/* offset where data ends */
27 #define	MLEN		(MSIZE-MMINOFF-MTAIL)	/* mbuf data length */
28 #ifdef GATEWAY
29 #define	NMBCLUSTERS	512
30 #else
31 #define	NMBCLUSTERS	256
32 #endif
33 #define	NMBPCL		(CLBYTES/MSIZE)		/* # mbufs per cluster */
34 
35 /*
36  * Macros for type conversion
37  */
38 
39 /* network cluster number to virtual address, and back */
40 #define	cltom(x) ((struct mbuf *)((int)mbutl + ((x) << MCLSHIFT)))
41 #define	mtocl(x) (((int)x - (int)mbutl) >> MCLSHIFT)
42 
43 /* address in mbuf to mbuf head */
44 #define	dtom(x)		((struct mbuf *)((int)x & ~(MSIZE-1)))
45 
46 /* mbuf head, to typed data */
47 #define	mtod(x,t)	((t)((int)(x) + (x)->m_off))
48 
49 struct mbuf {
50 	struct	mbuf *m_next;		/* next buffer in chain */
51 	u_long	m_off;			/* offset of data */
52 	short	m_len;			/* amount of data in this mbuf */
53 	short	m_type;			/* mbuf type (0 == free) */
54 	u_char	m_dat[MLEN];		/* data storage */
55 	struct	mbuf *m_act;		/* link in higher-level mbuf list */
56 };
57 
58 /* mbuf types */
59 #define	MT_FREE		0	/* should be on free list */
60 #define	MT_DATA		1	/* dynamic (data) allocation */
61 #define	MT_HEADER	2	/* packet header */
62 #define	MT_SOCKET	3	/* socket structure */
63 #define	MT_PCB		4	/* protocol control block */
64 #define	MT_RTABLE	5	/* routing tables */
65 #define	MT_HTABLE	6	/* IMP host tables */
66 #define	MT_ATABLE	7	/* address resolution tables */
67 #define	MT_SONAME	8	/* socket name */
68 #define	MT_ZOMBIE	9	/* zombie proc status */
69 #define	MT_SOOPTS	10	/* socket options */
70 #define	MT_FTABLE	11	/* fragment reassembly header */
71 #define	MT_RIGHTS	12	/* access rights */
72 #define	MT_IFADDR	13	/* interface address */
73 
74 /* flags to m_get */
75 #define	M_DONTWAIT	0
76 #define	M_WAIT		1
77 
78 /* flags to m_pgalloc */
79 #define	MPG_MBUFS	0		/* put new mbufs on free list */
80 #define	MPG_CLUSTERS	1		/* put new clusters on free list */
81 #define	MPG_SPACE	2		/* don't free; caller wants space */
82 
83 /* length to m_copy to copy all */
84 #define	M_COPYALL	1000000000
85 
86 /*
87  * m_pullup will pull up additional length if convenient;
88  * should be enough to hold headers of second-level and higher protocols.
89  */
90 #define	MPULL_EXTRA	32
91 
92 #define	MGET(m, i, t) \
93 	{ int ms = splimp(); \
94 	  if ((m)=mfree) \
95 		{ if ((m)->m_type != MT_FREE) panic("mget"); (m)->m_type = t; \
96 		  mbstat.m_mtypes[MT_FREE]--; mbstat.m_mtypes[t]++; \
97 		  mfree = (m)->m_next; (m)->m_next = 0; \
98 		  (m)->m_off = MMINOFF; } \
99 	  else \
100 		(m) = m_more(i, t); \
101 	  splx(ms); }
102 /*
103  * Mbuf page cluster macros.
104  * MCLALLOC allocates mbuf page clusters.
105  * Note that it works only with a count of 1 at the moment.
106  * MCLGET adds such clusters to a normal mbuf.
107  * m->m_len is set to MCLBYTES upon success, and to MLEN on failure.
108  * MCLFREE frees clusters allocated by MCLALLOC.
109  */
110 #define	MCLALLOC(m, i) \
111 	{ int ms = splimp(); \
112 	  if (mclfree == 0) \
113 		(void)m_clalloc((i), MPG_CLUSTERS, M_DONTWAIT); \
114 	  if ((m)=mclfree) \
115 	     {++mclrefcnt[mtocl(m)];mbstat.m_clfree--;mclfree = (m)->m_next;} \
116 	  splx(ms); }
117 #define	M_HASCL(m)	((m)->m_off >= MSIZE)
118 #define	MTOCL(m)	((struct mbuf *)(mtod((m), int) &~ MCLOFSET))
119 
120 #define	MCLGET(m) \
121 	{ struct mbuf *p; \
122 	  MCLALLOC(p, 1); \
123 	  if (p) { \
124 		(m)->m_off = (int)p - (int)(m); \
125 		(m)->m_len = MCLBYTES; \
126 	  } else \
127 		(m)->m_len = MLEN; \
128 	}
129 #define	MCLFREE(m) { \
130 	if (--mclrefcnt[mtocl(m)] == 0) \
131 	    { (m)->m_next = mclfree;mclfree = (m);mbstat.m_clfree++;} \
132 	}
133 #define	MFREE(m, n) \
134 	{ int ms = splimp(); \
135 	  if ((m)->m_type == MT_FREE) panic("mfree"); \
136 	  mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[MT_FREE]++; \
137 	  (m)->m_type = MT_FREE; \
138 	  if (M_HASCL(m)) { \
139 		(n) = MTOCL(m); \
140 		MCLFREE(n); \
141 	  } \
142 	  (n) = (m)->m_next; (m)->m_next = mfree; \
143 	  (m)->m_off = 0; (m)->m_act = 0; mfree = (m); \
144 	  splx(ms); \
145 	  if (m_want) { \
146 		  m_want = 0; \
147 		  wakeup((caddr_t)&mfree); \
148 	  } \
149 	}
150 
151 /*
152  * Mbuf statistics.
153  */
154 struct mbstat {
155 	u_long	m_mbufs;	/* mbufs obtained from page pool */
156 	u_long	m_clusters;	/* clusters obtained from page pool */
157 	u_long	m_space;	/* interface pages obtained from page pool */
158 	u_long	m_clfree;	/* free clusters */
159 	u_long	m_drops;	/* times failed to find space */
160 	u_long	m_wait;		/* times waited for space */
161 	u_long	m_drain;	/* times drained protocols for space */
162 	u_short	m_mtypes[256];	/* type specific mbuf allocations */
163 };
164 
165 #ifdef	KERNEL
166 extern	struct mbuf mbutl[];		/* virtual address of net free mem */
167 extern	struct pte Mbmap[];		/* page tables to map Netutl */
168 struct	mbstat mbstat;
169 int	nmbclusters;
170 struct	mbuf *mfree, *mclfree;
171 char	mclrefcnt[NMBCLUSTERS + 1];
172 int	m_want;
173 struct	mbuf *m_get(),*m_getclr(),*m_free(),*m_more(),*m_copy(),*m_pullup();
174 caddr_t	m_clalloc();
175 #endif
176