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 ]''''''''''\
  <> [EMAIL PROTECTED]                               \  The Power to Serve! \
 Opinions expressed are my own.                       \,,,,,,,,,,,,,,,,,,,,,,\
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to