Re: panic: Duplicate free of item 0xc2580a00 from zone 0xc103e9a0(Mbuf)

From: Peter Holm <peter_at_holm.cc>
Date: Sat, 26 Feb 2005 13:40:21 +0100
On Thu, Feb 24, 2005 at 10:05:30AM +0000, Robert Watson wrote:
> On Thu, 24 Feb 2005, Peter Holm wrote:
> 
> > With GENERIC HEAD from Feb 23 06:23 UTC + mpsafe_vfs = 1 I got:
> > 
> > Slab at 0xc2580fa8, freei 10 = 0.  panic: Duplicate free of item
> > 0xc2580a00 from zone 0xc103e9a0(Mbuf) 
> 
> rl_encap() appears to be pretty broken in the event that m_defrag() has to
> allocate a new mbuf on the head of the chain.  Specifcally, rl_encap() 
> may allocate a new head to the chain, but the caller won't use that new
> head, instead using the old head (which may have been free'd, or otherwise
> munged).  This might also explain other crashes or panics involving rl
> interfaces.  I'm surprised this lasted as long as it apparently has in the
> wild (since 2003?).
> 
> Try this patch:
> 

I have used your patch for a day now without seeing any problems.
The hardware is a ASUS P4P800S M/B with an onboard RealTek 8139
10/100BaseTX that I have used for stress testing the last 7
months.

- Peter

> Index: if_rl.c
> ===================================================================
> RCS file: /home/ncvs/src/sys/pci/if_rl.c,v
> retrieving revision 1.147
> diff -u -r1.147 if_rl.c
> --- if_rl.c	11 Feb 2005 01:05:52 -0000	1.147
> +++ if_rl.c	24 Feb 2005 10:03:02 -0000
> _at__at_ -180,7 +180,7 _at__at_
>  static void rl_dma_map_txbuf	(void *, bus_dma_segment_t *, int, int);
>  static void rl_eeprom_putbyte	(struct rl_softc *, int);
>  static void rl_eeprom_getword	(struct rl_softc *, int, uint16_t *);
> -static int rl_encap		(struct rl_softc *, struct mbuf * );
> +static int rl_encap		(struct rl_softc *, struct mbuf ** );
>  static int rl_list_tx_init	(struct rl_softc *);
>  static int rl_ifmedia_upd	(struct ifnet *);
>  static void rl_ifmedia_sts	(struct ifnet *, struct ifmediareq *);
> _at__at_ -1394,9 +1394,10 _at__at_
>   * pointers to the fragment pointers.
>   */
>  static int
> -rl_encap(struct rl_softc *sc, struct mbuf *m_head)
> +rl_encap(struct rl_softc *sc, struct mbuf **m_headp)
>  {
>  	struct mbuf		*m_new = NULL;
> +	struct mbuf		*m_head;
>  
>  	RL_LOCK_ASSERT(sc);
>  
> _at__at_ -1405,10 +1406,12 _at__at_
>  	 * TX buffers, plus we can only have one fragment buffer
>  	 * per packet. We have to copy pretty much all the time.
>  	 */
> +	m_head = *m_headp;
>  	m_new = m_defrag(m_head, M_DONTWAIT);
>  
>  	if (m_new == NULL) {
>  		m_freem(m_head);
> +		*m_headp = NULL;
>  		return (1);
>  	}
>  	m_head = m_new;
> _at__at_ -1429,7 +1432,7 _at__at_
>  	}
>  
>  	RL_CUR_TXMBUF(sc) = m_head;
> -
> +	*m_headp = m_head;
>  	return (0);
>  }
>  
> _at__at_ -1461,7 +1464,7 _at__at_
>  		if (m_head == NULL)
>  			break;
>  
> -		if (rl_encap(sc, m_head))
> +		if (rl_encap(sc, &m_head))
>  			break;
>  
>  		/* Pass a copy of this mbuf chain to the bpf subsystem. */
> 
> 
> 
> > 
> > cpuid = 0
> > KDB: enter: panic
> > [thread pid 37 tid 100013 ]
> > Stopped at      kdb_enter+0x2b: nop
> > db> where
> > Tracing pid 37 tid 100013 td 0xc1524450
> > kdb_enter(c0824c5d) at kdb_enter+0x2b
> > panic(c083ea9c,c2580a00,c103e9a0,c0823405,c083ea80) at panic+0x14b
> > uma_dbg_free(c103e9a0,0,c2580a00) at uma_dbg_free+0x110
> > uma_zfree_arg(c103e9a0,c2580a00,0) at uma_zfree_arg+0xf3
> > m_freem(c2580a00,5ea,3,c15fc8fc,0) at m_freem+0x36
> > m_defrag(c2580a00,1,c15fcf00,1,c08384bf,579) at m_defrag+0x18a
> > rl_encap(c15fc800,c2580a00) at rl_encap+0x2b
> > rl_start_locked(c15fc800,c15fcf00,0,c08384bf,5a4) at rl_start_locked+0x1f3
> > rl_start(c15fc800) at rl_start+0x28
> > if_start(c15fc800) at if_start+0x7b
> > ether_output_frame(c15fc800,c2580a00,0,0,0) at ether_output_frame+0x1d9
> > ether_output(c15fc800,c2580a00,c2467500,c180c7bc,c2264c58) at ether_output+0x380
> > in_arpinput(c2264c00,c2264c00,cbf9bce0,c067eef6,c2264c00) at in_arpinput+0x5a6
> > arpintr(c2264c00) at arpintr+0xca
> > netisr_processqueue(c0951978) at netisr_processqueue+0x6e
> > swi_net(0) at swi_net+0xbe
> > ithread_loop(c154f080,cbf9bd48,c154f080,c05fe964,0) at ithread_loop+0x120
> > fork_exit(c05fe964,c154f080,cbf9bd48) at fork_exit+0xa4
> > fork_trampoline() at fork_trampoline+0x8
> > --- trap 0x1, eip = 0, esp = 0xcbf9bd7c, ebp = 0 ---
> > 
> > Details at http://www.holm.cc/stress/log/cons119.html
> > -- 
> > Peter Holm
> > _______________________________________________
> > freebsd-current_at_freebsd.org mailing list
> > http://lists.freebsd.org/mailman/listinfo/freebsd-current
> > To unsubscribe, send any mail to "freebsd-current-unsubscribe_at_freebsd.org"
> > 

-- 
Peter Holm
Received on Sat Feb 26 2005 - 11:40:28 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:29 UTC