merge of bill's code plus lint (plus, of course, cleanup of bill's bugs)
[unix-history] / usr / src / sys / kern / uipc_mbuf.c
index a1acf81..11f5f9b 100644 (file)
-/*     uipc_mbuf.c     1.16    81/11/22        */
+/*     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/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 "../h/cmap.h"
 #include "../h/map.h"
 #include "../h/mbuf.h"
-#include "../net/inet_systm.h"         /* XXX */
 #include "../h/vm.h"
 #include "../h/vm.h"
+#include "../h/kernel.h"
 
 
-m_reserve(mbufs)
-       int mbufs;
+mbinit()
 {
 
 {
 
-/*
-       printf("reserve %d\n", mbufs);
-*/
-       if (mbstat.m_lowat + (mbufs>>1) > NMBPAGES * NMBPG - 32) 
+       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");
+}
+
+caddr_t
+m_clalloc(ncl, how)
+       register int ncl;
+       int how;
+{
+       int npg, mbx;
+       register struct mbuf *m;
+       register int i;
+       int s;
+
+       npg = ncl * CLSIZE;
+       s = splimp();           /* careful: rmalloc isn't reentrant */
+       mbx = rmalloc(mbmap, (long)npg);
+       splx(s);
+       if (mbx == 0)
                return (0);
                return (0);
-       mbstat.m_hiwat += mbufs;
-       mbstat.m_lowat = mbstat.m_hiwat >> 1;
-       return (1);
+       m = cltom(mbx / CLSIZE);
+       if (memall(&Mbmap[mbx], npg, proc, CSYS) == 0) {
+               s = splimp();
+               rmfree(mbmap, (long)npg, (long)mbx);
+               splx(s);
+               return (0);
+       }
+       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_release(mbufs)
-       int mbufs;
+m_pgfree(addr, n)
+       caddr_t addr;
+       int n;
 {
 
 {
 
-/*
-       printf("release %d\n", mbufs);
-*/
-       mbstat.m_hiwat -= mbufs;
-       mbstat.m_lowat = mbstat.m_hiwat >> 1;
+#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);
+}
+
+/* NEED SOME WAY TO RELEASE SPACE */
+
+/*
+ * Space allocation routines.
+ * These are also available as macros
+ * for critical paths.
+ */
 struct mbuf *
 struct mbuf *
-m_get(canwait)
-       int canwait;
+m_get(canwait, type)
+       int canwait, type;
 {
        register struct mbuf *m;
 
 {
        register struct mbuf *m;
 
-COUNT(M_GET);
-       MGET(m, canwait);
+       MGET(m, canwait, type);
        return (m);
 }
 
 struct mbuf *
        return (m);
 }
 
 struct mbuf *
-m_getclr(canwait)
-       int canwait;
+m_getclr(canwait, type)
+       int canwait, type;
 {
        register struct mbuf *m;
 
 {
        register struct mbuf *m;
 
-COUNT(M_GETCLR);
-       m = m_get(canwait);
+       m = m_get(canwait, type);
        if (m == 0)
                return (0);
        if (m == 0)
                return (0);
-       m->m_off = MMINOFF;
        bzero(mtod(m, caddr_t), MLEN);
        return (m);
 }
        bzero(mtod(m, caddr_t), MLEN);
        return (m);
 }
@@ -68,25 +134,24 @@ m_free(m)
 {
        register struct mbuf *n;
 
 {
        register struct mbuf *n;
 
-COUNT(M_FREE);
        MFREE(m, n);
        return (n);
 }
 
 /*ARGSUSED*/
 struct mbuf *
        MFREE(m, n);
        return (n);
 }
 
 /*ARGSUSED*/
 struct mbuf *
-m_more(type)
-       int type;
+m_more(canwait, type)
+       int canwait, type;
 {
        register struct mbuf *m;
 
 {
        register struct mbuf *m;
 
-COUNT(M_MORE);
        if (!m_expand()) {
                mbstat.m_drops++;
                return (NULL);
        }
        if (!m_expand()) {
                mbstat.m_drops++;
                return (NULL);
        }
-#define m_more(x) (panic("m_more"), (struct mbuf *)0)
-       MGET(m, type);
+#define m_more(x,y) (panic("m_more"), (struct mbuf *)0)
+       MGET(m, canwait, type);
+#undef m_more
        return (m);
 }
 
        return (m);
 }
 
@@ -96,7 +161,6 @@ m_freem(m)
        register struct mbuf *n;
        register int s;
 
        register struct mbuf *n;
        register int s;
 
-COUNT(M_FREEM);
        if (m == NULL)
                return;
        s = splimp();
        if (m == NULL)
                return;
        s = splimp();
@@ -106,15 +170,9 @@ COUNT(M_FREEM);
        splx(s);
 }
 
        splx(s);
 }
 
-/*ARGSUSED*/
-m_pullup(m, len)
-       struct mbuf *m;
-       int len;
-{
-
-       return (0);
-}
-
+/*
+ * Mbuffer utility routines.
+ */
 struct mbuf *
 m_copy(m, off, len)
        register struct mbuf *m;
 struct mbuf *
 m_copy(m, off, len)
        register struct mbuf *m;
@@ -123,12 +181,13 @@ m_copy(m, off, len)
 {
        register struct mbuf *n, **np;
        struct mbuf *top, *p;
 {
        register struct mbuf *n, **np;
        struct mbuf *top, *p;
-COUNT(M_COPY);
+       int type;
 
        if (len == 0)
                return (0);
        if (off < 0 || len < 0)
                panic("m_copy");
 
        if (len == 0)
                return (0);
        if (off < 0 || len < 0)
                panic("m_copy");
+       type = m->m_type;
        while (off > 0) {
                if (m == 0)
                        panic("m_copy");
        while (off > 0) {
                if (m == 0)
                        panic("m_copy");
@@ -140,150 +199,53 @@ COUNT(M_COPY);
        np = &top;
        top = 0;
        while (len > 0) {
        np = &top;
        top = 0;
        while (len > 0) {
-               MGET(n, 1);
+               if (m == 0) {
+                       if (len != M_COPYALL)
+                               panic("m_copy");
+                       break;
+               }
+               MGET(n, M_WAIT, type);
                *np = n;
                if (n == 0)
                        goto nospace;
                *np = n;
                if (n == 0)
                        goto nospace;
-               if (m == 0)
-                       panic("m_copy");
                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;
                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;
-                       mprefcnt[mtopf(p)]++;
-               } else {
-                       n->m_off = MMINOFF;
+                       mclrefcnt[mtocl(p)]++;
+               } else
                        bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
                            (unsigned)n->m_len);
                        bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
                            (unsigned)n->m_len);
-               }
-               len -= n->m_len;
+               if (len != M_COPYALL)
+                       len -= n->m_len;
                off = 0;
                m = m->m_next;
                np = &n->m_next;
        }
        return (top);
 nospace:
                off = 0;
                m = m->m_next;
                np = &n->m_next;
        }
        return (top);
 nospace:
-       printf("m_copy: no space\n");
        m_freem(top);
        return (0);
 }
 
        m_freem(top);
        return (0);
 }
 
-mbinit()
-{
-       register struct mbuf *m;
-       register i;
-
-COUNT(MBUFINIT);
-       m = (struct mbuf *)&mbutl[0];  /* ->start of buffer virt mem */
-       (void) vmemall(&Mbmap[0], 2, proc, CSYS);
-       vmaccess(&Mbmap[0], (caddr_t)m, 2);
-       for (i=0; i < NMBPG; i++) {
-               m->m_off = 0;
-               (void) m_free(m);
-               m++;
-       }
-       (void) pg_alloc(3);
-       mbstat.m_pages = 4;
-       mbstat.m_bufs = 32;
-       mbstat.m_lowat = 16;
-       mbstat.m_hiwat = 32;
-       { int j,k,n;
-       n = 32;
-       k = n << 1;
-       if ((i = rmalloc(mbmap, n)) == 0)
-               panic("mbinit");
-       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;
-{
-       register i, j, k;
-       register struct mbuf *m;
-       int bufs, s;
-
-COUNT(PG_ALLOC);
-       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)
-               return (0);
-       vmaccess(&Mbmap[j], (caddr_t)m, k);
-       bufs = n << 3;
-       s = splimp();
-       for (j=0; j < bufs; j++) {
-               m->m_off = 0;
-               (void) m_free(m);
-               m++;
-       }
-       splx(s);
-       mbstat.m_pages += n;
-       return (1);
-}
-
-m_expand()
-{
-       register i;
-       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 */
-       ;
-       return (0);
-}
-
-#ifdef notdef
-m_relse()
-{
-
-COUNT(M_RELSE);
-}
-#endif
-
 m_cat(m, n)
        register struct mbuf *m, *n;
 {
 m_cat(m, n)
        register struct mbuf *m, *n;
 {
-
        while (m->m_next)
                m = m->m_next;
        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,
-                           (u_int)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->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)
 }
 
 m_adj(mp, len)
@@ -292,7 +254,6 @@ m_adj(mp, len)
 {
        register struct mbuf *m, *n;
 
 {
        register struct mbuf *m, *n;
 
-COUNT(M_ADJ);
        if ((m = mp) == NULL)
                return;
        if (len >= 0) {
        if ((m = mp) == NULL)
                return;
        if (len >= 0) {
@@ -326,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);
+}