1 /* uipc_mbuf.c 1.9 81/11/14 */ 2 3 #include "../h/param.h" 4 #include "../h/dir.h" 5 #include "../h/user.h" 6 #include "../h/proc.h" 7 #include "../h/pte.h" 8 #include "../h/cmap.h" 9 #include "../h/map.h" 10 #include "../h/mbuf.h" 11 #include "../net/inet_systm.h" /* ### */ 12 #include "../h/vm.h" 13 14 m_reserve(mbufs) 15 int mbufs; 16 { 17 18 if (mbstat.m_lowat + mbufs > NMBPAGES * NMBPG - 32) 19 return (0); 20 mbstat.m_lowat += mbufs; 21 mbstat.m_hiwat = 2 * mbstat.m_lowat; 22 } 23 24 m_release(mbufs) 25 int mbufs; 26 { 27 28 mbstat.m_lowat -= mbufs; 29 mbstat.m_hiwat = 2 * mbstat.m_lowat; 30 } 31 32 struct mbuf * 33 m_get(canwait) 34 int canwait; 35 { 36 register struct mbuf *m; 37 38 COUNT(M_GET); 39 MGET(m, canwait); 40 return (m); 41 } 42 43 struct mbuf * 44 m_getclr(canwait) 45 int canwait; 46 { 47 register struct mbuf *m; 48 49 COUNT(M_GETCLR); 50 m = m_get(m, canwait); 51 if (m == 0) 52 return (0); 53 m->m_off = MMINOFF; 54 bzero(mtod(m, caddr_t), MLEN); 55 return (m); 56 } 57 58 struct mbuf * 59 m_free(m) 60 struct mbuf *m; 61 { 62 register struct mbuf *n; 63 64 COUNT(M_FREE); 65 MFREE(m, n); 66 return (n); 67 } 68 69 struct mbuf * 70 m_more(type) 71 int type; 72 { 73 int s; 74 register struct mbuf *m; 75 76 COUNT(M_MORE); 77 if (!m_expand()) { 78 mbstat.m_drops++; 79 return (NULL); 80 } 81 #define m_more(x) ((struct mbuf *)panic("m_more")) 82 MGET(m, 0); 83 return (m); 84 } 85 86 m_freem(m) 87 register struct mbuf *m; 88 { 89 register struct mbuf *n; 90 register int s, cnt; 91 92 COUNT(M_FREEM); 93 if (m == NULL) 94 return (0); 95 cnt = 0; 96 s = splimp(); 97 do { 98 if (m->m_off > MMAXOFF) 99 cnt += NMBPG; 100 cnt++; 101 MFREE(m, n); 102 } while (m = n); 103 splx(s); 104 return (cnt); 105 } 106 107 mbinit() 108 { 109 register struct mbuf *m; 110 register i; 111 112 COUNT(MBUFINIT); 113 m = (struct mbuf *)&mbutl[0]; /* ->start of buffer virt mem */ 114 vmemall(&Mbmap[0], 2, proc, CSYS); 115 vmaccess(&Mbmap[0], m, 2); 116 for (i=0; i < NMBPG; i++) { 117 m->m_off = 0; 118 m_free(m); 119 m++; 120 } 121 pg_alloc(3); 122 mbstat.m_pages = 4; 123 mbstat.m_bufs = 32; 124 mbstat.m_lowat = 16; 125 mbstat.m_hiwat = 32; 126 { int i,j,k,n; 127 n = 32; 128 k = n << 1; 129 if ((i = rmalloc(mbmap, n)) == 0) 130 return (0); 131 j = i<<1; 132 m = pftom(i); 133 /* should use vmemall sometimes */ 134 if (memall(&Mbmap[j], k, proc, CSYS) == 0) { 135 printf("botch\n"); 136 return; 137 } 138 vmaccess(&Mbmap[j], (caddr_t)m, k); 139 for (j=0; j < n; j++) { 140 m->m_off = 0; 141 m->m_next = mpfree; 142 mpfree = m; 143 m += NMBPG; 144 nmpfree++; 145 } 146 } 147 } 148 149 pg_alloc(n) 150 register int n; 151 { 152 register i, j, k; 153 register struct mbuf *m; 154 int bufs, s; 155 156 COUNT(PG_ALLOC); 157 k = n << 1; 158 if ((i = rmalloc(mbmap, n)) == 0) 159 return (0); 160 j = i<<1; 161 m = pftom(i); 162 /* should use vmemall sometimes */ 163 if (memall(&Mbmap[j], k, proc, CSYS) == 0) 164 return (0); 165 vmaccess(&Mbmap[j], (caddr_t)m, k); 166 bufs = n << 3; 167 s = splimp(); 168 for (j=0; j < bufs; j++) { 169 m->m_off = 0; 170 m_free(m); 171 m++; 172 } 173 splx(s); 174 mbstat.m_pages += n; 175 return (1); 176 } 177 178 m_expand() 179 { 180 register i; 181 register struct mbuf *m, *n; 182 int need, needp, needs; 183 184 COUNT(M_EXPAND); 185 needs = need = mbstat.m_hiwat - mbstat.m_bufs; 186 needp = need >> 3; 187 if (pg_alloc(needp)) 188 return (1); 189 for (i=0; i < needp; i++, need -= NMBPG) 190 if (pg_alloc(1) == 0) 191 goto steal; 192 return (need < needs); 193 steal: 194 /* while (not enough) ask protocols to free code */ 195 ; 196 } 197 198 #ifdef notdef 199 m_relse() 200 { 201 202 COUNT(M_RELSE); 203 } 204 #endif 205 206 m_cat(m, n) 207 register struct mbuf *m, *n; 208 { 209 210 while (m->m_next) 211 m = m->m_next; 212 while (n) 213 if (m->m_off + m->m_len + n->m_len <= MMAXOFF) { 214 bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, n->m_len); 215 m->m_len += n->m_len; 216 n = m_free(n); 217 } else { 218 m->m_next = n; 219 m = n; 220 n = m->m_next; 221 } 222 } 223 224 m_adj(mp, len) 225 struct mbuf *mp; 226 register len; 227 { 228 register struct mbuf *m, *n; 229 230 COUNT(M_ADJ); 231 if ((m = mp) == NULL) 232 return; 233 if (len >= 0) { 234 while (m != NULL && len > 0) { 235 if (m->m_len <= len) { 236 len -= m->m_len; 237 m->m_len = 0; 238 m = m->m_next; 239 } else { 240 m->m_len -= len; 241 m->m_off += len; 242 break; 243 } 244 } 245 } else { 246 /* a 2 pass algorithm might be better */ 247 len = -len; 248 while (len > 0 && m->m_len != 0) { 249 while (m != NULL && m->m_len != 0) { 250 n = m; 251 m = m->m_next; 252 } 253 if (n->m_len <= len) { 254 len -= n->m_len; 255 n->m_len = 0; 256 m = mp; 257 } else { 258 n->m_len -= len; 259 break; 260 } 261 } 262 } 263 } 264