1*5228Swnj /* uipc_mbuf.c 1.19 81/12/09 */ 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" 115090Swnj #include "../net/in_systm.h" /* XXX */ 124585Swnj #include "../h/vm.h" 134585Swnj 14*5228Swnj mbinit() 15*5228Swnj { 16*5228Swnj register struct mbuf *m; 17*5228Swnj register i; 18*5228Swnj 19*5228Swnj COUNT(MBINIT); 20*5228Swnj if (m_reserve(32) == 0) 21*5228Swnj goto bad; 22*5228Swnj if (m_clalloc(4, MPG_MBUFS) == 0) 23*5228Swnj goto bad; 24*5228Swnj if (m_clalloc(32, MPG_CLUSTERS) == 0) 25*5228Swnj goto bad; 26*5228Swnj return; 27*5228Swnj bad: 28*5228Swnj panic("mbinit"); 29*5228Swnj } 30*5228Swnj 31*5228Swnj caddr_t 32*5228Swnj m_clalloc(ncl, how) 33*5228Swnj register int ncl; 34*5228Swnj int how; 35*5228Swnj { 36*5228Swnj int npg, mbx; 37*5228Swnj register struct mbuf *m; 38*5228Swnj register int i; 39*5228Swnj int s; 40*5228Swnj 41*5228Swnj COUNT(M_CLALLOC); 42*5228Swnj npg = ncl * CLSIZE; 43*5228Swnj mbx = rmalloc(mbmap, npg); 44*5228Swnj printf("ncl %d how %d npg %d mbx %d\n", ncl, how, npg, mbx); 45*5228Swnj if (mbx == 0) 46*5228Swnj return (0); 47*5228Swnj m = cltom(mbx / CLSIZE); 48*5228Swnj if (memall(&Mbmap[mbx], ncl * CLSIZE, proc, CSYS) == 0) 49*5228Swnj return (0); 50*5228Swnj vmaccess(&Mbmap[mbx], (caddr_t)m, npg); 51*5228Swnj printf("m %x &Mbmap[mbx] %x\n", m, &Mbmap[mbx]); 52*5228Swnj switch (how) { 53*5228Swnj 54*5228Swnj case MPG_CLUSTERS: 55*5228Swnj s = splimp(); 56*5228Swnj for (i = 0; i < ncl; i++) { 57*5228Swnj m->m_off = 0; 58*5228Swnj m->m_next = mclfree; 59*5228Swnj mclfree = m; 60*5228Swnj m += CLBYTES / sizeof (*m); 61*5228Swnj nmclfree++; 62*5228Swnj } 63*5228Swnj mbstat.m_clusters += ncl; 64*5228Swnj splx(s); 65*5228Swnj break; 66*5228Swnj 67*5228Swnj case MPG_MBUFS: 68*5228Swnj for (i = ncl * CLBYTES / sizeof (*m); i > 0; i--) { 69*5228Swnj m->m_off = 0; 70*5228Swnj (void) m_free(m); 71*5228Swnj m++; 72*5228Swnj } 73*5228Swnj mbstat.m_clusters += ncl; 74*5228Swnj } 75*5228Swnj return ((caddr_t)m); 76*5228Swnj } 77*5228Swnj 78*5228Swnj m_pgfree(addr, n) 79*5228Swnj caddr_t addr; 80*5228Swnj int n; 81*5228Swnj { 82*5228Swnj 83*5228Swnj COUNT(M_PGFREE); 84*5228Swnj printf("m_pgfree %x %d\n", addr, n); 85*5228Swnj } 86*5228Swnj 87*5228Swnj m_expand() 88*5228Swnj { 89*5228Swnj 90*5228Swnj COUNT(M_EXPAND); 91*5228Swnj if (mbstat.m_bufs >= mbstat.m_hiwat) 92*5228Swnj return (0); 93*5228Swnj if (m_clalloc(1, MPG_MBUFS) == 0) 94*5228Swnj goto steal; 95*5228Swnj return (1); 96*5228Swnj steal: 97*5228Swnj /* should ask protocols to free code */ 98*5228Swnj return (0); 99*5228Swnj } 100*5228Swnj 101*5228Swnj /* NEED SOME WAY TO RELEASE SPACE */ 102*5228Swnj 103*5228Swnj /* 104*5228Swnj * Space reservation routines 105*5228Swnj */ 1065015Sroot m_reserve(mbufs) 1075015Sroot int mbufs; 1084732Swnj { 1094732Swnj 1105147Swnj if (mbstat.m_lowat + (mbufs>>1) > (NMBCLUSTERS-32) * CLBYTES) 1114732Swnj return (0); 1125016Swnj mbstat.m_hiwat += mbufs; 1135016Swnj mbstat.m_lowat = mbstat.m_hiwat >> 1; 1144916Swnj return (1); 1154732Swnj } 1164732Swnj 1175015Sroot m_release(mbufs) 1185015Sroot int mbufs; 1194732Swnj { 1204732Swnj 1215016Swnj mbstat.m_hiwat -= mbufs; 1225016Swnj mbstat.m_lowat = mbstat.m_hiwat >> 1; 1234732Swnj } 1244732Swnj 125*5228Swnj /* 126*5228Swnj * Space allocation routines. 127*5228Swnj * These are also available as macros 128*5228Swnj * for critical paths. 129*5228Swnj */ 1304585Swnj struct mbuf * 1314585Swnj m_get(canwait) 1324585Swnj int canwait; 1334585Swnj { 1344585Swnj register struct mbuf *m; 1354585Swnj 1364585Swnj COUNT(M_GET); 1374585Swnj MGET(m, canwait); 1384585Swnj return (m); 1394585Swnj } 1404585Swnj 1414585Swnj struct mbuf * 1424890Swnj m_getclr(canwait) 1434890Swnj int canwait; 1444890Swnj { 1454890Swnj register struct mbuf *m; 1464890Swnj 1474890Swnj COUNT(M_GETCLR); 1484916Swnj m = m_get(canwait); 1494890Swnj if (m == 0) 1504890Swnj return (0); 1514890Swnj m->m_off = MMINOFF; 1524890Swnj bzero(mtod(m, caddr_t), MLEN); 1534890Swnj return (m); 1544890Swnj } 1554890Swnj 1564890Swnj struct mbuf * 1574585Swnj m_free(m) 1584585Swnj struct mbuf *m; 1594585Swnj { 1604585Swnj register struct mbuf *n; 1614585Swnj 1624585Swnj COUNT(M_FREE); 1634585Swnj MFREE(m, n); 1644585Swnj return (n); 1654585Swnj } 1664585Swnj 1674916Swnj /*ARGSUSED*/ 1684585Swnj struct mbuf * 1694585Swnj m_more(type) 1704585Swnj int type; 1714585Swnj { 1724585Swnj register struct mbuf *m; 1734585Swnj 1744585Swnj COUNT(M_MORE); 1754585Swnj if (!m_expand()) { 1764822Swnj mbstat.m_drops++; 1774585Swnj return (NULL); 1784585Swnj } 1794916Swnj #define m_more(x) (panic("m_more"), (struct mbuf *)0) 1804916Swnj MGET(m, type); 1814585Swnj return (m); 1824585Swnj } 1834585Swnj 1844669Swnj m_freem(m) 1854585Swnj register struct mbuf *m; 1864585Swnj { 1874585Swnj register struct mbuf *n; 1884927Swnj register int s; 1894585Swnj 1904585Swnj COUNT(M_FREEM); 1914585Swnj if (m == NULL) 1924916Swnj return; 1934662Swnj s = splimp(); 1944585Swnj do { 1954585Swnj MFREE(m, n); 1964585Swnj } while (m = n); 1974585Swnj splx(s); 1984585Swnj } 1994585Swnj 200*5228Swnj /* 201*5228Swnj * Mbuffer utility routines. 202*5228Swnj */ 2034927Swnj struct mbuf * 2044927Swnj m_copy(m, off, len) 2054927Swnj register struct mbuf *m; 2064927Swnj int off; 2074927Swnj register int len; 2084927Swnj { 2094927Swnj register struct mbuf *n, **np; 2104927Swnj struct mbuf *top, *p; 2114927Swnj COUNT(M_COPY); 2124927Swnj 2134927Swnj if (len == 0) 2144927Swnj return (0); 2154927Swnj if (off < 0 || len < 0) 2164927Swnj panic("m_copy"); 2174927Swnj while (off > 0) { 2184927Swnj if (m == 0) 2194927Swnj panic("m_copy"); 2204927Swnj if (off < m->m_len) 2214927Swnj break; 2224927Swnj off -= m->m_len; 2234927Swnj m = m->m_next; 2244927Swnj } 2254927Swnj np = ⊤ 2264927Swnj top = 0; 2274927Swnj while (len > 0) { 2284927Swnj MGET(n, 1); 2294927Swnj *np = n; 2304927Swnj if (n == 0) 2314927Swnj goto nospace; 2324927Swnj if (m == 0) 2334927Swnj panic("m_copy"); 2344927Swnj n->m_len = MIN(len, m->m_len - off); 2354927Swnj if (m->m_off > MMAXOFF) { 2364927Swnj p = mtod(m, struct mbuf *); 2374927Swnj n->m_off = ((int)p - (int)n) + off; 2385090Swnj mclrefcnt[mtocl(p)]++; 2394927Swnj } else { 2404927Swnj n->m_off = MMINOFF; 2414927Swnj bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t), 2424927Swnj (unsigned)n->m_len); 2434927Swnj } 2444927Swnj len -= n->m_len; 2454927Swnj off = 0; 2464927Swnj m = m->m_next; 2474927Swnj np = &n->m_next; 2484927Swnj } 2494927Swnj return (top); 2504927Swnj nospace: 2514927Swnj printf("m_copy: no space\n"); 2524927Swnj m_freem(top); 2534927Swnj return (0); 2544927Swnj } 2554927Swnj 2564669Swnj m_cat(m, n) 2574669Swnj register struct mbuf *m, *n; 2584669Swnj { 2594669Swnj 2604669Swnj while (m->m_next) 2614669Swnj m = m->m_next; 2624669Swnj while (n) 2634669Swnj if (m->m_off + m->m_len + n->m_len <= MMAXOFF) { 2644916Swnj bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, 2654916Swnj (u_int)n->m_len); 2664669Swnj m->m_len += n->m_len; 2674669Swnj n = m_free(n); 2684669Swnj } else { 2694669Swnj m->m_next = n; 2704669Swnj m = n; 2714669Swnj n = m->m_next; 2724669Swnj } 2734669Swnj } 2744669Swnj 2754585Swnj m_adj(mp, len) 2764585Swnj struct mbuf *mp; 2774916Swnj register int len; 2784585Swnj { 2794585Swnj register struct mbuf *m, *n; 2804585Swnj 2814585Swnj COUNT(M_ADJ); 2824585Swnj if ((m = mp) == NULL) 2834585Swnj return; 2844822Swnj if (len >= 0) { 2854585Swnj while (m != NULL && len > 0) { 2864822Swnj if (m->m_len <= len) { 2874585Swnj len -= m->m_len; 2884585Swnj m->m_len = 0; 2894585Swnj m = m->m_next; 2904822Swnj } else { 2914585Swnj m->m_len -= len; 2924585Swnj m->m_off += len; 2934585Swnj break; 2944585Swnj } 2954585Swnj } 2964822Swnj } else { 2974822Swnj /* a 2 pass algorithm might be better */ 2984585Swnj len = -len; 2994585Swnj while (len > 0 && m->m_len != 0) { 3004585Swnj while (m != NULL && m->m_len != 0) { 3014585Swnj n = m; 3024585Swnj m = m->m_next; 3034585Swnj } 3044822Swnj if (n->m_len <= len) { 3054585Swnj len -= n->m_len; 3064585Swnj n->m_len = 0; 3074585Swnj m = mp; 3084822Swnj } else { 3094585Swnj n->m_len -= len; 3104585Swnj break; 3114585Swnj } 3124585Swnj } 3134585Swnj } 3144585Swnj } 315*5228Swnj 316*5228Swnj /*ARGSUSED*/ 317*5228Swnj m_pullup(m, len) 318*5228Swnj struct mbuf *m; 319*5228Swnj int len; 320*5228Swnj { 321*5228Swnj 322*5228Swnj return (0); 323*5228Swnj } 324