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 <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
3ac5d98070
commit
a68e59dd1d
@@ -235,7 +235,6 @@ m_cljget(struct mbuf* memoryBuffer, int how, int size)
|
|||||||
static void
|
static void
|
||||||
mb_free_ext(struct mbuf *memoryBuffer)
|
mb_free_ext(struct mbuf *memoryBuffer)
|
||||||
{
|
{
|
||||||
object_cache *cache = NULL;
|
|
||||||
volatile u_int *refcnt;
|
volatile u_int *refcnt;
|
||||||
struct mbuf *mref;
|
struct mbuf *mref;
|
||||||
int freembuf;
|
int freembuf;
|
||||||
@@ -270,22 +269,24 @@ mb_free_ext(struct mbuf *memoryBuffer)
|
|||||||
freembuf = 1;
|
freembuf = 1;
|
||||||
|
|
||||||
/* Free attached storage only if this mbuf is the only reference to it. */
|
/* Free attached storage only if this mbuf is the only reference to it. */
|
||||||
if (!(*refcnt == 1 || atomic_add(refcnt, -1) == 1)
|
if (*refcnt == 1 || atomic_add((int32*)refcnt, -1) == 1) {
|
||||||
&& !(freembuf && memoryBuffer != mref))
|
object_cache *cache = NULL;
|
||||||
return;
|
|
||||||
|
|
||||||
if (memoryBuffer->m_ext.ext_type == EXT_CLUSTER)
|
if (memoryBuffer->m_ext.ext_type == EXT_CLUSTER)
|
||||||
cache = sChunkCache;
|
cache = sChunkCache;
|
||||||
else if (memoryBuffer->m_ext.ext_type == EXT_JUMBO9)
|
else if (memoryBuffer->m_ext.ext_type == EXT_JUMBO9)
|
||||||
cache = sJumbo9ChunkCache;
|
cache = sJumbo9ChunkCache;
|
||||||
else if (memoryBuffer->m_ext.ext_type == EXT_JUMBOP)
|
else if (memoryBuffer->m_ext.ext_type == EXT_JUMBOP)
|
||||||
cache = sJumboPageSizeCache;
|
cache = sJumboPageSizeCache;
|
||||||
else
|
else
|
||||||
panic("unknown mbuf ext_type %d", memoryBuffer->m_ext.ext_type);
|
panic("unknown mbuf ext_type %d", memoryBuffer->m_ext.ext_type);
|
||||||
|
|
||||||
object_cache_free(cache, memoryBuffer->m_ext.ext_buf, 0);
|
object_cache_free(cache, memoryBuffer->m_ext.ext_buf, 0);
|
||||||
memoryBuffer->m_ext.ext_buf = NULL;
|
object_cache_free(sMBufCache, mref, 0);
|
||||||
object_cache_free(sMBufCache, memoryBuffer, 0);
|
}
|
||||||
|
|
||||||
|
if (freembuf && memoryBuffer != mref)
|
||||||
|
object_cache_free(sMBufCache, memoryBuffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user