1*4916Swnj /* uipc_mbuf.c 1.10 81/11/16 */ 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*4916Swnj #include "../net/inet_systm.h" /* XXX */ 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; 22*4916Swnj return (1); 234732Swnj } 244732Swnj 254732Swnj m_release(mbufs) 264732Swnj int mbufs; 274732Swnj { 284732Swnj 294732Swnj mbstat.m_lowat -= mbufs; 304732Swnj mbstat.m_hiwat = 2 * mbstat.m_lowat; 314732Swnj } 324732Swnj 334585Swnj struct mbuf * 344585Swnj m_get(canwait) 354585Swnj int canwait; 364585Swnj { 374585Swnj register struct mbuf *m; 384585Swnj 394585Swnj COUNT(M_GET); 404585Swnj MGET(m, canwait); 414585Swnj return (m); 424585Swnj } 434585Swnj 444585Swnj struct mbuf * 454890Swnj m_getclr(canwait) 464890Swnj int canwait; 474890Swnj { 484890Swnj register struct mbuf *m; 494890Swnj 504890Swnj COUNT(M_GETCLR); 51*4916Swnj m = m_get(canwait); 524890Swnj if (m == 0) 534890Swnj return (0); 544890Swnj m->m_off = MMINOFF; 554890Swnj bzero(mtod(m, caddr_t), MLEN); 564890Swnj return (m); 574890Swnj } 584890Swnj 594890Swnj struct mbuf * 604585Swnj m_free(m) 614585Swnj struct mbuf *m; 624585Swnj { 634585Swnj register struct mbuf *n; 644585Swnj 654585Swnj COUNT(M_FREE); 664585Swnj MFREE(m, n); 674585Swnj return (n); 684585Swnj } 694585Swnj 70*4916Swnj /*ARGSUSED*/ 714585Swnj struct mbuf * 724585Swnj m_more(type) 734585Swnj int type; 744585Swnj { 754585Swnj register struct mbuf *m; 764585Swnj 774585Swnj COUNT(M_MORE); 784585Swnj if (!m_expand()) { 794822Swnj mbstat.m_drops++; 804585Swnj return (NULL); 814585Swnj } 82*4916Swnj #define m_more(x) (panic("m_more"), (struct mbuf *)0) 83*4916Swnj MGET(m, type); 844585Swnj return (m); 854585Swnj } 864585Swnj 874669Swnj m_freem(m) 884585Swnj register struct mbuf *m; 894585Swnj { 904585Swnj register struct mbuf *n; 91*4916Swnj register int s, i; 924585Swnj 934585Swnj COUNT(M_FREEM); 944585Swnj if (m == NULL) 95*4916Swnj return; 96*4916Swnj i = 0; 974662Swnj s = splimp(); 984585Swnj do { 994669Swnj if (m->m_off > MMAXOFF) 100*4916Swnj i += NMBPG; 101*4916Swnj i++; 1024585Swnj MFREE(m, n); 1034585Swnj } while (m = n); 1044585Swnj splx(s); 105*4916Swnj return; 1064585Swnj } 1074585Swnj 1084822Swnj mbinit() 1094585Swnj { 1104585Swnj register struct mbuf *m; 1114585Swnj register i; 1124585Swnj 1134585Swnj COUNT(MBUFINIT); 1144822Swnj m = (struct mbuf *)&mbutl[0]; /* ->start of buffer virt mem */ 115*4916Swnj (void) vmemall(&Mbmap[0], 2, proc, CSYS); 116*4916Swnj vmaccess(&Mbmap[0], (caddr_t)m, 2); 1174585Swnj for (i=0; i < NMBPG; i++) { 1184587Swnj m->m_off = 0; 1194585Swnj m_free(m); 1204585Swnj m++; 1214585Swnj } 122*4916Swnj (void) pg_alloc(3); 1234662Swnj mbstat.m_pages = 4; 1244662Swnj mbstat.m_bufs = 32; 1254662Swnj mbstat.m_lowat = 16; 1264662Swnj mbstat.m_hiwat = 32; 127*4916Swnj { int j,k,n; 1284669Swnj n = 32; 1294669Swnj k = n << 1; 1304822Swnj if ((i = rmalloc(mbmap, n)) == 0) 131*4916Swnj panic("mbinit"); 1324669Swnj j = i<<1; 1334669Swnj m = pftom(i); 1344669Swnj /* should use vmemall sometimes */ 1354822Swnj if (memall(&Mbmap[j], k, proc, CSYS) == 0) { 1364669Swnj printf("botch\n"); 1374669Swnj return; 1384669Swnj } 1394822Swnj vmaccess(&Mbmap[j], (caddr_t)m, k); 1404669Swnj for (j=0; j < n; j++) { 1414669Swnj m->m_off = 0; 1424669Swnj m->m_next = mpfree; 1434669Swnj mpfree = m; 1444669Swnj m += NMBPG; 1454669Swnj nmpfree++; 1464669Swnj } 1474669Swnj } 1484585Swnj } 1494585Swnj 1504585Swnj pg_alloc(n) 1514585Swnj register int n; 1524585Swnj { 1534585Swnj register i, j, k; 1544585Swnj register struct mbuf *m; 1554585Swnj int bufs, s; 1564585Swnj 1574585Swnj COUNT(PG_ALLOC); 1584585Swnj k = n << 1; 1594822Swnj if ((i = rmalloc(mbmap, n)) == 0) 1604585Swnj return (0); 1614585Swnj j = i<<1; 1624585Swnj m = pftom(i); 1634585Swnj /* should use vmemall sometimes */ 1644822Swnj if (memall(&Mbmap[j], k, proc, CSYS) == 0) 1654585Swnj return (0); 1664822Swnj vmaccess(&Mbmap[j], (caddr_t)m, k); 1674585Swnj bufs = n << 3; 1684662Swnj s = splimp(); 1694585Swnj for (j=0; j < bufs; j++) { 1704587Swnj m->m_off = 0; 1714585Swnj m_free(m); 1724585Swnj m++; 1734585Swnj } 1744585Swnj splx(s); 1754662Swnj mbstat.m_pages += n; 1764585Swnj return (1); 1774585Swnj } 1784585Swnj 1794585Swnj m_expand() 1804585Swnj { 1814585Swnj register i; 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 ; 196*4916Swnj return (0); 1974585Swnj } 1984585Swnj 1994585Swnj #ifdef notdef 2004585Swnj m_relse() 2014585Swnj { 2024669Swnj 2034662Swnj COUNT(M_RELSE); 2044585Swnj } 2054585Swnj #endif 2064585Swnj 2074669Swnj m_cat(m, n) 2084669Swnj register struct mbuf *m, *n; 2094669Swnj { 2104669Swnj 2114669Swnj while (m->m_next) 2124669Swnj m = m->m_next; 2134669Swnj while (n) 2144669Swnj if (m->m_off + m->m_len + n->m_len <= MMAXOFF) { 215*4916Swnj bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, 216*4916Swnj (u_int)n->m_len); 2174669Swnj m->m_len += n->m_len; 2184669Swnj n = m_free(n); 2194669Swnj } else { 2204669Swnj m->m_next = n; 2214669Swnj m = n; 2224669Swnj n = m->m_next; 2234669Swnj } 2244669Swnj } 2254669Swnj 2264585Swnj m_adj(mp, len) 2274585Swnj struct mbuf *mp; 228*4916Swnj register int len; 2294585Swnj { 2304585Swnj register struct mbuf *m, *n; 2314585Swnj 2324585Swnj COUNT(M_ADJ); 2334585Swnj if ((m = mp) == NULL) 2344585Swnj return; 2354822Swnj if (len >= 0) { 2364585Swnj while (m != NULL && len > 0) { 2374822Swnj if (m->m_len <= len) { 2384585Swnj len -= m->m_len; 2394585Swnj m->m_len = 0; 2404585Swnj m = m->m_next; 2414822Swnj } else { 2424585Swnj m->m_len -= len; 2434585Swnj m->m_off += len; 2444585Swnj break; 2454585Swnj } 2464585Swnj } 2474822Swnj } else { 2484822Swnj /* a 2 pass algorithm might be better */ 2494585Swnj len = -len; 2504585Swnj while (len > 0 && m->m_len != 0) { 2514585Swnj while (m != NULL && m->m_len != 0) { 2524585Swnj n = m; 2534585Swnj m = m->m_next; 2544585Swnj } 2554822Swnj if (n->m_len <= len) { 2564585Swnj len -= n->m_len; 2574585Swnj n->m_len = 0; 2584585Swnj m = mp; 2594822Swnj } else { 2604585Swnj n->m_len -= len; 2614585Swnj break; 2624585Swnj } 2634585Swnj } 2644585Swnj } 2654585Swnj } 266