freebsd_network: Fix destruction of ref-counted ext_bufs.
The check as to whether or not the buf should be freed was wrong, leading to incorrect frees. Fixes double-free KDLs under the idualwifi driver that occur on boot extremely frequently. Change-Id: Ia411a6f5c31dd30764705cd87840797f862b4020 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2862 Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
3ac5d98070
commit
a68e59dd1d
@ -235,7 +235,6 @@ m_cljget(struct mbuf* memoryBuffer, int how, int size)
|
||||
static void
|
||||
mb_free_ext(struct mbuf *memoryBuffer)
|
||||
{
|
||||
object_cache *cache = NULL;
|
||||
volatile u_int *refcnt;
|
||||
struct mbuf *mref;
|
||||
int freembuf;
|
||||
@ -270,22 +269,24 @@ mb_free_ext(struct mbuf *memoryBuffer)
|
||||
freembuf = 1;
|
||||
|
||||
/* Free attached storage only if this mbuf is the only reference to it. */
|
||||
if (!(*refcnt == 1 || atomic_add(refcnt, -1) == 1)
|
||||
&& !(freembuf && memoryBuffer != mref))
|
||||
return;
|
||||
if (*refcnt == 1 || atomic_add((int32*)refcnt, -1) == 1) {
|
||||
object_cache *cache = NULL;
|
||||
|
||||
if (memoryBuffer->m_ext.ext_type == EXT_CLUSTER)
|
||||
cache = sChunkCache;
|
||||
else if (memoryBuffer->m_ext.ext_type == EXT_JUMBO9)
|
||||
cache = sJumbo9ChunkCache;
|
||||
else if (memoryBuffer->m_ext.ext_type == EXT_JUMBOP)
|
||||
cache = sJumboPageSizeCache;
|
||||
else
|
||||
panic("unknown mbuf ext_type %d", memoryBuffer->m_ext.ext_type);
|
||||
if (memoryBuffer->m_ext.ext_type == EXT_CLUSTER)
|
||||
cache = sChunkCache;
|
||||
else if (memoryBuffer->m_ext.ext_type == EXT_JUMBO9)
|
||||
cache = sJumbo9ChunkCache;
|
||||
else if (memoryBuffer->m_ext.ext_type == EXT_JUMBOP)
|
||||
cache = sJumboPageSizeCache;
|
||||
else
|
||||
panic("unknown mbuf ext_type %d", memoryBuffer->m_ext.ext_type);
|
||||
|
||||
object_cache_free(cache, memoryBuffer->m_ext.ext_buf, 0);
|
||||
memoryBuffer->m_ext.ext_buf = NULL;
|
||||
object_cache_free(sMBufCache, memoryBuffer, 0);
|
||||
object_cache_free(cache, memoryBuffer->m_ext.ext_buf, 0);
|
||||
object_cache_free(sMBufCache, mref, 0);
|
||||
}
|
||||
|
||||
if (freembuf && memoryBuffer != mref)
|
||||
object_cache_free(sMBufCache, memoryBuffer, 0);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user