Date: Fri, 9 Mar 2001 23:13:36 +0900 (JST) From: kawai@kunugi.rim.or.jp To: FreeBSD-gnats-submit@freebsd.org Subject: kern/25632: USB modem (umodem) may destroy the cfreelist queue Message-ID: <200103091413.f29EDa715736@funyan.kunugi.rim.or.jp>
next in thread | raw e-mail | index | archive | help
>Number: 25632 >Category: kern >Synopsis: USB modem (umodem) may destroy the cfreelist queue >Confidential: no >Severity: critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Mar 09 06:20:01 PST 2001 >Closed-Date: >Last-Modified: >Originator: KAWAI Ken >Release: FreeBSD 4.3-BETA i386 >Organization: >Environment: Use umodem under FreeBSD 4.3-BETA or 5.0-CURRENT. >Description: The cblock_alloc() function is a critical section. The priority level is raised by spltty() before executing cblock_alloc(). The umodemreadcb() function in /usr/src/sys/dev/usb/umodem.c calls cblock_alloc() via ttyinput() and putc(). Because the interrupt priority level of USB is defined as INTR_TYPE_BIO in /usr/src/sys/pci/ohci_pci.c and /usr/src/sys/pci/uhci_pci.c, the interrupt which calls umodemreadcb() isn't blocked when another process is executing cblock_alloc() routine. This may destroy the cfreelist queue. To reconfirm this problem, I put a simple detector into cblock_alloc() and got a core dump. Because I used umodem by KLD module, we can't see the symbol name of umodemreadcb() in the trace. The anonymous function on #13 should be umodemreadcb(). Also, we can't see cblock_alloc() in the trace because cblock_alloc() is a inline function. --- kern/tty_subr.c- Sat Oct 9 15:30:35 1999 +++ kern/tty_subr.c Fri Mar 9 10:48:13 2001 @@ -93,17 +93,23 @@ * Remove a cblock from the cfreelist queue and return a pointer * to it. */ +static int someone_here = 0; + static __inline struct cblock * cblock_alloc() { struct cblock *cblockp; + if (someone_here) + panic("cblock_alloc: Already someone is here\n"); + someone_here = 1; cblockp = cfreelist; if (cblockp == NULL) panic("clist reservation botch"); cfreelist = cblockp->c_next; cblockp->c_next = NULL; cfreecount -= CBSIZE; + someone_here = 0; return (cblockp); } -------- trace #0 dumpsys () at ../../kern/kern_shutdown.c:469 469 if (dumping++) { (kgdb) where #0 dumpsys () at ../../kern/kern_shutdown.c:469 #1 0xc013062d in boot (howto=260) at ../../kern/kern_shutdown.c:309 #2 0xc01309c5 in panic (fmt=0xc01fbd54 "from debugger") at ../../kern/kern_shutdown.c:556 #3 0xc011c9b5 in db_panic (addr=-1071763772, have_addr=0, count=-1, modif=0xc7198aa4 "") at ../../ddb/db_command.c:433 #4 0xc011c954 in db_command (last_cmdp=0xc0224278, cmd_table=0xc02240d8, aux_cmd_tablep=0xc025e160) at ../../ddb/db_command.c:333 #5 0xc011ca1a in db_command_loop () at ../../ddb/db_command.c:455 #6 0xc011eb3f in db_trap (type=3, code=0) at ../../ddb/db_trap.c:71 #7 0xc01e2c6e in kdb_trap (type=3, code=0, regs=0xc7198bc0) at ../../i386/i386/db_interface.c:158 #8 0xc01eec3c in trap (frame={tf_fs = 16, tf_es = 16, tf_ds = 16, tf_edi = 7034930, tf_esi = 256, tf_ebp = -954627064, tf_isp = -954627092, tf_ebx = -1071641856, tf_edx = 0, tf_ecx = 0, tf_eax = 18, tf_trapno = 3, tf_err = 0, tf_eip = -1071763772, tf_cs = 8, tf_eflags = 582, tf_esp = -1071532641, tf_ss = -1071650845}) at ../../i386/i386/trap.c:569 #9 0xc01e2ec4 in Debugger (msg=0xc01fe7e3 "panic") at machine/cpufunc.h:64 #10 0xc01309bc in panic (fmt=0xc0200b00 "cblock_alloc: Already someone is here\n") at ../../kern/kern_shutdown.c:554 #11 0xc014974f in putc (chr=96, clistp=0xc087e900) at ../../kern/tty_subr.c:104 #12 0xc0144c3f in ttyinput (c=96, tp=0xc087e900) at ../../kern/tty.c:563 #13 0xc02cad1e in ?? () #14 0xc01a4cf9 in usb_transfer_complete (xfer=0xc0881580) at ../../dev/usb/usbdi.c:839 #15 0xc01a1e30 in ohci_process_done (sc=0xc0678000, done=97748944) at ../../dev/usb/ohci.c:1207 #16 0xc01a1c4a in ohci_intr1 (sc=0xc0678000) at ../../dev/usb/ohci.c:1065 #17 0xc01a1b41 in ohci_intr (p=0xc0678000) at ../../dev/usb/ohci.c:994 #18 0xc014994a in b_to_q (src=0xc7198d94 "./usr/local/X11R6/share\n\002", amount=23, clistp=0xc0270a38) at ../../kern/tty_subr.c:109 #19 0xc01469a4 in ttwrite (tp=0xc0270a00, uio=0xc7198ed4, flag=8323073) at ../../kern/tty.c:1962 #20 0xc0147517 in ttywrite (dev=0xc02612d8, uio=0xc7198ed4, flag=8323073) at ../../kern/tty.c:2584 #21 0xc0166fb1 in spec_write (ap=0xc7198e8c) at ../../miscfs/specfs/spec_vnops.c:283 #22 0xc01916c4 in ufsspec_write (ap=0xc7198e8c) at ../../ufs/ufs/ufs_vnops.c:1863 #23 0xc0191c6d in ufs_vnoperatespec (ap=0xc7198e8c) at ../../ufs/ufs/ufs_vnops.c:2391 #24 0xc016308f in vn_write (fp=0xc095b3c0, uio=0xc7198ed4, cred=0xc0680600, flags=0, p=0xc69dbd40) at vnode_if.h:363 #25 0xc013e5ed in dofilewrite (p=0xc69dbd40, fp=0xc095b3c0, fd=1, buf=0x8052000, nbyte=24, offset=-1, flags=0) at ../../sys/file.h:163 #26 0xc013e4e2 in write (p=0xc69dbd40, uap=0xc7198f80) at ../../kern/sys_generic.c:328 #27 0xc01ef52a in syscall2 (frame={tf_fs = 47, tf_es = 47, tf_ds = 47, tf_edi = 134553600, tf_esi = 134535856, tf_ebp = -1077937568, tf_isp = -954626092, tf_ebx = 672043880, tf_edx = 134535856, tf_ecx = 134535856, tf_eax = 4, tf_trapno = 0, tf_err = 2, tf_eip = 672003256, tf_cs = 31, tf_eflags = 663, tf_esp = -1077937612, tf_ss = 47}) at ../../i386/i386/trap.c:1150 #28 0xc01e35b5 in Xint0x80_syscall () #29 0x280dd132 in ?? () #30 0x280dd0a1 in ?? () #31 0x280da0d8 in ?? () #32 0x28085710 in ?? () #33 0x804aabc in ?? () #34 0x8049424 in ?? () #35 0x804b594 in ?? () #36 0x80491ab in ?? () (kgdb) quit >How-To-Repeat: For example, use umodem and sio at the same time. >Fix: >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200103091413.f29EDa715736>