diff options
author | alfred <alfred@FreeBSD.org> | 2004-07-21 07:12:24 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2004-07-21 07:12:24 +0000 |
commit | 53db4c36fadd491dbf171e8e3614b182fc130ced (patch) | |
tree | 09085bbe2d70870f8c8c9bfc9db7ecd09a460b36 /sys | |
parent | be4d9dd8f3f7b0d6f5f89e8a9381a447de73bec5 (diff) | |
download | FreeBSD-src-53db4c36fadd491dbf171e8e3614b182fc130ced.zip FreeBSD-src-53db4c36fadd491dbf171e8e3614b182fc130ced.tar.gz |
Make sure we don't call mbuf allocation functions with mutexes held.
Discussed with: rwatson
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/uipc_mbuf.c | 8 | ||||
-rw-r--r-- | sys/kern/uipc_mbuf2.c | 4 | ||||
-rw-r--r-- | sys/sys/mbuf.h | 16 |
3 files changed, 28 insertions, 0 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 339e05d..a9a93fd 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -105,6 +105,7 @@ m_getm(struct mbuf *m, int len, int how, short type) int i; KASSERT(len >= 0, ("m_getm(): len is < 0")); + MBUF_CHECKSLEEP(how); /* If m != NULL, we will append to the end of that chain. */ if (m != NULL) @@ -307,6 +308,7 @@ m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how) /* Note: with MAC, this may not be a good assertion. */ KASSERT(SLIST_EMPTY(&to->m_pkthdr.tags), ("m_dup_pkthdr: to has tags")); #endif + MBUF_CHECKSLEEP(how); #ifdef MAC if (to->m_flags & M_PKTHDR) m_tag_delete_chain(to, NULL); @@ -329,6 +331,7 @@ m_prepend(struct mbuf *m, int len, int how) { struct mbuf *mn; + MBUF_CHECKSLEEP(how); if (m->m_flags & M_PKTHDR) MGETHDR(mn, how, m->m_type); else @@ -364,6 +367,7 @@ m_copym(struct mbuf *m, int off0, int len, int wait) KASSERT(off >= 0, ("m_copym, negative off %d", off)); KASSERT(len >= 0, ("m_copym, negative len %d", len)); + MBUF_CHECKSLEEP(wait); if (off == 0 && m->m_flags & M_PKTHDR) copyhdr = 1; while (off > 0) { @@ -436,6 +440,7 @@ m_copypacket(struct mbuf *m, int how) { struct mbuf *top, *n, *o; + MBUF_CHECKSLEEP(how); MGET(n, how, m->m_type); top = n; if (n == NULL) @@ -522,6 +527,7 @@ m_dup(struct mbuf *m, int how) struct mbuf **p, *top = NULL; int remain, moff, nsize; + MBUF_CHECKSLEEP(how); /* Sanity check */ if (m == NULL) return (NULL); @@ -760,6 +766,7 @@ m_split(struct mbuf *m0, int len0, int wait) struct mbuf *m, *n; u_int len = len0, remain; + MBUF_CHECKSLEEP(wait); for (m = m0; m && len > m->m_len; m = m->m_next) len -= m->m_len; if (m == NULL) @@ -1049,6 +1056,7 @@ m_defrag(struct mbuf *m0, int how) struct mbuf *m_new = NULL, *m_final = NULL; int progress = 0, length; + MBUF_CHECKSLEEP(how); if (!(m0->m_flags & M_PKTHDR)) return (m0); diff --git a/sys/kern/uipc_mbuf2.c b/sys/kern/uipc_mbuf2.c index ff7944d..f5a35ca 100644 --- a/sys/kern/uipc_mbuf2.c +++ b/sys/kern/uipc_mbuf2.c @@ -318,6 +318,7 @@ m_tag_alloc(u_int32_t cookie, int type, int len, int wait) { struct m_tag *t; + MBUF_CHECKSLEEP(wait); if (len < 0) return NULL; t = malloc(len + sizeof(struct m_tag), M_PACKET_TAGS, wait); @@ -332,6 +333,7 @@ m_tag_alloc(u_int32_t cookie, int type, int len, int wait) void m_tag_delete(struct mbuf *m, struct m_tag *t) { + KASSERT(m && t, ("m_tag_delete: null argument, m %p t %p", m, t)); m_tag_unlink(m, t); m_tag_free(t); @@ -397,6 +399,7 @@ m_tag_copy(struct m_tag *t, int how) { struct m_tag *p; + MBUF_CHECKSLEEP(how); KASSERT(t, ("m_tag_copy: null tag")); p = m_tag_alloc(t->m_tag_cookie, t->m_tag_id, t->m_tag_len, how); if (p == NULL) @@ -430,6 +433,7 @@ m_tag_copy_chain(struct mbuf *to, struct mbuf *from, int how) { struct m_tag *p, *t, *tprev = NULL; + MBUF_CHECKSLEEP(how); KASSERT(to && from, ("m_tag_copy_chain: null argument, to %p from %p", to, from)); m_tag_delete_chain(to, NULL); diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index 0ba8e00..34d84f9 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -38,6 +38,9 @@ #ifdef _KERNEL #include <sys/systm.h> #include <vm/uma.h> +#ifdef WITNESS +#include <sys/lock.h> +#endif #endif /* @@ -304,6 +307,12 @@ struct mbstat { #define MEXT_ADD_REF(m) atomic_add_int((m)->m_ext.ref_cnt, 1) +#define MBUF_CHECKSLEEP(how) do { \ + if (how == M_WAITOK) \ + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, \ + "Sleeping in \"%s\"", __func__); \ +} while(0) + /* * Network buffer allocation API * @@ -329,6 +338,7 @@ m_get(int how, short type) { struct mb_args args; + MBUF_CHECKSLEEP(how); args.flags = 0; args.how = how; args.type = type; @@ -343,6 +353,7 @@ m_getclr(int how, short type) struct mbuf *m; struct mb_args args; + MBUF_CHECKSLEEP(how); args.flags = 0; args.how = how; args.type = type; @@ -358,6 +369,7 @@ m_gethdr(int how, short type) { struct mb_args args; + MBUF_CHECKSLEEP(how); args.flags = M_PKTHDR; args.how = how; args.type = type; @@ -370,6 +382,7 @@ m_getcl(int how, short type, int flags) { struct mb_args args; + MBUF_CHECKSLEEP(how); args.flags = flags; args.how = how; args.type = type; @@ -396,6 +409,8 @@ static __inline void m_clget(struct mbuf *m, int how) { + + MBUF_CHECKSLEEP(how); m->m_ext.ext_buf = NULL; uma_zalloc_arg(zone_clust, m, how); } @@ -491,6 +506,7 @@ m_chtype(struct mbuf *m, short new_type) int _mplen = (plen); \ int __mhow = (how); \ \ + MBUF_CHECKSLEEP(how); \ if (M_LEADINGSPACE(_mm) >= _mplen) { \ _mm->m_data -= _mplen; \ _mm->m_len += _mplen; \ |