X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/6d19f7efb6e5e730cf29c43560d9f222b6684c50..88a7a62ac37860454424240400aa10e0319144c7:/usr/src/sys/kern/uipc_mbuf.c diff --git a/usr/src/sys/kern/uipc_mbuf.c b/usr/src/sys/kern/uipc_mbuf.c index 0472721b36..11f5f9b982 100644 --- a/usr/src/sys/kern/uipc_mbuf.c +++ b/usr/src/sys/kern/uipc_mbuf.c @@ -1,42 +1,130 @@ -/* uipc_mbuf.c 1.8 81/11/08 */ +/* uipc_mbuf.c 1.43 83/05/27 */ + +#include "../machine/pte.h" #include "../h/param.h" #include "../h/dir.h" #include "../h/user.h" #include "../h/proc.h" -#include "../h/pte.h" #include "../h/cmap.h" #include "../h/map.h" #include "../h/mbuf.h" -#include "../net/inet_systm.h" /* ### */ #include "../h/vm.h" +#include "../h/kernel.h" + +mbinit() +{ + + if (m_clalloc(4096/CLBYTES, MPG_MBUFS) == 0) + goto bad; + if (m_clalloc(8*4096/CLBYTES, MPG_CLUSTERS) == 0) + goto bad; + return; +bad: + panic("mbinit"); +} -m_reserve(mbufs) - int mbufs; +caddr_t +m_clalloc(ncl, how) + register int ncl; + int how; { + int npg, mbx; + register struct mbuf *m; + register int i; + int s; - if (mbstat.m_lowat + mbufs > NMBPAGES * NMBPG - 32) + npg = ncl * CLSIZE; + s = splimp(); /* careful: rmalloc isn't reentrant */ + mbx = rmalloc(mbmap, (long)npg); + splx(s); + if (mbx == 0) + return (0); + m = cltom(mbx / CLSIZE); + if (memall(&Mbmap[mbx], npg, proc, CSYS) == 0) { + s = splimp(); + rmfree(mbmap, (long)npg, (long)mbx); + splx(s); return (0); - mbstat.m_lowat += mbufs; - mbstat.m_hiwat = 2 * mbstat.m_lowat; + } + vmaccess(&Mbmap[mbx], (caddr_t)m, npg); + switch (how) { + + case MPG_CLUSTERS: + s = splimp(); + for (i = 0; i < ncl; i++) { + m->m_off = 0; + m->m_next = mclfree; + mclfree = m; + m += CLBYTES / sizeof (*m); + mbstat.m_clfree++; + } + mbstat.m_clusters += ncl; + splx(s); + break; + + case MPG_MBUFS: + for (i = ncl * CLBYTES / sizeof (*m); i > 0; i--) { + m->m_off = 0; + m->m_type = MT_DATA; + mbstat.m_mtypes[MT_DATA]++; + mbstat.m_mbufs++; + (void) m_free(m); + m++; + } + break; + } + return ((caddr_t)m); +} + +m_pgfree(addr, n) + caddr_t addr; + int n; +{ + +#ifdef lint + addr = addr; n = n; +#endif +} + +m_expand() +{ + + if (m_clalloc(1, MPG_MBUFS) == 0) + goto steal; + return (1); +steal: + /* should ask protocols to free code */ + return (0); } -m_release(mbufs) - int mbufs; +/* NEED SOME WAY TO RELEASE SPACE */ + +/* + * Space allocation routines. + * These are also available as macros + * for critical paths. + */ +struct mbuf * +m_get(canwait, type) + int canwait, type; { + register struct mbuf *m; - mbstat.m_lowat -= mbufs; - mbstat.m_hiwat = 2 * mbstat.m_lowat; + MGET(m, canwait, type); + return (m); } struct mbuf * -m_get(canwait) - int canwait; +m_getclr(canwait, type) + int canwait, type; { register struct mbuf *m; -COUNT(M_GET); - MGET(m, canwait); + m = m_get(canwait, type); + if (m == 0) + return (0); + bzero(mtod(m, caddr_t), MLEN); return (m); } @@ -46,25 +134,24 @@ m_free(m) { register struct mbuf *n; -COUNT(M_FREE); MFREE(m, n); return (n); } +/*ARGSUSED*/ struct mbuf * -m_more(type) - int type; +m_more(canwait, type) + int canwait, type; { - int s; register struct mbuf *m; -COUNT(M_MORE); if (!m_expand()) { mbstat.m_drops++; return (NULL); } -#define m_more(x) ((struct mbuf *)panic("m_more")) - MGET(m, 0); +#define m_more(x,y) (panic("m_more"), (struct mbuf *)0) + MGET(m, canwait, type); +#undef m_more return (m); } @@ -72,147 +159,101 @@ m_freem(m) register struct mbuf *m; { register struct mbuf *n; - register int s, cnt; + register int s; -COUNT(M_FREEM); if (m == NULL) - return (0); - cnt = 0; + return; s = splimp(); do { - if (m->m_off > MMAXOFF) - cnt += NMBPG; - cnt++; MFREE(m, n); } while (m = n); splx(s); - return (cnt); } -mbinit() -{ +/* + * Mbuffer utility routines. + */ +struct mbuf * +m_copy(m, off, len) register struct mbuf *m; - register i; - -COUNT(MBUFINIT); - m = (struct mbuf *)&mbutl[0]; /* ->start of buffer virt mem */ - vmemall(&Mbmap[0], 2, proc, CSYS); - vmaccess(&Mbmap[0], m, 2); - for (i=0; i < NMBPG; i++) { - m->m_off = 0; - m_free(m); - m++; - } - pg_alloc(3); - mbstat.m_pages = 4; - mbstat.m_bufs = 32; - mbstat.m_lowat = 16; - mbstat.m_hiwat = 32; - { int i,j,k,n; - n = 32; - k = n << 1; - if ((i = rmalloc(mbmap, n)) == 0) - return (0); - j = i<<1; - m = pftom(i); - /* should use vmemall sometimes */ - if (memall(&Mbmap[j], k, proc, CSYS) == 0) { - printf("botch\n"); - return; - } - vmaccess(&Mbmap[j], (caddr_t)m, k); - for (j=0; j < n; j++) { - m->m_off = 0; - m->m_next = mpfree; - mpfree = m; - m += NMBPG; - nmpfree++; - } - } -} - -pg_alloc(n) - register int n; + int off; + register int len; { - register i, j, k; - register struct mbuf *m; - int bufs, s; + register struct mbuf *n, **np; + struct mbuf *top, *p; + int type; -COUNT(PG_ALLOC); - k = n << 1; - if ((i = rmalloc(mbmap, n)) == 0) + if (len == 0) return (0); - j = i<<1; - m = pftom(i); - /* should use vmemall sometimes */ - if (memall(&Mbmap[j], k, proc, CSYS) == 0) - return (0); - vmaccess(&Mbmap[j], (caddr_t)m, k); - bufs = n << 3; - s = splimp(); - for (j=0; j < bufs; j++) { - m->m_off = 0; - m_free(m); - m++; + if (off < 0 || len < 0) + panic("m_copy"); + type = m->m_type; + while (off > 0) { + if (m == 0) + panic("m_copy"); + if (off < m->m_len) + break; + off -= m->m_len; + m = m->m_next; } - splx(s); - mbstat.m_pages += n; - return (1); -} - -m_expand() -{ - register i; - register struct mbuf *m, *n; - int need, needp, needs; - -COUNT(M_EXPAND); - needs = need = mbstat.m_hiwat - mbstat.m_bufs; - needp = need >> 3; - if (pg_alloc(needp)) - return (1); - for (i=0; i < needp; i++, need -= NMBPG) - if (pg_alloc(1) == 0) - goto steal; - return (need < needs); -steal: - /* while (not enough) ask protocols to free code */ - ; -} - -#ifdef notdef -m_relse() -{ - -COUNT(M_RELSE); + np = ⊤ + top = 0; + while (len > 0) { + if (m == 0) { + if (len != M_COPYALL) + panic("m_copy"); + break; + } + MGET(n, M_WAIT, type); + *np = n; + if (n == 0) + goto nospace; + n->m_len = MIN(len, m->m_len - off); + if (m->m_off > MMAXOFF) { + p = mtod(m, struct mbuf *); + n->m_off = ((int)p - (int)n) + off; + mclrefcnt[mtocl(p)]++; + } else + bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t), + (unsigned)n->m_len); + if (len != M_COPYALL) + len -= n->m_len; + off = 0; + m = m->m_next; + np = &n->m_next; + } + return (top); +nospace: + m_freem(top); + return (0); } -#endif m_cat(m, n) register struct mbuf *m, *n; { - while (m->m_next) m = m->m_next; - while (n) - if (m->m_off + m->m_len + n->m_len <= MMAXOFF) { - bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, n->m_len); - m->m_len += n->m_len; - n = m_free(n); - } else { + while (n) { + if (m->m_off >= MMAXOFF || + m->m_off + m->m_len + n->m_len > MMAXOFF) { + /* just join the two chains */ m->m_next = n; - m = n; - n = m->m_next; + return; } + /* splat the data from one into the other */ + bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, + (u_int)n->m_len); + m->m_len += n->m_len; + n = m_free(n); + } } m_adj(mp, len) struct mbuf *mp; - register len; + register int len; { register struct mbuf *m, *n; -COUNT(M_ADJ); if ((m = mp) == NULL) return; if (len >= 0) { @@ -246,3 +287,43 @@ COUNT(M_ADJ); } } } + +struct mbuf * +m_pullup(m0, len) + struct mbuf *m0; + int len; +{ + register struct mbuf *m, *n; + int count; + + n = m0; + if (len > MLEN) + goto bad; + MGET(m, M_DONTWAIT, n->m_type); + if (m == 0) + goto bad; + m->m_len = 0; + do { + count = MIN(MLEN - m->m_len, len); + if (count > n->m_len) + count = n->m_len; + bcopy(mtod(n, caddr_t), mtod(m, caddr_t)+m->m_len, + (unsigned)count); + len -= count; + m->m_len += count; + n->m_off += count; + n->m_len -= count; + if (n->m_len) + break; + n = m_free(n); + } while (n); + if (len) { + (void) m_free(m); + goto bad; + } + m->m_next = n; + return (m); +bad: + m_freem(n); + return (0); +}