"panic: fxp_start_body: attempted use of a free mbuf!" in
RELENG_5
Brian Fundakowski Feldman
green at FreeBSD.org
Thu Oct 7 13:48:47 PDT 2004
On Thu, Oct 07, 2004 at 09:57:19AM -0700, Kris Kennaway wrote:
> Top of RELENG_5 on an smp machine:
>
> panic: fxp_start_body: attempted use of a free mbuf!
> cpuid = 1
> KDB: enter: panic
> [thread 100042]
> Stopped at kdb_enter+0x30: leave
> db> trace
> kdb_enter(c06de69a,1,c06d47c5,ebbd2b14,c34cd320) at kdb_enter+0x30
> panic(c06d47c5,c06c1030,4,c0499300,c3539000) at panic+0x14e
> fxp_start_body(c3539000,0,c06d5639,4ca,c3539000) at fxp_start_body+0x462
> fxp_start(c3539000,122,0,c3539000) at fxp_start+0x3f
> if_start(c3539000,0,c06e7822,179,ffff8002) at if_start+0x99
> ether_output_frame(c3539000,c38b5300,6,c4106b00,ebbd2bc8) at ether_output_frame+0x218
> ether_output(c3539000,c38b5300,c4106b00,c95ec210,c04fe48d) at ether_output+0x43e
> in_arpinput(c38b8700,122,c38b8700,c07656b8,c38b8700) at in_arpinput+0x686
> arpintr(c38b8700,0,c06e7c88,e5,c07656b8) at arpintr+0x104
> netisr_processqueue(c07656b8,c0738ac0,1,c06dda24,c3462940) at netisr_processqueue+0x8e
> swi_net(0,0,c06dc037,269,c0738ac0) at swi_net+0xe9
> ithread_loop(c345d880,ebbd2d48,c06dbe2a,323,d552d9c9) at ithread_loop+0x172
> fork_exit(c04f1210,c345d880,ebbd2d48) at fork_exit+0xc6
> fork_trampoline() at fork_trampoline+0x8
> --- trap 0x1, eip = 0, esp = 0xebbd2d7c, ebp = 0 ---
Does this fix it?
Index: uma_core.c
===================================================================
RCS file: /usr/ncvs/src/sys/vm/uma_core.c,v
retrieving revision 1.105
diff -u -r1.105 uma_core.c
--- uma_core.c 6 Aug 2004 21:52:38 -0000 1.105
+++ uma_core.c 7 Oct 2004 20:31:08 -0000
@@ -825,13 +825,16 @@
slab->us_freecount = keg->uk_ipers;
slab->us_firstfree = 0;
slab->us_flags = flags;
- for (i = 0; i < keg->uk_ipers; i++)
- slab->us_freelist[i].us_item = i+1;
if (keg->uk_flags & UMA_ZONE_REFCNT) {
slabref = (uma_slabrefcnt_t)slab;
- for (i = 0; i < keg->uk_ipers; i++)
+ for (i = 0; i < keg->uk_ipers; i++) {
slabref->us_freelist[i].us_refcnt = 0;
+ slabref->us_freelist[i].us_item = i+1;
+ }
+ } else {
+ for (i = 0; i < keg->uk_ipers; i++)
+ slab->us_freelist[i].us_item = i+1;
}
if (keg->uk_init != NULL) {
@@ -1983,13 +1986,19 @@
uma_slab_alloc(uma_zone_t zone, uma_slab_t slab)
{
uma_keg_t keg;
+ uma_slabrefcnt_t slabref;
void *item;
u_int8_t freei;
keg = zone->uz_keg;
freei = slab->us_firstfree;
- slab->us_firstfree = slab->us_freelist[freei].us_item;
+ if (keg->uk_flags & UMA_ZONE_REFCNT) {
+ slabref = (uma_slabrefcnt_t)slab;
+ slab->us_firstfree = slabref->us_freelist[freei].us_item;
+ } else {
+ slab->us_firstfree = slab->us_freelist[freei].us_item;
+ }
item = slab->us_data + (keg->uk_rsize * freei);
slab->us_freecount--;
@@ -2339,6 +2348,7 @@
enum zfreeskip skip)
{
uma_slab_t slab;
+ uma_slabrefcnt_t slabref;
uma_keg_t keg;
u_int8_t *mem;
u_int8_t freei;
@@ -2382,7 +2392,12 @@
uma_dbg_free(zone, slab, item);
#endif
- slab->us_freelist[freei].us_item = slab->us_firstfree;
+ if (keg->uk_flags & UMA_ZONE_REFCNT) {
+ slabref = (uma_slabrefcnt_t)slab;
+ slabref->us_freelist[freei].us_item = slab->us_firstfree;
+ } else {
+ slab->us_freelist[freei].us_item = slab->us_firstfree;
+ }
slab->us_firstfree = freei;
slab->us_freecount++;
@@ -2545,18 +2560,19 @@
u_int32_t *
uma_find_refcnt(uma_zone_t zone, void *item)
{
- uma_slabrefcnt_t slab;
+ uma_slabrefcnt_t slabref;
uma_keg_t keg;
u_int32_t *refcnt;
int idx;
keg = zone->uz_keg;
- slab = (uma_slabrefcnt_t)vtoslab((vm_offset_t)item & (~UMA_SLAB_MASK));
- KASSERT(slab != NULL,
+ slabref = (uma_slabrefcnt_t)vtoslab((vm_offset_t)item &
+ (~UMA_SLAB_MASK));
+ KASSERT(slabref != NULL && slabref->us_keg->uk_flags & UMA_ZONE_REFCNT,
("uma_find_refcnt(): zone possibly not UMA_ZONE_REFCNT"));
- idx = ((unsigned long)item - (unsigned long)slab->us_data)
+ idx = ((unsigned long)item - (unsigned long)slabref->us_data)
/ keg->uk_rsize;
- refcnt = &(slab->us_freelist[idx].us_refcnt);
+ refcnt = &slabref->us_freelist[idx].us_refcnt;
return refcnt;
}
Index: uma_dbg.c
===================================================================
RCS file: /usr/ncvs/src/sys/vm/uma_dbg.c,v
retrieving revision 1.15
diff -u -r1.15 uma_dbg.c
--- uma_dbg.c 2 Aug 2004 00:18:35 -0000 1.15
+++ uma_dbg.c 7 Oct 2004 20:35:22 -0000
@@ -218,6 +218,7 @@
uma_dbg_alloc(uma_zone_t zone, uma_slab_t slab, void *item)
{
uma_keg_t keg;
+ uma_slabrefcnt_t slabref;
int freei;
keg = zone->uz_keg;
@@ -231,7 +232,12 @@
freei = ((unsigned long)item - (unsigned long)slab->us_data)
/ keg->uk_rsize;
- slab->us_freelist[freei].us_item = 255;
+ if (keg->uk_flags & UMA_ZONE_REFCNT) {
+ slabref = (uma_slabrefcnt_t)slab;
+ slabref->us_freelist[freei].us_item = 255;
+ } else {
+ slab->us_freelist[freei].us_item = 255;
+ }
return;
}
@@ -246,6 +252,7 @@
uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item)
{
uma_keg_t keg;
+ uma_slabrefcnt_t slabref;
int freei;
keg = zone->uz_keg;
@@ -270,17 +277,34 @@
(freei * keg->uk_rsize) + slab->us_data);
}
- if (slab->us_freelist[freei].us_item != 255) {
- printf("Slab at %p, freei %d = %d.\n",
- slab, freei, slab->us_freelist[freei].us_item);
- panic("Duplicate free of item %p from zone %p(%s)\n",
- item, zone, zone->uz_name);
+ if (keg->uk_flags & UMA_ZONE_REFCNT) {
+ slabref = (uma_slabrefcnt_t)slab;
+ if (slabref->us_freelist[freei].us_item != 255) {
+ printf("Slab at %p, freei %d = %d.\n",
+ slab, freei, slabref->us_freelist[freei].us_item);
+ panic("Duplicate free of item %p from zone %p(%s)\n",
+ item, zone, zone->uz_name);
+ }
+
+ /*
+ * When this is actually linked into the slab this will change.
+ * Until then the count of valid slabs will make sure we don't
+ * accidentally follow this and assume it's a valid index.
+ */
+ slabref->us_freelist[freei].us_item = 0;
+ } else {
+ if (slab->us_freelist[freei].us_item != 255) {
+ printf("Slab at %p, freei %d = %d.\n",
+ slab, freei, slab->us_freelist[freei].us_item);
+ panic("Duplicate free of item %p from zone %p(%s)\n",
+ item, zone, zone->uz_name);
+ }
+
+ /*
+ * When this is actually linked into the slab this will change.
+ * Until then the count of valid slabs will make sure we don't
+ * accidentally follow this and assume it's a valid index.
+ */
+ slab->us_freelist[freei].us_item = 0;
}
-
- /*
- * When this is actually linked into the slab this will change.
- * Until then the count of valid slabs will make sure we don't
- * accidentally follow this and assume it's a valid index.
- */
- slab->us_freelist[freei].us_item = 0;
}
--
Brian Fundakowski Feldman \'[ FreeBSD ]''''''''''\
<> green at FreeBSD.org \ The Power to Serve! \
Opinions expressed are my own. \,,,,,,,,,,,,,,,,,,,,,,\
More information about the freebsd-net
mailing list