-/* uipc_mbuf.c 6.1 83/07/29 */
+/*
+ * 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/cmap.h"
-#include "../h/map.h"
-#include "../h/mbuf.h"
-#include "../h/vm.h"
-#include "../h/kernel.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;
- if (m_clalloc(4096/CLBYTES, MPG_MBUFS) == 0)
+ s = splimp();
+ if (m_clalloc(4096/CLBYTES, MPG_MBUFS, M_DONTWAIT) == 0)
goto bad;
- if (m_clalloc(8*4096/CLBYTES, 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;
npg = ncl * CLSIZE;
- s = splimp(); /* careful: rmalloc isn't reentrant */
mbx = rmalloc(mbmap, (long)npg);
- splx(s);
- if (mbx == 0)
+ if (mbx == 0) {
+ if (canwait == M_WAIT)
+ panic("out of mbuf map");
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);
}
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;
mbstat.m_clfree++;
}
mbstat.m_clusters += ncl;
- splx(s);
break;
case MPG_MBUFS:
#endif
}
-m_expand()
+/*
+ * Must be called at splimp.
+ */
+m_expand(canwait)
+ int canwait;
{
- if (m_clalloc(1, MPG_MBUFS) == 0)
+ if (m_clalloc(1, MPG_MBUFS, canwait) == 0)
goto steal;
return (1);
steal:
{
register struct mbuf *m;
- m = m_get(canwait, type);
+ MGET(m, canwait, type);
if (m == 0)
return (0);
bzero(mtod(m, caddr_t), MLEN);
return (n);
}
+/*
+ * Get more mbufs; called from MGET macro if mfree list is empty.
+ * Must be called at splimp.
+ */
/*ARGSUSED*/
struct mbuf *
m_more(canwait, type)
{
register struct mbuf *m;
- 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,y) (panic("m_more"), (struct mbuf *)0)
MGET(m, canwait, type);
/*
* 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;
{
register struct mbuf *n, **np;
struct mbuf *top, *p;
- int type;
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");
panic("m_copy");
break;
}
- MGET(n, M_WAIT, type);
+ MGET(n, M_DONTWAIT, m->m_type);
*np = n;
if (n == 0)
goto nospace;