kern/85258: changing promisc mode on nic can lead to kernel
panic
Pawel Malachowski
pawmal-posting at freebsd.lublin.pl
Mon Aug 29 16:47:14 GMT 2005
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
More information about the freebsd-bugs
mailing list