Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 Aug 2005 16:50:11 GMT
From:      Pawel Malachowski <pawmal-posting@freebsd.lublin.pl>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/85258: changing promisc mode on nic can lead to kernel panic
Message-ID:  <200508291650.j7TGoBUn072052@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/85258; it has been noted by GNATS.

From: Pawel Malachowski <pawmal-posting@freebsd.lublin.pl>
To: FreeBSD-gnats-submit@freebsd.org
Cc: freebsd-bugs@freebsd.org
Subject: Re: kern/85258: changing promisc mode on nic can lead to kernel panic
Date: Mon, 29 Aug 2005 18:45:25 +0200

 On Fri, Aug 26, 2005 at 06:40:22PM +0000, Pawel Malachowski wrote:
 
 >  To sum up, factors are:
 >  . dummynet configured for outgoing packets seems to be needed;
 >  . frequent changes of fxp flags, one can use link0 (setting promisc
 >    is not needed at all);
 >  . kern.polling.enable=1.
 
 After todays testing I can say that:
 . switching from polled fxp(4) to polled rl(4) fixes the problem
 . ifconfig fxpX -polling fixes the problem
 . can't reproduce problem od 4.10, this is 5.x specific
 
 I would say fxp_ioctl() in case of SIOCSIFFLAGS is not safe on 5.x when
 fxp device works in polling mode and dummynet makes easier to expose the
 problem.
 
 HTH.
 
 >  I've prepared static kernel for debugging, much better backtrace below. :)
 >  
 >  Test setup:
 >  ipfw pipe 100 config bw 512kbit/s queue 20KB mask src-ip 0xffffffff
 >  ipfw add 100 pipe 100 ip from any to any out xmit wan0
 >  
 >  (wan0 is renamed fxp0)
 >  
 >  while [ 1 ]
 >  do
 >   ifconfig $1 link0
 >   sleep 1
 >   ifconfig $1 -link0
 >   sleep 1
 >  done
 >  
 >  And ping -f from another box to speed things up. ;)
 >  
 >  Full reproducable for me within 10-20 minutes.
 >  
 >  (kgdb) bt
 >  #0  doadump () at pcpu.h:159
 >  #1  0xc060c948 in boot (howto=260) at /usr/src/sys/kern/kern_shutdown.c:410
 >  #2  0xc060cbc6 in panic (fmt=0xc081e7fd "m_copym, offset > size of mbuf chain") at /usr/src/sys/kern/kern_shutdown.c:566
 >  #3  0xc063e500 in m_copym (m=0x0, off0=16380, len=5124, wait=1) at /usr/src/sys/kern/uipc_mbuf.c:385
 >  #4  0xc0697780 in ip_fragment (ip=0xc13fa820, m_frag=0xc7aafc44, mtu=-1051870208, if_hwassist_flags=0, sw_csum=1)
 >      at /usr/src/sys/netinet/ip_output.c:974
 >  #5  0xc0697405 in ip_output (m=0xc13ef700, opt=0xc13fa820, ro=0xc7aafc10, flags=0, imo=0x0, inp=0x0)
 >      at /usr/src/sys/netinet/ip_output.c:798
 >  #6  0xc068b731 in transmit_event (pipe=0xc16e3d00) at /usr/src/sys/netinet/ip_dummynet.c:454
 >  #7  0xc068bab4 in ready_event (q=0xc172e280) at /usr/src/sys/netinet/ip_dummynet.c:624
 >  #8  0xc068c04b in dummynet (unused=0x0) at /usr/src/sys/netinet/ip_dummynet.c:779
 >  #9  0xc0617b12 in softclock (dummy=0x0) at /usr/src/sys/kern/kern_timeout.c:279
 >  #10 0xc05fb4b8 in ithread_loop (arg=0xc12b9500) at /usr/src/sys/kern/kern_intr.c:547
 >  #11 0xc05fa92c in fork_exit (callout=0xc05fb394 <ithread_loop>, arg=0xc12b9500, frame=0xc7aafd48)
 >      at /usr/src/sys/kern/kern_fork.c:791
 >  #12 0xc07a0a4c in fork_trampoline () at /usr/src/sys/i386/i386/exception.s:209
 >  (kgdb) up 3
 >  #3  0xc063e500 in m_copym (m=0x0, off0=16380, len=5124, wait=1) at /usr/src/sys/kern/uipc_mbuf.c:385
 >  385                     KASSERT(m != NULL, ("m_copym, offset > size of mbuf chain"));
 >  (kgdb) l
 >  380             KASSERT(len >= 0, ("m_copym, negative len %d", len));
 >  381             MBUF_CHECKSLEEP(wait);
 >  382             if (off == 0 && m->m_flags & M_PKTHDR)
 >  383                     copyhdr = 1;
 >  384             while (off > 0) {
 >  385                     KASSERT(m != NULL, ("m_copym, offset > size of mbuf chain"));
 >  386                     if (off < m->m_len)
 >  387                             break;
 >  388                     off -= m->m_len;
 >  389                     m = m->m_next;
 >  (kgdb) up
 >  #4  0xc0697780 in ip_fragment (ip=0xc13fa820, m_frag=0xc7aafc44, mtu=-1051870208, if_hwassist_flags=0, sw_csum=1)
 >      at /usr/src/sys/netinet/ip_output.c:974
 >  974                     m->m_next = m_copy(m0, off, len);
 >  (kgdb) l
 >  969                             len = ip->ip_len - off;
 >  970                             m->m_flags |= M_LASTFRAG;
 >  971                     } else
 >  972                             mhip->ip_off |= IP_MF;
 >  973                     mhip->ip_len = htons((u_short)(len + mhlen));
 >  974                     m->m_next = m_copy(m0, off, len);
 >  975                     if (m->m_next == NULL) {        /* copy failed */
 >  976                             m_free(m);
 >  977                             error = ENOBUFS;        /* ??? */
 >  978                             ipstat.ips_odropped++;
 >  (kgdb) up
 >  #5  0xc0697405 in ip_output (m=0xc13ef700, opt=0xc13fa820, ro=0xc7aafc10, flags=0, imo=0x0, inp=0x0)
 >      at /usr/src/sys/netinet/ip_output.c:798
 >  798             error = ip_fragment(ip, &m, ifp->if_mtu, ifp->if_hwassist, sw_csum);
 >  (kgdb) l
 >  793              * Too large for interface; fragment if possible. If successful,
 >  794              * on return, m will point to a list of packets to be sent.
 >  795              */
 >  796     /*if (ifp->if_mtu) {
 >  797     }*/
 >  798             error = ip_fragment(ip, &m, ifp->if_mtu, ifp->if_hwassist, sw_csum);
 >  799             if (error)
 >  800                     goto bad;
 >  801             for (; m; m = m0) {
 >  802                     m0 = m->m_nextpkt;
 
 
 -- 
 Paweł Małachowski



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508291650.j7TGoBUn072052>