From owner-freebsd-current@FreeBSD.ORG Thu Oct 7 20:48:47 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from green.homeunix.org (freefall.freebsd.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id C734916A4CF; Thu, 7 Oct 2004 20:48:46 +0000 (GMT) Received: from green.homeunix.org (green@localhost [127.0.0.1]) by green.homeunix.org (8.13.1/8.13.1) with ESMTP id i97Kmkg0097829; Thu, 7 Oct 2004 16:48:46 -0400 (EDT) (envelope-from green@green.homeunix.org) Received: (from green@localhost) by green.homeunix.org (8.13.1/8.13.1/Submit) id i97Kmimt097828; Thu, 7 Oct 2004 16:48:44 -0400 (EDT) (envelope-from green) Date: Thu, 7 Oct 2004 16:48:44 -0400 From: Brian Fundakowski Feldman To: Kris Kennaway Message-ID: <20041007204844.GE73261@green.homeunix.org> References: <20041007165719.GA4023@xor.obsecurity.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20041007165719.GA4023@xor.obsecurity.org> User-Agent: Mutt/1.5.6i cc: current@FreeBSD.org cc: net@FreeBSD.org Subject: Re: "panic: fxp_start_body: attempted use of a free mbuf!" in RELENG_5 X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Oct 2004 20:48:47 -0000 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@FreeBSD.org \ The Power to Serve! \ Opinions expressed are my own. \,,,,,,,,,,,,,,,,,,,,,,\