diff options
author | andre <andre@FreeBSD.org> | 2005-11-04 17:20:53 +0000 |
---|---|---|
committer | andre <andre@FreeBSD.org> | 2005-11-04 17:20:53 +0000 |
commit | 438cb7bde701ce0b9a4dffe748bd0f98a9621770 (patch) | |
tree | 6fd7fe096545c90fb4216ae8f8172a94f08c19a3 /sys/kern | |
parent | 1aceee70b0e0f10ab5c1556417c9a033f8342137 (diff) | |
download | FreeBSD-src-438cb7bde701ce0b9a4dffe748bd0f98a9621770.zip FreeBSD-src-438cb7bde701ce0b9a4dffe748bd0f98a9621770.tar.gz |
Fix a logic error introduced with mandatory mbuf cluster refcounting and
freeing of mbufs+clusters back to the packet zone.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_mbuf.c | 7 | ||||
-rw-r--r-- | sys/kern/uipc_mbuf.c | 6 |
2 files changed, 7 insertions, 6 deletions
diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c index e02acca..ffb3e80 100644 --- a/sys/kern/kern_mbuf.c +++ b/sys/kern/kern_mbuf.c @@ -395,11 +395,10 @@ mb_ctor_clust(void *mem, int size, void *arg, int how) static void mb_dtor_clust(void *mem, int size, void *arg) { - u_int *refcnt; - refcnt = uma_find_refcnt(zone_clust, mem); - KASSERT(*refcnt == 1, ("%s: refcnt incorrect %u", __func__, *refcnt)); - *refcnt = 0; + KASSERT(*(uma_find_refcnt(zone_clust, mem)) <= 1, + ("%s: refcnt incorrect %u", __func__, + *(uma_find_refcnt(zone_clust, mem))) ); #ifdef INVARIANTS trash_dtor(mem, size, arg); #endif diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 9d90e01..4e0f2d9 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -215,9 +215,11 @@ mb_free_ext(struct mbuf *m) /* Free attached storage if this mbuf is the only reference to it. */ if (*(m->m_ext.ref_cnt) == 1 || - atomic_fetchadd_int(m->m_ext.ref_cnt, -1) == 1) { + atomic_fetchadd_int(m->m_ext.ref_cnt, -1) == 0) { switch (m->m_ext.ext_type) { - case EXT_CLUSTER: + case EXT_CLUSTER: /* The packet zone is special. */ + if (*(m->m_ext.ref_cnt) == 0) + *(m->m_ext.ref_cnt) = 1; uma_zfree(zone_pack, m); return; /* Job done. */ break; |