1*4669Swnj /* uipc_mbuf.c 1.6 81/10/30 */ 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" 114662Swnj #include "../inet/inet.h" 124662Swnj #include "../inet/inet_systm.h" 13*4669Swnj #include "../inet/ip.h" 144662Swnj #include "../inet/tcp.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 56*4669Swnj m_freem(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; 664662Swnj s = splimp(); 674585Swnj do { 68*4669Swnj if (m->m_off > MMAXOFF) 69*4669Swnj cnt += NMBPG; 70*4669Swnj cnt++; 714585Swnj MFREE(m, n); 724585Swnj } while (m = n); 734585Swnj splx(s); 744585Swnj return (cnt); 754585Swnj } 764585Swnj 77*4669Swnj mbufinit() 784585Swnj { 794585Swnj register struct mbuf *m; 804585Swnj register i; 814585Swnj 824585Swnj COUNT(MBUFINIT); 834585Swnj m = (struct mbuf *)&netutl[0]; /* ->start of buffer virt mem */ 844585Swnj vmemall(&Netmap[0], 2, proc, CSYS); 854585Swnj vmaccess(&Netmap[0], m, 2); 864585Swnj for (i=0; i < NMBPG; i++) { 874587Swnj m->m_off = 0; 884585Swnj m_free(m); 894585Swnj m++; 904585Swnj } 914585Swnj pg_alloc(3); 924662Swnj mbstat.m_pages = 4; 934662Swnj mbstat.m_bufs = 32; 944662Swnj mbstat.m_lowat = 16; 954662Swnj mbstat.m_hiwat = 32; 96*4669Swnj { int i,j,k,n; 97*4669Swnj n = 32; 98*4669Swnj k = n << 1; 99*4669Swnj if ((i = rmalloc(netmap, n)) == 0) 100*4669Swnj return (0); 101*4669Swnj j = i<<1; 102*4669Swnj m = pftom(i); 103*4669Swnj /* should use vmemall sometimes */ 104*4669Swnj if (memall(&Netmap[j], k, proc, CSYS) == 0) { 105*4669Swnj printf("botch\n"); 106*4669Swnj return; 107*4669Swnj } 108*4669Swnj vmaccess(&Netmap[j], (caddr_t)m, k); 109*4669Swnj for (j=0; j < n; j++) { 110*4669Swnj m->m_off = 0; 111*4669Swnj m->m_next = mpfree; 112*4669Swnj mpfree = m; 113*4669Swnj m += NMBPG; 114*4669Swnj nmpfree++; 115*4669Swnj } 116*4669Swnj } 1174585Swnj } 1184585Swnj 1194585Swnj pg_alloc(n) 1204585Swnj register int n; 1214585Swnj { 1224585Swnj register i, j, k; 1234585Swnj register struct mbuf *m; 1244585Swnj int bufs, s; 1254585Swnj 1264585Swnj COUNT(PG_ALLOC); 1274585Swnj k = n << 1; 1284585Swnj if ((i = rmalloc(netmap, n)) == 0) 1294585Swnj return (0); 1304585Swnj j = i<<1; 1314585Swnj m = pftom(i); 1324585Swnj /* should use vmemall sometimes */ 1334585Swnj if (memall(&Netmap[j], k, proc, CSYS) == 0) 1344585Swnj return (0); 1354585Swnj vmaccess(&Netmap[j], (caddr_t)m, k); 1364585Swnj bufs = n << 3; 1374662Swnj s = splimp(); 1384585Swnj for (j=0; j < bufs; j++) { 1394587Swnj m->m_off = 0; 1404585Swnj m_free(m); 1414585Swnj m++; 1424585Swnj } 1434585Swnj splx(s); 1444662Swnj mbstat.m_pages += n; 1454585Swnj return (1); 1464585Swnj } 1474585Swnj 1484585Swnj m_expand() 1494585Swnj { 1504585Swnj register i; 1514585Swnj register struct mbuf *m, *n; 1524585Swnj int need, needp, needs; 1534585Swnj 1544585Swnj COUNT(M_EXPAND); 1554662Swnj needs = need = mbstat.m_hiwat - mbstat.m_bufs; 1564662Swnj needp = need >> 3; 1574585Swnj if (pg_alloc(needp)) 1584585Swnj return (1); 159*4669Swnj for (i=0; i < needp; i++, need -= NMBPG) 160*4669Swnj if (pg_alloc(1) == 0) 1614585Swnj goto steal; 1624585Swnj return (need < needs); 1634585Swnj steal: 164*4669Swnj /* while (not enough) ask protocols to free code */ 165*4669Swnj ; 1664585Swnj } 1674585Swnj 1684585Swnj #ifdef notdef 1694585Swnj m_relse() 1704585Swnj { 171*4669Swnj 1724662Swnj COUNT(M_RELSE); 1734585Swnj } 1744585Swnj #endif 1754585Swnj 176*4669Swnj m_cat(m, n) 177*4669Swnj register struct mbuf *m, *n; 178*4669Swnj { 179*4669Swnj 180*4669Swnj while (m->m_next) 181*4669Swnj m = m->m_next; 182*4669Swnj while (n) 183*4669Swnj if (m->m_off + m->m_len + n->m_len <= MMAXOFF) { 184*4669Swnj bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, n->m_len); 185*4669Swnj m->m_len += n->m_len; 186*4669Swnj n = m_free(n); 187*4669Swnj } else { 188*4669Swnj m->m_next = n; 189*4669Swnj m = n; 190*4669Swnj n = m->m_next; 191*4669Swnj } 192*4669Swnj } 193*4669Swnj 1944585Swnj m_adj(mp, len) 1954585Swnj struct mbuf *mp; 1964585Swnj register len; 1974585Swnj { 1984585Swnj register struct mbuf *m, *n; 1994585Swnj 200*4669Swnj /* 201*4669Swnj for (m = mp; m; m = m->m_next) { 202*4669Swnj printf("a %x %d\n", m, m->m_len); 203*4669Swnj } 204*4669Swnj */ 2054585Swnj COUNT(M_ADJ); 2064585Swnj if ((m = mp) == NULL) 2074585Swnj return; 2084585Swnj if (len >= 0) { /* adjust from top of msg chain */ 2094585Swnj while (m != NULL && len > 0) { 2104585Swnj if (m->m_len <= len) { /* free this mbuf */ 2114585Swnj len -= m->m_len; 2124585Swnj m->m_len = 0; 2134585Swnj m = m->m_next; 2144585Swnj } else { /* adjust mbuf */ 2154585Swnj m->m_len -= len; 2164585Swnj m->m_off += len; 2174585Swnj break; 2184585Swnj } 2194585Swnj } 2204585Swnj 2214585Swnj } else { /* adjust from bottom of msg chain */ 2224585Swnj len = -len; 2234585Swnj while (len > 0 && m->m_len != 0) { 2244585Swnj /* find end of chain */ 2254585Swnj while (m != NULL && m->m_len != 0) { 2264585Swnj n = m; 2274585Swnj m = m->m_next; 2284585Swnj } 2294585Swnj if (n->m_len <= len) { /* last mbuf */ 2304585Swnj len -= n->m_len; 2314585Swnj n->m_len = 0; 2324585Swnj m = mp; 2334585Swnj } else { /* adjust length */ 2344585Swnj n->m_len -= len; 2354585Swnj break; 2364585Swnj } 2374585Swnj } 2384585Swnj } 2394585Swnj } 2404585Swnj 2414585Swnj /* 2424585Swnj * convert mbuf virtual to physical addr for uballoc 2434585Swnj */ 2444585Swnj mtophys(m) 2454585Swnj register struct mbuf *m; 2464585Swnj { 2474585Swnj register i; 2484585Swnj register unsigned long addr; 2494585Swnj register struct pte *pte; 2504585Swnj 2514585Swnj COUNT(MTOPHYS); 2524585Swnj i = (((int)m & ~PGOFSET) - (int)netutl) >> PGSHIFT; 2534585Swnj pte = &Netmap[i]; 2544585Swnj addr = (pte->pg_pfnum << PGSHIFT) | ((int)m & PGOFSET); 2554585Swnj return (addr); 2564585Swnj } 257