xref: /csrg-svn/sys/kern/uipc_mbuf.c (revision 4662)
1*4662Swnj /* uipc_mbuf.c 1.5 81/10/29 */
24585Swnj 
34585Swnj #include "../h/param.h"
44585Swnj #include "../h/dir.h"
54585Swnj #include "../h/user.h"
64585Swnj #include "../h/proc.h"
74585Swnj #include "../h/pte.h"
84585Swnj #include "../h/cmap.h"
94585Swnj #include "../h/map.h"
104641Swnj #include "../h/mbuf.h"
11*4662Swnj #include "../inet/inet.h"
12*4662Swnj #include "../inet/inet_systm.h"
13*4662Swnj #include "../inet/tcp.h"
14*4662Swnj #include "../inet/ip.h"
154585Swnj #include "../h/vm.h"
164585Swnj 
174585Swnj struct mbuf *
184585Swnj m_get(canwait)
194585Swnj 	int canwait;
204585Swnj {
214585Swnj 	register struct mbuf *m;
224585Swnj 
234585Swnj COUNT(M_GET);
244585Swnj 	MGET(m, canwait);
254585Swnj 	return (m);
264585Swnj }
274585Swnj 
284585Swnj struct mbuf *
294585Swnj m_free(m)
304585Swnj 	struct mbuf *m;
314585Swnj {
324585Swnj 	register struct mbuf *n;
334585Swnj 
344585Swnj COUNT(M_FREE);
354585Swnj 	MFREE(m, n);
364585Swnj 	return (n);
374585Swnj }
384585Swnj 
394585Swnj struct mbuf *
404585Swnj m_more(type)
414585Swnj 	int type;
424585Swnj {
434585Swnj 	int s;
444585Swnj 	register struct mbuf *m;
454585Swnj 
464585Swnj COUNT(M_MORE);
474585Swnj 	if (!m_expand()) {
484585Swnj 		netstat.m_drops++;
494585Swnj 		return (NULL);
504585Swnj 	}
514585Swnj #define m_more(x) ((struct mbuf *)panic("m_more"))
524585Swnj 	MGET(m, 0);
534585Swnj 	return (m);
544585Swnj }
554585Swnj 
564585Swnj m_freem(m)                      /* free mbuf chain headed by m */
574585Swnj 	register struct mbuf *m;
584585Swnj {
594585Swnj 	register struct mbuf *n;
604585Swnj 	register int s, cnt;
614585Swnj 
624585Swnj COUNT(M_FREEM);
634585Swnj 	if (m == NULL)
644585Swnj 		return (0);
654585Swnj 	cnt = 0;
66*4662Swnj 	s = splimp();
674585Swnj 	do {
684585Swnj 		MFREE(m, n);
694585Swnj 		cnt++;
704585Swnj 	} while (m = n);
714585Swnj 	splx(s);
724585Swnj 	return (cnt);
734585Swnj }
744585Swnj 
754585Swnj 
764585Swnj mbufinit()                      /* init network buffer mgmt system */
774585Swnj {
784585Swnj 	register struct mbuf *m;
794585Swnj 	register i;
804585Swnj 
814585Swnj COUNT(MBUFINIT);
824585Swnj 	m = (struct mbuf *)&netutl[0];  /* ->start of buffer virt mem */
834585Swnj 	vmemall(&Netmap[0], 2, proc, CSYS);
844585Swnj 	vmaccess(&Netmap[0], m, 2);
854585Swnj 	for (i=0; i < NMBPG; i++) {
864587Swnj 		m->m_off = 0;
874585Swnj 		m_free(m);
884585Swnj 		m++;
894585Swnj 	}
904585Swnj 	pg_alloc(3);
91*4662Swnj 	mbstat.m_pages = 4;
92*4662Swnj 	mbstat.m_bufs = 32;
93*4662Swnj 	mbstat.m_lowat = 16;
94*4662Swnj 	mbstat.m_hiwat = 32;
954585Swnj }
964585Swnj 
974585Swnj pg_alloc(n)
984585Swnj 	register int n;
994585Swnj {
1004585Swnj 	register i, j, k;
1014585Swnj 	register struct mbuf *m;
1024585Swnj 	int bufs, s;
1034585Swnj 
1044585Swnj COUNT(PG_ALLOC);
1054585Swnj 	k = n << 1;
1064585Swnj 	if ((i = rmalloc(netmap, n)) == 0)
1074585Swnj 		return (0);
1084585Swnj 	j = i<<1;
1094585Swnj 	m = pftom(i);
1104585Swnj 	/* should use vmemall sometimes */
1114585Swnj 	if (memall(&Netmap[j], k, proc, CSYS) == 0)
1124585Swnj 		return (0);
1134585Swnj 	vmaccess(&Netmap[j], (caddr_t)m, k);
1144585Swnj 	bufs = n << 3;
115*4662Swnj 	s = splimp();
1164585Swnj 	for (j=0; j < bufs; j++) {
1174587Swnj 		m->m_off = 0;
1184585Swnj 		m_free(m);
1194585Swnj 		m++;
1204585Swnj 	}
1214585Swnj 	splx(s);
122*4662Swnj 	mbstat.m_pages += n;
1234585Swnj 	return (1);
1244585Swnj }
1254585Swnj 
1264585Swnj m_expand()
1274585Swnj {
1284585Swnj 	register i;
1294585Swnj 	register struct ipq *fp;
1304585Swnj 	register struct ip *q;
1314585Swnj 	register struct tcb *tp;
1324585Swnj 	register struct mbuf *m, *n;
1334585Swnj 	int need, needp, needs;
1344585Swnj 
1354585Swnj COUNT(M_EXPAND);
136*4662Swnj 	needs = need = mbstat.m_hiwat - mbstat.m_bufs;
137*4662Swnj 	needp = need >> 3;
1384585Swnj 	if (pg_alloc(needp))
1394585Swnj 		return (1);
1404585Swnj 	for (i=0; i < needp; i++, need-=NMBPG)
1414585Swnj 		if (needp == 1 || pg_alloc(1) == 0)		/* ??? */
1424585Swnj 			goto steal;
1434585Swnj 	return (need < needs);
1444585Swnj steal:
145*4662Swnj #ifdef notdef
146*4662Swnj 	/* free fragments */
147*4662Swnj 	/* free unacks */
148*4662Swnj #endif
1494585Swnj 	return (need < needs);
1504585Swnj }
1514585Swnj 
1524585Swnj #ifdef notdef
1534585Swnj m_relse()
1544585Swnj {
155*4662Swnj COUNT(M_RELSE);
1564585Swnj 
1574585Swnj }
1584585Swnj #endif
1594585Swnj 
1604585Swnj struct mbuf *
1614585Swnj m_adj(mp, len)
1624585Swnj 	struct mbuf *mp;
1634585Swnj 	register len;
1644585Swnj {
1654585Swnj 	register struct mbuf *m, *n;
1664585Swnj 
1674585Swnj COUNT(M_ADJ);
1684585Swnj 	if ((m = mp) == NULL)
1694585Swnj 		return;
1704585Swnj 	if (len >= 0) {                 /* adjust from top of msg chain */
1714585Swnj 		while (m != NULL && len > 0) {
1724585Swnj 			if (m->m_len <= len) {          /* free this mbuf */
1734585Swnj 				len -= m->m_len;
1744585Swnj 				m->m_len = 0;
1754585Swnj 				m = m->m_next;
1764585Swnj 			} else {                        /* adjust mbuf */
1774585Swnj 				m->m_len -= len;
1784585Swnj 				m->m_off += len;
1794585Swnj 				break;
1804585Swnj 			}
1814585Swnj 		}
1824585Swnj 
1834585Swnj 	} else {                        /* adjust from bottom of msg chain */
1844585Swnj 		len = -len;
1854585Swnj 		while (len > 0 && m->m_len != 0) {
1864585Swnj 			/* find end of chain */
1874585Swnj 			while (m != NULL && m->m_len != 0) {
1884585Swnj 				n = m;
1894585Swnj 				m = m->m_next;
1904585Swnj 			}
1914585Swnj 			if (n->m_len <= len) {          /* last mbuf */
1924585Swnj 				len -= n->m_len;
1934585Swnj 				n->m_len = 0;
1944585Swnj 				m = mp;
1954585Swnj 			} else {                        /* adjust length */
1964585Swnj 				n->m_len -= len;
1974585Swnj 				break;
1984585Swnj 			}
1994585Swnj 		}
2004585Swnj 	}
2014585Swnj }
2024585Swnj 
2034585Swnj /*
2044585Swnj  * convert mbuf virtual to physical addr for uballoc
2054585Swnj  */
2064585Swnj mtophys(m)
2074585Swnj 	register struct mbuf *m;
2084585Swnj {
2094585Swnj 	register i;
2104585Swnj 	register unsigned long addr;
2114585Swnj 	register struct pte *pte;
2124585Swnj 
2134585Swnj COUNT(MTOPHYS);
2144585Swnj 	i = (((int)m & ~PGOFSET) - (int)netutl) >> PGSHIFT;
2154585Swnj 	pte = &Netmap[i];
2164585Swnj 	addr = (pte->pg_pfnum << PGSHIFT) | ((int)m & PGOFSET);
2174585Swnj 	return (addr);
2184585Swnj }
2194641Swnj 
2204641Swnj m_cat(m, n)
2214641Swnj 	register struct mbuf *m, *n;
2224641Swnj {
2234641Swnj 
2244641Swnj 	while (m->m_next)
2254641Swnj 		m = m->m_next;
2264641Swnj 	while (n)
2274641Swnj 		if (m->m_off + m->m_len + n->m_len <= MMAXOFF) {
2284643Swnj 			bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, n->m_len);
2294641Swnj 			m->m_len += n->m_len;
2304641Swnj 			n = m_free(n);
2314641Swnj 		} else {
2324641Swnj 			m->m_next = n;
2334641Swnj 			m = n;
2344641Swnj 			n = m->m_next;
2354641Swnj 		}
2364641Swnj }
237