Hi, I'm using kernel 2.6.30, I have a USB serial modem program with ftdi_sio driver. A kernel bug occurred when this modem process tried to open /dev/ttyUSB0 without sleep until it made it. Here is the bug info: [35096.074482] ------------[ cut here ]------------ [35096.079319] kernel BUG at drivers/char/tty_ldisc.c:198! [35096.084788] invalid opcode: 0000 [#2] SMP [35096.089104] last sysfs file: [35096.092224] Modules linked in: iptable_filter xt_multiport ipt_MASQUERADE xt_mark ads_alarm sinfor_dog ppp_async crc_ccitt ppp_synctty pppoe pppox ppp_generic slhc xt_ipgrp xt_zone nf_nat_sqlnet nf_conntrack_sqlnet nf_nat_rtsp nf_conntrack_rtsp dns nf_nat_pptp nf_conntrack_pptp nf_conntrack_proto_gre nf_nat_proto_gre nf_nat_h323 nf_conntrack_h323 nf_nat_sip nf_conntrack_sip nf_nat_tftp nf_conntrack_tftp nf_nat_ftp nf_conntrack_ftp tun mselector ipfilter small_nat kv_http_filter kv_ftp_filter kv_core_filter login_defense waf httpinspect snort_module sf_pcre ips_center waf_url_lib ips_pcap netsafedrv ha_drv ssl url arpguard webattest_drv dosck_drv wdos fw flux_log tc path_deliver proute skype behavior contchk exclude dnscache protocol_drv proxyconv netpolicy droplist_drv webredirect fwlog ipctcall if_zone af_debug iptable_nat ip_tables 8021q switch nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack watchreboot ixgbe igb dca e1000e e1000 [35096.180453] [35096.182076] Pid: 3687, comm: smssp Tainted: G D (2.6.30-gentoo-r8 #45) HM6000A [35096.190421] EIP: 0060:[<40369b9c>] EFLAGS: 00010046 CPU: 4 [35096.196182] EIP is at tty_ldisc_put+0x28/0x46 [35096.200745] EAX: 00000000 EBX: 00000000 ECX: 00000297 EDX: 4072c3e0 [35096.207348] ESI: 00000297 EDI: 00000000 EBP: 00000000 ESP: c5837dcc [35096.213865] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 [35096.219605] Process smssp (pid: 3687, ti=c5836000 task=da4e1490 task.ti=c5836000) [35096.227506] Stack: [35096.229693] c38f5000 00000000 40369e8a ffffffff c38f5000 00000000 bf43eb40 4036439c [35096.237761] 4036442c c38f5000 c38f5000 00000000 00000000 40365cc0 bf43eb40 00000000 [35096.246133] 00000001 00000000 00000000 daa52e84 4021e5c1 00000000 00000000 00000003 [35096.254774] Call Trace: [35096.259109] [<40369e8a>] ? tty_ldisc_release+0xba/0x143 [35096.264673] [<4036439c>] ? tty_fasync+0x3e/0xd5 [35096.269577] [<4036442c>] ? tty_fasync+0xce/0xd5 [35096.274465] [<40365cc0>] ? tty_release_dev+0x36f/0x392 [35096.279918] [<4021e5c1>] ? __wake_up+0x29/0x39 [35096.284694] [<404825c4>] ? usb_serial_get_by_index+0x2a/0x2e [35096.290742] [<4048271f>] ? serial_open+0x34/0x189 [35096.295794] [<40365e66>] ? tty_init_dev+0xd3/0x116 [35096.300952] [<4036615c>] ? tty_open+0x2b3/0x3a9 [35096.305850] [<40293df8>] ? chrdev_open+0x128/0x152 [35096.310980] [<402a2260>] ? mntput_no_expire+0x12/0xe0 [35096.316414] [<40293cd0>] ? chrdev_open+0x0/0x152 [35096.321493] [<4028feb1>] ? __dentry_open+0x113/0x1e9 [35096.326867] [<40290ce7>] ? nameidata_to_filp+0x29/0x3c [35096.332422] [<4029a398>] ? do_filp_open+0x3ab/0x689 [35096.337673] [<40236d66>] ? autoremove_wake_function+0x0/0x2d [35096.343844] [<4028b207>] ? virt_to_head_page+0x13/0x2e [35096.349434] [<402a0ed3>] ? alloc_fd+0x5e/0xd0 [35096.354167] [<4028fcbe>] ? do_sys_open+0x44/0xb4 [35096.359178] [<4028fd72>] ? sys_open+0x1e/0x23 [35096.364021] [<40202964>] ? sysenter_do_call+0x12/0x22 [35096.369431] Code: 5b 5e c3 56 53 8b 58 08 83 fb 12 76 04 0f 0b eb fe b8 20 79 87 40 e8 9e 0e 22 00 8b 14 9d 40 79 87 40 89 c6 8b 42 48 85 c0 75 04 <0f> 0b eb fe 48 89 42 48 8b 42 44 e8 5d ab ed ff 89 f2 b8 20 79 [35096.390672] EIP: [<40369b9c>] tty_ldisc_put+0x28/0x46 SS:ESP 0068:c5837dcc [35096.398378] ---[ end trace 8fa05b047da26885 ]--- source code arround drivers/char/tty_ldisc.c:198 is: static void tty_ldisc_put(struct tty_ldisc_ops *ld) { unsigned long flags; int disc = ld->num; BUG_ON(disc < N_TTY || disc >= NR_LDISCS); spin_lock_irqsave(&tty_ldisc_lock, flags); ld = tty_ldiscs[disc]; BUG_ON(ld->refcount == 0); /*line 198*/ ld->refcount--; module_put(ld->owner); spin_unlock_irqrestore(&tty_ldisc_lock, flags); } It can be triggered after ten or more hours since booting up, and my program runs as system runs. I've attached my program, and I've also run into three other similar situations triggered by tcpdump and sshd. BTW, i guess this issue may has been reported already, so how can i find out a specific patch? Regards, Ken
/* * ===================================================================================== * * Filename: usb.c * * Description: * * Version: 1.0 * Created: 03/06/2012 04:59:04 PM * Revision: none * Compiler: gcc * * Author: YOUR NAME (), * Organization: * * compile: * gcc -g usb.c -o usb_sleep.exe -DSLEEP -D_GNU_SOURCE * gcc -g usb.c -o usb.exe -D_GNU_SOURCE * * ===================================================================================== */ #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <unistd.h> #include <errno.h> int main() { char *dev = "/dev/ttyUSB0"; //O_RDONLY | O_LARGEFILE is used by 'cat' while open file //int fd = open(dev, O_RDONLY|O_LARGEFILE/* O_RDWR | O_NOCTTY | O_NONBLOCK */); //int fd = open(dev, O_RDWR | O_NOCTTY | O_NONBLOCK); int fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY); while(fd < 0) { fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY); #ifdef SLEEP sleep(1); #endif } printf("open tty ok!\n"); char buf[1024]; printf(buf, "at"); int ret = write(fd, buf, strlen(buf)); if(ret < 0){ printf("write error:%s\n", strerror(errno)); } ret = read(fd, buf, sizeof(buf) - 1); if(ret < 0){ printf("read error:%s\n", strerror(errno)); } close(fd); }