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