1*4585Swnj /* mbuf.c 1.6 81/10/21 */ 2*4585Swnj 3*4585Swnj #include "../h/param.h" 4*4585Swnj #include "../h/dir.h" 5*4585Swnj #include "../h/user.h" 6*4585Swnj #include "../h/proc.h" 7*4585Swnj #include "../h/pte.h" 8*4585Swnj #include "../h/cmap.h" 9*4585Swnj #include "../h/map.h" 10*4585Swnj #include "../bbnnet/net.h" 11*4585Swnj #include "../bbnnet/mbuf.h" 12*4585Swnj #include "../bbnnet/tcp.h" 13*4585Swnj #include "../bbnnet/ip.h" 14*4585Swnj #include "../h/vm.h" 15*4585Swnj 16*4585Swnj struct mbuf * 17*4585Swnj m_get(canwait) 18*4585Swnj int canwait; 19*4585Swnj { 20*4585Swnj register struct mbuf *m; 21*4585Swnj 22*4585Swnj COUNT(M_GET); 23*4585Swnj MGET(m, canwait); 24*4585Swnj return (m); 25*4585Swnj } 26*4585Swnj 27*4585Swnj struct mbuf * 28*4585Swnj m_free(m) 29*4585Swnj struct mbuf *m; 30*4585Swnj { 31*4585Swnj register struct mbuf *n; 32*4585Swnj 33*4585Swnj COUNT(M_FREE); 34*4585Swnj MFREE(m, n); 35*4585Swnj return (n); 36*4585Swnj } 37*4585Swnj 38*4585Swnj struct mbuf * 39*4585Swnj m_more(type) 40*4585Swnj int type; 41*4585Swnj { 42*4585Swnj int s; 43*4585Swnj register struct mbuf *m; 44*4585Swnj 45*4585Swnj COUNT(M_MORE); 46*4585Swnj if (!m_expand()) { 47*4585Swnj netstat.m_drops++; 48*4585Swnj return (NULL); 49*4585Swnj } 50*4585Swnj #define m_more(x) ((struct mbuf *)panic("m_more")) 51*4585Swnj MGET(m, 0); 52*4585Swnj return (m); 53*4585Swnj } 54*4585Swnj 55*4585Swnj m_freem(m) /* free mbuf chain headed by m */ 56*4585Swnj register struct mbuf *m; 57*4585Swnj { 58*4585Swnj register struct mbuf *n; 59*4585Swnj register int s, cnt; 60*4585Swnj 61*4585Swnj COUNT(M_FREEM); 62*4585Swnj if (m == NULL) 63*4585Swnj return (0); 64*4585Swnj cnt = 0; 65*4585Swnj s = spl_imp(); 66*4585Swnj do { 67*4585Swnj MFREE(m, n); 68*4585Swnj cnt++; 69*4585Swnj } while (m = n); 70*4585Swnj splx(s); 71*4585Swnj return (cnt); 72*4585Swnj } 73*4585Swnj 74*4585Swnj 75*4585Swnj mbufinit() /* init network buffer mgmt system */ 76*4585Swnj { 77*4585Swnj register struct mbuf *m; 78*4585Swnj register i; 79*4585Swnj 80*4585Swnj COUNT(MBUFINIT); 81*4585Swnj m = (struct mbuf *)&netutl[0]; /* ->start of buffer virt mem */ 82*4585Swnj vmemall(&Netmap[0], 2, proc, CSYS); 83*4585Swnj vmaccess(&Netmap[0], m, 2); 84*4585Swnj for (i=0; i < NMBPG; i++) { 85*4585Swnj m_free(m); 86*4585Swnj m++; 87*4585Swnj } 88*4585Swnj pg_alloc(3); 89*4585Swnj netcb.n_pages = 4; 90*4585Swnj netcb.n_bufs = 32; 91*4585Swnj netcb.n_lowat = 16; 92*4585Swnj netcb.n_hiwat = 32; 93*4585Swnj } 94*4585Swnj 95*4585Swnj pg_alloc(n) 96*4585Swnj register int n; 97*4585Swnj { 98*4585Swnj register i, j, k; 99*4585Swnj register struct mbuf *m; 100*4585Swnj int bufs, s; 101*4585Swnj 102*4585Swnj COUNT(PG_ALLOC); 103*4585Swnj k = n << 1; 104*4585Swnj if ((i = rmalloc(netmap, n)) == 0) 105*4585Swnj return (0); 106*4585Swnj j = i<<1; 107*4585Swnj m = pftom(i); 108*4585Swnj /* should use vmemall sometimes */ 109*4585Swnj if (memall(&Netmap[j], k, proc, CSYS) == 0) 110*4585Swnj return (0); 111*4585Swnj vmaccess(&Netmap[j], (caddr_t)m, k); 112*4585Swnj bufs = n << 3; 113*4585Swnj s = spl_imp(); 114*4585Swnj for (j=0; j < bufs; j++) { 115*4585Swnj m_free(m); 116*4585Swnj m++; 117*4585Swnj } 118*4585Swnj splx(s); 119*4585Swnj netcb.n_pages += n; 120*4585Swnj return (1); 121*4585Swnj } 122*4585Swnj 123*4585Swnj m_expand() 124*4585Swnj { 125*4585Swnj register i; 126*4585Swnj register struct ipq *fp; 127*4585Swnj register struct ip *q; 128*4585Swnj register struct tcb *tp; 129*4585Swnj register struct mbuf *m, *n; 130*4585Swnj int need, needp, needs; 131*4585Swnj 132*4585Swnj COUNT(M_EXPAND); 133*4585Swnj needs = need = netcb.n_hiwat - netcb.n_bufs; /* #bufs to add */ 134*4585Swnj needp = need >> 3; /* #pages to add */ 135*4585Swnj if (pg_alloc(needp)) 136*4585Swnj return (1); 137*4585Swnj for (i=0; i < needp; i++, need-=NMBPG) 138*4585Swnj if (needp == 1 || pg_alloc(1) == 0) /* ??? */ 139*4585Swnj goto steal; 140*4585Swnj return (need < needs); 141*4585Swnj steal: 142*4585Swnj fp = netcb.n_ip_tail; /* ip reass.q */ 143*4585Swnj while (need > 0 && fp) { 144*4585Swnj q = fp->iqx.ip_next; /* free mbufs assoc. w/chain */ 145*4585Swnj while (q != (struct ip *)fp) { 146*4585Swnj need -= m_freem(dtom(q)); 147*4585Swnj q = q->ip_next; 148*4585Swnj } 149*4585Swnj ip_freef(fp); /* free header */ 150*4585Swnj fp = netcb.n_ip_tail; 151*4585Swnj } 152*4585Swnj tp = netcb.n_tcb_tail; /* ->tcbs */ 153*4585Swnj while (need > 0 && tp != NULL) { 154*4585Swnj m = tp->t_rcv_unack; 155*4585Swnj while (m != NULL) { 156*4585Swnj n = m->m_act; 157*4585Swnj need -= m_freem(m); 158*4585Swnj m = n; 159*4585Swnj } 160*4585Swnj tp->t_rcv_unack = NULL; 161*4585Swnj tp = tp->t_tcb_prev; 162*4585Swnj } 163*4585Swnj return (need < needs); 164*4585Swnj } 165*4585Swnj 166*4585Swnj #ifdef notdef 167*4585Swnj m_relse() 168*4585Swnj { 169*4585Swnj int free; 170*4585Swnj 171*4585Swnj COUNT(M_RELSE); 172*4585Swnj free = (netcb.n_bufs - netcb.n_hiwat) >> 3; /* # excess free pages */ 173*4585Swnj return; 174*4585Swnj } 175*4585Swnj #endif 176*4585Swnj 177*4585Swnj struct mbuf * 178*4585Swnj m_adj(mp, len) 179*4585Swnj struct mbuf *mp; 180*4585Swnj register len; 181*4585Swnj { 182*4585Swnj register struct mbuf *m, *n; 183*4585Swnj 184*4585Swnj COUNT(M_ADJ); 185*4585Swnj if ((m = mp) == NULL) 186*4585Swnj return; 187*4585Swnj if (len >= 0) { /* adjust from top of msg chain */ 188*4585Swnj while (m != NULL && len > 0) { 189*4585Swnj if (m->m_len <= len) { /* free this mbuf */ 190*4585Swnj len -= m->m_len; 191*4585Swnj m->m_len = 0; 192*4585Swnj m = m->m_next; 193*4585Swnj } else { /* adjust mbuf */ 194*4585Swnj m->m_len -= len; 195*4585Swnj m->m_off += len; 196*4585Swnj break; 197*4585Swnj } 198*4585Swnj } 199*4585Swnj 200*4585Swnj } else { /* adjust from bottom of msg chain */ 201*4585Swnj len = -len; 202*4585Swnj while (len > 0 && m->m_len != 0) { 203*4585Swnj /* find end of chain */ 204*4585Swnj while (m != NULL && m->m_len != 0) { 205*4585Swnj n = m; 206*4585Swnj m = m->m_next; 207*4585Swnj } 208*4585Swnj if (n->m_len <= len) { /* last mbuf */ 209*4585Swnj len -= n->m_len; 210*4585Swnj n->m_len = 0; 211*4585Swnj m = mp; 212*4585Swnj } else { /* adjust length */ 213*4585Swnj n->m_len -= len; 214*4585Swnj break; 215*4585Swnj } 216*4585Swnj } 217*4585Swnj } 218*4585Swnj } 219*4585Swnj 220*4585Swnj /* 221*4585Swnj * convert mbuf virtual to physical addr for uballoc 222*4585Swnj */ 223*4585Swnj mtophys(m) 224*4585Swnj register struct mbuf *m; 225*4585Swnj { 226*4585Swnj register i; 227*4585Swnj register unsigned long addr; 228*4585Swnj register struct pte *pte; 229*4585Swnj 230*4585Swnj COUNT(MTOPHYS); 231*4585Swnj i = (((int)m & ~PGOFSET) - (int)netutl) >> PGSHIFT; 232*4585Swnj pte = &Netmap[i]; 233*4585Swnj addr = (pte->pg_pfnum << PGSHIFT) | ((int)m & PGOFSET); 234*4585Swnj return (addr); 235*4585Swnj } 236