1*4890Swnj /* uipc_mbuf.c 1.9 81/11/14 */ 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" 114822Swnj #include "../net/inet_systm.h" /* ### */ 124585Swnj #include "../h/vm.h" 134585Swnj 144732Swnj m_reserve(mbufs) 154732Swnj int mbufs; 164732Swnj { 174732Swnj 184822Swnj if (mbstat.m_lowat + mbufs > NMBPAGES * NMBPG - 32) 194732Swnj return (0); 204732Swnj mbstat.m_lowat += mbufs; 214732Swnj mbstat.m_hiwat = 2 * mbstat.m_lowat; 224732Swnj } 234732Swnj 244732Swnj m_release(mbufs) 254732Swnj int mbufs; 264732Swnj { 274732Swnj 284732Swnj mbstat.m_lowat -= mbufs; 294732Swnj mbstat.m_hiwat = 2 * mbstat.m_lowat; 304732Swnj } 314732Swnj 324585Swnj struct mbuf * 334585Swnj m_get(canwait) 344585Swnj int canwait; 354585Swnj { 364585Swnj register struct mbuf *m; 374585Swnj 384585Swnj COUNT(M_GET); 394585Swnj MGET(m, canwait); 404585Swnj return (m); 414585Swnj } 424585Swnj 434585Swnj struct mbuf * 44*4890Swnj m_getclr(canwait) 45*4890Swnj int canwait; 46*4890Swnj { 47*4890Swnj register struct mbuf *m; 48*4890Swnj 49*4890Swnj COUNT(M_GETCLR); 50*4890Swnj m = m_get(m, canwait); 51*4890Swnj if (m == 0) 52*4890Swnj return (0); 53*4890Swnj m->m_off = MMINOFF; 54*4890Swnj bzero(mtod(m, caddr_t), MLEN); 55*4890Swnj return (m); 56*4890Swnj } 57*4890Swnj 58*4890Swnj struct mbuf * 594585Swnj m_free(m) 604585Swnj struct mbuf *m; 614585Swnj { 624585Swnj register struct mbuf *n; 634585Swnj 644585Swnj COUNT(M_FREE); 654585Swnj MFREE(m, n); 664585Swnj return (n); 674585Swnj } 684585Swnj 694585Swnj struct mbuf * 704585Swnj m_more(type) 714585Swnj int type; 724585Swnj { 734585Swnj int s; 744585Swnj register struct mbuf *m; 754585Swnj 764585Swnj COUNT(M_MORE); 774585Swnj if (!m_expand()) { 784822Swnj mbstat.m_drops++; 794585Swnj return (NULL); 804585Swnj } 814585Swnj #define m_more(x) ((struct mbuf *)panic("m_more")) 824585Swnj MGET(m, 0); 834585Swnj return (m); 844585Swnj } 854585Swnj 864669Swnj m_freem(m) 874585Swnj register struct mbuf *m; 884585Swnj { 894585Swnj register struct mbuf *n; 904585Swnj register int s, cnt; 914585Swnj 924585Swnj COUNT(M_FREEM); 934585Swnj if (m == NULL) 944585Swnj return (0); 954585Swnj cnt = 0; 964662Swnj s = splimp(); 974585Swnj do { 984669Swnj if (m->m_off > MMAXOFF) 994669Swnj cnt += NMBPG; 1004669Swnj cnt++; 1014585Swnj MFREE(m, n); 1024585Swnj } while (m = n); 1034585Swnj splx(s); 1044585Swnj return (cnt); 1054585Swnj } 1064585Swnj 1074822Swnj mbinit() 1084585Swnj { 1094585Swnj register struct mbuf *m; 1104585Swnj register i; 1114585Swnj 1124585Swnj COUNT(MBUFINIT); 1134822Swnj m = (struct mbuf *)&mbutl[0]; /* ->start of buffer virt mem */ 1144822Swnj vmemall(&Mbmap[0], 2, proc, CSYS); 1154822Swnj vmaccess(&Mbmap[0], m, 2); 1164585Swnj for (i=0; i < NMBPG; i++) { 1174587Swnj m->m_off = 0; 1184585Swnj m_free(m); 1194585Swnj m++; 1204585Swnj } 1214585Swnj pg_alloc(3); 1224662Swnj mbstat.m_pages = 4; 1234662Swnj mbstat.m_bufs = 32; 1244662Swnj mbstat.m_lowat = 16; 1254662Swnj mbstat.m_hiwat = 32; 1264669Swnj { int i,j,k,n; 1274669Swnj n = 32; 1284669Swnj k = n << 1; 1294822Swnj if ((i = rmalloc(mbmap, n)) == 0) 1304669Swnj return (0); 1314669Swnj j = i<<1; 1324669Swnj m = pftom(i); 1334669Swnj /* should use vmemall sometimes */ 1344822Swnj if (memall(&Mbmap[j], k, proc, CSYS) == 0) { 1354669Swnj printf("botch\n"); 1364669Swnj return; 1374669Swnj } 1384822Swnj vmaccess(&Mbmap[j], (caddr_t)m, k); 1394669Swnj for (j=0; j < n; j++) { 1404669Swnj m->m_off = 0; 1414669Swnj m->m_next = mpfree; 1424669Swnj mpfree = m; 1434669Swnj m += NMBPG; 1444669Swnj nmpfree++; 1454669Swnj } 1464669Swnj } 1474585Swnj } 1484585Swnj 1494585Swnj pg_alloc(n) 1504585Swnj register int n; 1514585Swnj { 1524585Swnj register i, j, k; 1534585Swnj register struct mbuf *m; 1544585Swnj int bufs, s; 1554585Swnj 1564585Swnj COUNT(PG_ALLOC); 1574585Swnj k = n << 1; 1584822Swnj if ((i = rmalloc(mbmap, n)) == 0) 1594585Swnj return (0); 1604585Swnj j = i<<1; 1614585Swnj m = pftom(i); 1624585Swnj /* should use vmemall sometimes */ 1634822Swnj if (memall(&Mbmap[j], k, proc, CSYS) == 0) 1644585Swnj return (0); 1654822Swnj vmaccess(&Mbmap[j], (caddr_t)m, k); 1664585Swnj bufs = n << 3; 1674662Swnj s = splimp(); 1684585Swnj for (j=0; j < bufs; j++) { 1694587Swnj m->m_off = 0; 1704585Swnj m_free(m); 1714585Swnj m++; 1724585Swnj } 1734585Swnj splx(s); 1744662Swnj mbstat.m_pages += n; 1754585Swnj return (1); 1764585Swnj } 1774585Swnj 1784585Swnj m_expand() 1794585Swnj { 1804585Swnj register i; 1814585Swnj register struct mbuf *m, *n; 1824585Swnj int need, needp, needs; 1834585Swnj 1844585Swnj COUNT(M_EXPAND); 1854662Swnj needs = need = mbstat.m_hiwat - mbstat.m_bufs; 1864662Swnj needp = need >> 3; 1874585Swnj if (pg_alloc(needp)) 1884585Swnj return (1); 1894669Swnj for (i=0; i < needp; i++, need -= NMBPG) 1904669Swnj if (pg_alloc(1) == 0) 1914585Swnj goto steal; 1924585Swnj return (need < needs); 1934585Swnj steal: 1944669Swnj /* while (not enough) ask protocols to free code */ 1954669Swnj ; 1964585Swnj } 1974585Swnj 1984585Swnj #ifdef notdef 1994585Swnj m_relse() 2004585Swnj { 2014669Swnj 2024662Swnj COUNT(M_RELSE); 2034585Swnj } 2044585Swnj #endif 2054585Swnj 2064669Swnj m_cat(m, n) 2074669Swnj register struct mbuf *m, *n; 2084669Swnj { 2094669Swnj 2104669Swnj while (m->m_next) 2114669Swnj m = m->m_next; 2124669Swnj while (n) 2134669Swnj if (m->m_off + m->m_len + n->m_len <= MMAXOFF) { 2144669Swnj bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, n->m_len); 2154669Swnj m->m_len += n->m_len; 2164669Swnj n = m_free(n); 2174669Swnj } else { 2184669Swnj m->m_next = n; 2194669Swnj m = n; 2204669Swnj n = m->m_next; 2214669Swnj } 2224669Swnj } 2234669Swnj 2244585Swnj m_adj(mp, len) 2254585Swnj struct mbuf *mp; 2264585Swnj register len; 2274585Swnj { 2284585Swnj register struct mbuf *m, *n; 2294585Swnj 2304585Swnj COUNT(M_ADJ); 2314585Swnj if ((m = mp) == NULL) 2324585Swnj return; 2334822Swnj if (len >= 0) { 2344585Swnj while (m != NULL && len > 0) { 2354822Swnj if (m->m_len <= len) { 2364585Swnj len -= m->m_len; 2374585Swnj m->m_len = 0; 2384585Swnj m = m->m_next; 2394822Swnj } else { 2404585Swnj m->m_len -= len; 2414585Swnj m->m_off += len; 2424585Swnj break; 2434585Swnj } 2444585Swnj } 2454822Swnj } else { 2464822Swnj /* a 2 pass algorithm might be better */ 2474585Swnj len = -len; 2484585Swnj while (len > 0 && m->m_len != 0) { 2494585Swnj while (m != NULL && m->m_len != 0) { 2504585Swnj n = m; 2514585Swnj m = m->m_next; 2524585Swnj } 2534822Swnj if (n->m_len <= len) { 2544585Swnj len -= n->m_len; 2554585Swnj n->m_len = 0; 2564585Swnj m = mp; 2574822Swnj } else { 2584585Swnj n->m_len -= len; 2594585Swnj break; 2604585Swnj } 2614585Swnj } 2624585Swnj } 2634585Swnj } 264