/* * Copyright (c) 1982, 1986 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * * @(#)mbuf.h 7.1 (Berkeley) 6/4/86 */ /* * Constants related to memory allocator. */ #define MSIZE 128 /* size of an mbuf */ #define MMINOFF 12 /* mbuf header length */ #define MTAIL 4 #define MMAXOFF (MSIZE-MTAIL) /* offset where data ends */ #define MLEN (MSIZE-MMINOFF-MTAIL) /* mbuf data length */ #define NMBCLUSTERS 256 #define NMBPCL (CLBYTES/MSIZE) /* # mbufs per cluster */ /* * Macros for type conversion */ /* network cluster number to virtual address, and back */ #define cltom(x) ((struct mbuf *)((int)mbutl + ((x) << CLSHIFT))) #define mtocl(x) (((int)x - (int)mbutl) >> CLSHIFT) /* address in mbuf to mbuf head */ #define dtom(x) ((struct mbuf *)((int)x & ~(MSIZE-1))) /* mbuf head, to typed data */ #define mtod(x,t) ((t)((int)(x) + (x)->m_off)) struct mbuf { struct mbuf *m_next; /* next buffer in chain */ u_long m_off; /* offset of data */ short m_len; /* amount of data in this mbuf */ short m_type; /* mbuf type (0 == free) */ u_char m_dat[MLEN]; /* data storage */ struct mbuf *m_act; /* link in higher-level mbuf list */ }; /* mbuf types */ #define MT_FREE 0 /* should be on free list */ #define MT_DATA 1 /* dynamic (data) allocation */ #define MT_HEADER 2 /* packet header */ #define MT_SOCKET 3 /* socket structure */ #define MT_PCB 4 /* protocol control block */ #define MT_RTABLE 5 /* routing tables */ #define MT_HTABLE 6 /* IMP host tables */ #define MT_ATABLE 7 /* address resolution tables */ #define MT_SONAME 8 /* socket name */ #define MT_ZOMBIE 9 /* zombie proc status */ #define MT_SOOPTS 10 /* socket options */ #define MT_FTABLE 11 /* fragment reassembly header */ #define MT_RIGHTS 12 /* access rights */ #define MT_IFADDR 13 /* interface address */ /* flags to m_get */ #define M_DONTWAIT 0 #define M_WAIT 1 /* flags to m_pgalloc */ #define MPG_MBUFS 0 /* put new mbufs on free list */ #define MPG_CLUSTERS 1 /* put new clusters on free list */ #define MPG_SPACE 2 /* don't free; caller wants space */ /* length to m_copy to copy all */ #define M_COPYALL 1000000000 /* * m_pullup will pull up additional length if convenient; * should be enough to hold headers of second-level and higher protocols. */ #define MPULL_EXTRA 32 #define MGET(m, i, t) \ { int ms = splimp(); \ if ((m)=mfree) \ { if ((m)->m_type != MT_FREE) panic("mget"); (m)->m_type = t; \ mbstat.m_mtypes[MT_FREE]--; mbstat.m_mtypes[t]++; \ mfree = (m)->m_next; (m)->m_next = 0; \ (m)->m_off = MMINOFF; } \ else \ (m) = m_more(i, t); \ splx(ms); } /* * Mbuf page cluster macros. * MCLALLOC allocates mbuf page clusters. * Note that it works only with a count of 1 at the moment. * MCLGET adds such clusters to a normal mbuf. * m->m_len is set to CLBYTES upon success. * MCLFREE frees clusters allocated by MCLALLOC. */ #define MCLALLOC(m, i) \ { int ms = splimp(); \ if ((m)=mclfree) \ {++mclrefcnt[mtocl(m)];mbstat.m_clfree--;mclfree = (m)->m_next;} \ splx(ms); } #define M_HASCL(m) ((m)->m_off >= MSIZE) #define MTOCL(m) ((struct mbuf *)(mtod((m), int)&~CLOFSET)) #define MCLGET(m) \ { struct mbuf *p; \ if (mclfree == 0) \ (void)m_clalloc(1, MPG_CLUSTERS, M_DONTWAIT); \ MCLALLOC(p, 1); \ if (p) { \ (m)->m_off = (int)p - (int)(m); \ (m)->m_len = CLBYTES; \ } \ } #define MCLFREE(m) { \ if (--mclrefcnt[mtocl(m)] == 0) \ { (m)->m_next = mclfree;mclfree = (m);mbstat.m_clfree++;} \ } #define MFREE(m, n) \ { int ms = splimp(); \ if ((m)->m_type == MT_FREE) panic("mfree"); \ mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[MT_FREE]++; \ (m)->m_type = MT_FREE; \ if (M_HASCL(m)) { \ (n) = MTOCL(m); \ MCLFREE(n); \ } \ (n) = (m)->m_next; (m)->m_next = mfree; \ (m)->m_off = 0; (m)->m_act = 0; mfree = (m); \ splx(ms); \ if (m_want) { \ m_want = 0; \ wakeup((caddr_t)&mfree); \ } \ } /* * Mbuf statistics. */ struct mbstat { short m_mbufs; /* mbufs obtained from page pool */ short m_clusters; /* clusters obtained from page pool */ short m_clfree; /* free clusters */ short m_drops; /* times failed to find space */ short m_mtypes[256]; /* type specific mbuf allocations */ }; #ifdef KERNEL extern struct mbuf mbutl[]; /* virtual address of net free mem */ extern struct pte Mbmap[]; /* page tables to map Netutl */ struct mbstat mbstat; int nmbclusters; struct mbuf *mfree, *mclfree; char mclrefcnt[NMBCLUSTERS + 1]; int m_want; struct mbuf *m_get(),*m_getclr(),*m_free(),*m_more(),*m_copy(),*m_pullup(); caddr_t m_clalloc(); #endif