X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/842ff04209a7b6e803651b9b6100194def68416a..da7c5cc62d0962b5d290c48159695646218b130b:/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 91e91789c3..ca8d4af43c 100644 --- a/usr/src/sys/kern/uipc_mbuf.c +++ b/usr/src/sys/kern/uipc_mbuf.c @@ -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() { + 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; - if (m_clalloc(32, MPG_CLUSTERS) == 0) + if (m_clalloc(8*4096/CLBYTES, MPG_CLUSTERS, M_DONTWAIT) == 0) goto bad; + splx(s); return; bad: panic("mbinit"); } +/* + * Must be called at splimp. + */ 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; - int s; -COUNT(M_CLALLOC); 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); + } 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); + } 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); - nmclfree++; + 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_free = 0; + m->m_type = MT_DATA; + mbstat.m_mtypes[MT_DATA]++; + mbstat.m_mbufs++; (void) m_free(m); m++; } - mbstat.m_clusters += ncl; break; } return ((caddr_t)m); @@ -80,16 +90,19 @@ m_pgfree(addr, 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: @@ -99,55 +112,30 @@ steal: /* 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 * -m_get(canwait) - int canwait; +m_get(canwait, type) + int canwait, type; { register struct mbuf *m; -COUNT(M_GET); - MGET(m, canwait); + MGET(m, canwait, type); return (m); } struct mbuf * -m_getclr(canwait) - int canwait; +m_getclr(canwait, type) + int canwait, type; { register struct mbuf *m; -COUNT(M_GETCLR); - m = m_get(canwait); + MGET(m, canwait, type); if (m == 0) return (0); - m->m_off = MMINOFF; bzero(mtod(m, caddr_t), MLEN); return (m); } @@ -158,25 +146,32 @@ m_free(m) { register struct mbuf *n; -COUNT(M_FREE); 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 * -m_more(type) - int type; +m_more(canwait, type) + int canwait, type; { 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); } @@ -187,7 +182,6 @@ m_freem(m) register struct mbuf *n; register int s; -COUNT(M_FREEM); if (m == NULL) return; s = splimp(); @@ -200,6 +194,12 @@ COUNT(M_FREEM); /* * 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; @@ -208,7 +208,6 @@ m_copy(m, off, len) { register struct mbuf *n, **np; struct mbuf *top, *p; -COUNT(M_COPY); if (len == 0) return (0); @@ -230,7 +229,7 @@ COUNT(M_COPY); panic("m_copy"); break; } - MGET(n, 1); + MGET(n, M_DONTWAIT, m->m_type); *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)]++; - } else { - n->m_off = MMINOFF; + } 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; @@ -259,20 +256,21 @@ nospace: 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, - (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 = 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) @@ -281,7 +279,6 @@ m_adj(mp, len) { register struct mbuf *m, *n; -COUNT(M_ADJ); if ((m = mp) == NULL) return; if (len >= 0) { @@ -322,25 +319,25 @@ m_pullup(m0, len) int len; { register struct mbuf *m, *n; - int cnt; + int count; + n = m0; if (len > MLEN) goto bad; - MGET(m, 0); + MGET(m, M_DONTWAIT, n->m_type); if (m == 0) goto bad; - m->m_off = MMINOFF; m->m_len = 0; - n = m0; 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); @@ -352,6 +349,6 @@ m_pullup(m0, len) m->m_next = n; return (m); bad: - m_freem(m0); + m_freem(n); return (0); }