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

From: Robert Watson <rwatson_at_FreeBSD.org>
Date: Thu, 24 Feb 2005 10:05:30 +0000 (GMT)
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:

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"
> 
Received on Thu Feb 24 2005 - 09:07:14 UTC

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