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