Add copyright
[unix-history] / usr / src / sys / kern / uipc_mbuf.c
index 91e9178..ca8d4af 100644 (file)
@@ -1,75 +1,85 @@
-/*     uipc_mbuf.c     1.27    82/01/24        */
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)uipc_mbuf.c 6.5 (Berkeley) %G%
+ */
+
+#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/in_systm.h"           /* XXX */
-#include "../h/vm.h"
+#include "param.h"
+#include "dir.h"
+#include "user.h"
+#include "proc.h"
+#include "cmap.h"
+#include "map.h"
+#include "mbuf.h"
+#include "vm.h"
+#include "kernel.h"
 
 mbinit()
 {
 
 mbinit()
 {
+       int s;
 
 
-COUNT(MBINIT);
-       if (m_reserve(32) == 0)
-               goto bad;
-       if (m_clalloc(4, MPG_MBUFS) == 0)
+       s = splimp();
+       if (m_clalloc(4096/CLBYTES, MPG_MBUFS, M_DONTWAIT) == 0)
                goto bad;
                goto bad;
-       if (m_clalloc(32, MPG_CLUSTERS) == 0)
+       if (m_clalloc(8*4096/CLBYTES, MPG_CLUSTERS, M_DONTWAIT) == 0)
                goto bad;
                goto bad;
+       splx(s);
        return;
 bad:
        panic("mbinit");
 }
 
        return;
 bad:
        panic("mbinit");
 }
 
+/*
+ * Must be called at splimp.
+ */
 caddr_t
 caddr_t
-m_clalloc(ncl, how)
+m_clalloc(ncl, how, canwait)
        register int ncl;
        int how;
 {
        int npg, mbx;
        register struct mbuf *m;
        register int i;
        register int ncl;
        int how;
 {
        int npg, mbx;
        register struct mbuf *m;
        register int i;
-       int s;
 
 
-COUNT(M_CLALLOC);
        npg = ncl * CLSIZE;
        npg = ncl * CLSIZE;
-       s = splimp();           /* careful: rmalloc isn't reentrant */
-       mbx = rmalloc(mbmap, npg);
-       splx(s);
-       if (mbx == 0)
+       mbx = rmalloc(mbmap, (long)npg);
+       if (mbx == 0) {
+               if (canwait == M_WAIT)
+                       panic("out of mbuf map");
                return (0);
                return (0);
+       }
        m = cltom(mbx / CLSIZE);
        m = cltom(mbx / CLSIZE);
-       if (memall(&Mbmap[mbx], ncl * CLSIZE, proc, CSYS) == 0)
+       if (memall(&Mbmap[mbx], npg, proc, CSYS) == 0) {
+               rmfree(mbmap, (long)npg, (long)mbx);
                return (0);
                return (0);
+       }
        vmaccess(&Mbmap[mbx], (caddr_t)m, npg);
        switch (how) {
 
        case MPG_CLUSTERS:
        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);
                for (i = 0; i < ncl; i++) {
                        m->m_off = 0;
                        m->m_next = mclfree;
                        mclfree = m;
                        m += CLBYTES / sizeof (*m);
-                       nmclfree++;
+                       mbstat.m_clfree++;
                }
                mbstat.m_clusters += ncl;
                }
                mbstat.m_clusters += ncl;
-               splx(s);
                break;
 
        case MPG_MBUFS:
                for (i = ncl * CLBYTES / sizeof (*m); i > 0; i--) {
                        m->m_off = 0;
                break;
 
        case MPG_MBUFS:
                for (i = ncl * CLBYTES / sizeof (*m); i > 0; i--) {
                        m->m_off = 0;
-                       m->m_free = 0;
+                       m->m_type = MT_DATA;
+                       mbstat.m_mtypes[MT_DATA]++;
+                       mbstat.m_mbufs++;
                        (void) m_free(m);
                        m++;
                }
                        (void) m_free(m);
                        m++;
                }
-               mbstat.m_clusters += ncl;
                break;
        }
        return ((caddr_t)m);
                break;
        }
        return ((caddr_t)m);
@@ -80,16 +90,19 @@ m_pgfree(addr, n)
        int n;
 {
 
        int n;
 {
 
-COUNT(M_PGFREE);
+#ifdef lint
+       addr = addr; n = n;
+#endif
 }
 
 }
 
-m_expand()
+/*
+ * Must be called at splimp.
+ */
+m_expand(canwait)
+       int canwait;
 {
 
 {
 
-COUNT(M_EXPAND);
-       if (mbstat.m_bufs >= mbstat.m_hiwat)
-               return (0);
-       if (m_clalloc(1, MPG_MBUFS) == 0)
+       if (m_clalloc(1, MPG_MBUFS, canwait) == 0)
                goto steal;
        return (1);
 steal:
                goto steal;
        return (1);
 steal:
@@ -99,55 +112,30 @@ steal:
 
 /* NEED SOME WAY TO RELEASE SPACE */
 
 
 /* NEED SOME WAY TO RELEASE SPACE */
 
-/*
- * Space reservation routines
- */
-m_reserve(mbufs)
-       int mbufs;
-{
-
-       if (mbstat.m_lowat + (mbufs>>1) > (NMBCLUSTERS-32) * CLBYTES) 
-               return (0);
-       mbstat.m_hiwat += mbufs;
-       mbstat.m_lowat = mbstat.m_hiwat >> 1;
-       return (1);
-}
-
-m_release(mbufs)
-       int mbufs;
-{
-
-       mbstat.m_hiwat -= mbufs;
-       mbstat.m_lowat = mbstat.m_hiwat >> 1;
-}
-
 /*
  * Space allocation routines.
  * These are also available as macros
  * for critical paths.
  */
 struct mbuf *
 /*
  * Space allocation routines.
  * These are also available as macros
  * for critical paths.
  */
 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);
+       MGET(m, 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);
 }
@@ -158,25 +146,32 @@ m_free(m)
 {
        register struct mbuf *n;
 
 {
        register struct mbuf *n;
 
-COUNT(M_FREE);
        MFREE(m, n);
        return (n);
 }
 
        MFREE(m, n);
        return (n);
 }
 
+/*
+ * Get more mbufs; called from MGET macro if mfree list is empty.
+ * Must be called at splimp.
+ */
 /*ARGSUSED*/
 struct mbuf *
 /*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);
+       while (m_expand(canwait) == 0) {
+               if (canwait == M_WAIT) {
+                       m_want++;
+                       sleep((caddr_t)mfree, PZERO - 1);
+               } else {
+                       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);
 }
 #undef m_more
        return (m);
 }
@@ -187,7 +182,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();
@@ -200,6 +194,12 @@ COUNT(M_FREEM);
 /*
  * Mbuffer utility routines.
  */
 /*
  * Mbuffer utility routines.
  */
+
+/*
+ * Make a copy of an mbuf chain starting "off" bytes from the beginning,
+ * continuing for "len" bytes.  If len is M_COPYALL, copy to end of mbuf.
+ * Should get M_WAIT/M_DONTWAIT from caller.
+ */
 struct mbuf *
 m_copy(m, off, len)
        register struct mbuf *m;
 struct mbuf *
 m_copy(m, off, len)
        register struct mbuf *m;
@@ -208,7 +208,6 @@ 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);
 
        if (len == 0)
                return (0);
 
        if (len == 0)
                return (0);
@@ -230,7 +229,7 @@ COUNT(M_COPY);
                                panic("m_copy");
                        break;
                }
                                panic("m_copy");
                        break;
                }
-               MGET(n, 1);
+               MGET(n, M_DONTWAIT, m->m_type);
                *np = n;
                if (n == 0)
                        goto nospace;
                *np = n;
                if (n == 0)
                        goto nospace;
@@ -239,11 +238,9 @@ COUNT(M_COPY);
                        p = mtod(m, struct mbuf *);
                        n->m_off = ((int)p - (int)n) + off;
                        mclrefcnt[mtocl(p)]++;
                        p = mtod(m, struct mbuf *);
                        n->m_off = ((int)p - (int)n) + off;
                        mclrefcnt[mtocl(p)]++;
-               } else {
-                       n->m_off = MMINOFF;
+               } 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);
-               }
                if (len != M_COPYALL)
                        len -= n->m_len;
                off = 0;
                if (len != M_COPYALL)
                        len -= n->m_len;
                off = 0;
@@ -259,20 +256,21 @@ nospace:
 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)
@@ -281,7 +279,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) {
@@ -322,25 +319,25 @@ m_pullup(m0, len)
        int len;
 {
        register struct mbuf *m, *n;
        int len;
 {
        register struct mbuf *m, *n;
-       int cnt;
+       int count;
 
 
+       n = m0;
        if (len > MLEN)
                goto bad;
        if (len > MLEN)
                goto bad;
-       MGET(m, 0);
+       MGET(m, M_DONTWAIT, n->m_type);
        if (m == 0)
                goto bad;
        if (m == 0)
                goto bad;
-       m->m_off = MMINOFF;
        m->m_len = 0;
        m->m_len = 0;
-       n = m0;
        do {
        do {
-               cnt = MIN(MLEN - m->m_len, len);
-               if (cnt > n->m_len)
-                       cnt = n->m_len;
-               bcopy(mtod(n, caddr_t), mtod(m, caddr_t)+m->m_len, cnt);
-               len -= cnt;
-               m->m_len += cnt;
-               n->m_off += cnt;
-               n->m_len -= cnt;
+               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);
                if (n->m_len)
                        break;
                n = m_free(n);
@@ -352,6 +349,6 @@ m_pullup(m0, len)
        m->m_next = n;
        return (m);
 bad:
        m->m_next = n;
        return (m);
 bad:
-       m_freem(m0);
+       m_freem(n);
        return (0);
 }
        return (0);
 }