Hi all, I just have rewritten the driver to do a constant polling. This imply that the module work in interrupt context. The driver works for a while but after some time ( 1 to 120 seconds it depends ), the driver produce a Oops. But the oops dont give any error on the driver function but show a page allocation problem in other part of the kernel Here the oops is in usbserial but yesterday before activation kernel debug, it was in the raid_one module !
Here the code , I tried different spin_lock_irq but without any changes. If I comment the bulk_write and just do a read polling, The polling is stable ( but this is normal, because the module will never see any character coming from the device because the device never receive any data ). Here is the code that cause the problem: ( It is just a part of the code. This is enough to see all things related to my problem - All spin_lock are removed for the moment.. I know it is quite dangerous but the module call all callback function in a kind of chain order. The oops follow the code ) Some explanations: The code ( not shown here ) iuu_open do a rxcmd with a completion pointer equal to iuu_uart_read_callback. So the polling begin in this function. In the same time, iuu_uart_write is called in a process context to just fill writebuf. So we have: 1.From tty: character -> iuu_uart_write -> writebuf 2.Polling: iuu_uart_read_callback -> if character in device buffer -> read_buf -> rxcmd if no character in buf and reset is waiting -> iuu_reset -> rxcmd if no character in device and no reset is waiting -> rxcmd rxcmd point at completion to iuu_uart_read_callback.... some question: 1.Is it right to allocate the memory like I do in the code ? ( iuu_alloc_buf ) 2.What I really must care in interrupt context ? I try to always avois any function that is able to sleep but if you see one .. say me. 3.Sometimes, I have Fatal exception in interrupt... --------------------------Code------------------------------ /* non interrupt context functions */ static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count); static int iuu_uart_baud(struct usb_serial_port *port, u_int32_t baud, u_int32_t *actual, u_int8_t parity); static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count); static int iuu_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg); static int iuu_tiocmset(struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); static int iuu_tiocmget(struct usb_serial_port *port, struct file *file); static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf, int count); static int iuu_uart_on(struct usb_serial_port *port); static int iuu_uart_off(struct usb_serial_port *port); /* polled functions (interrupt context) */ static void iuu_uart_read_callback (struct urb *urb); static int iuu_read_buf(struct usb_serial_port *port ,u8 len); static void read_buf_callback (struct urb *urb); static int iuu_bulk_write(struct usb_serial_port *port); static void iuu_rxcmd (struct urb *urb); static void read_rxcmd_callback (struct urb *urb); static int iuu_status(struct usb_serial_port *port); static void iuu_status_callback(struct urb *urb); static void iuu_update_status_callback(struct urb *urb); static int iuu_reset(struct usb_serial_port *port, u_int8_t wt); /* structures definitions */ static struct usb_serial_driver iuu_device = { .driver = { .owner = THIS_MODULE, .name = "IUU Phoenix", }, .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 1, .num_bulk_out = 1, .num_ports = 1, .open = iuu_open, .close = iuu_close, .write = iuu_uart_write, .read_bulk_callback = iuu_uart_read_callback, .ioctl = iuu_ioctl, .tiocmget = iuu_tiocmget, .tiocmset = iuu_tiocmset, .attach = iuu_startup, .shutdown = iuu_shutdown, }; struct iuu_private { spinlock_t lock; /* store irq state */ wait_queue_head_t delta_msr_wait; u8 line_control; u8 line_status; u8 termios_initialized; int TIOSTATUS; /* store IUART SIGNAL for tiocmget call */ u8 reset; /* if 1 reset is needed */ int poll; /* number of poll */ u8 *writebuf; /* buffer for writing to device */ int writelen; /* num of byte to write to device */ u8 *buf; /* used for initialize speed */ u8 *dbgbuf; /* debug buffer */ u8 len; }; static int iuu_alloc_buf (struct usb_serial_port *port) { struct iuu_private *priv = usb_get_serial_port_data(port); priv->buf = kmalloc(256,GFP_KERNEL); priv->dbgbuf = kmalloc(256,GFP_KERNEL); priv->writebuf = kmalloc(256,GFP_KERNEL); if ( !priv->buf || !priv->dbgbuf || !priv->writebuf ) return 1 ; return 0; } static int iuu_free_buf (struct usb_serial_port *port) { struct iuu_private *priv = usb_get_serial_port_data(port); kfree(priv->buf); kfree(priv->dbgbuf); kfree(priv->writebuf); return 0; } static int iuu_startup(struct usb_serial *serial) { struct iuu_private *priv; priv = kmalloc(sizeof(struct iuu_private), GFP_KERNEL); if (!priv) return -ENOMEM; memset(priv, 0x00, sizeof(struct iuu_private)); spin_lock_init(&priv->lock); init_waitqueue_head(&priv->delta_msr_wait); usb_set_serial_port_data(serial->port[0], priv); if ( iuu_alloc_buf(serial->port[0]) ) dbg ("%s - error on kmalloc buffers",__FUNCTION__); return 0; } static void iuu_uart_read_callback ( struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *) urb->context; struct iuu_private *priv = usb_get_serial_port_data(port); int status; int error = 0 ; u8 *len ; //priv->poll++ ; dbg("%s - enter", __FUNCTION__ ); if (urb->status) { dbg("%s - urb->status = %d", __FUNCTION__, urb->status); /* error stop all */ return ; } len = urb->transfer_buffer; if ( urb->actual_length > 1) { dbg("%s - urb->actual_length = %i",__FUNCTION__,urb->actual_length); error = 1 ; } // if len > 0 call readbuf if (len[0] > 0 && error == 0) { dbg("%s - call read buf", __FUNCTION__ ); status = iuu_read_buf (port,len[0]); return ; } /* need to update status ? */ if ( priv->poll > 999 ) { //status = iuu_status(port); //if (!status) // priv->poll = 0 ; //return ; } /* reset waiting ? */ if ( priv->reset == 1 ) { status = iuu_reset(port,0xC); return ; } /* Writebuf is waiting */ if ( priv->writelen > 0 ) { status = iuu_bulk_write (port); return ; } // if nothing to write call again rxcmd dbg("%s - rxcmd recall", __FUNCTION__ ); iuu_rxcmd( urb ); return ; } static int iuu_read_buf ( struct usb_serial_port *port , u8 len ){ int result; dbg("%s - enter", __FUNCTION__ ); usb_fill_bulk_urb (port->read_urb, port->serial->dev, usb_rcvbulkpipe (port->serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, len, read_buf_callback, port); result = usb_submit_urb(port->read_urb, GFP_ATOMIC); return result ; } static void read_buf_callback ( struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *) urb->context; unsigned char *data = urb->transfer_buffer; int i; struct tty_struct *tty; dbg("%s - urb->status = %d", __FUNCTION__, urb->status); if (urb->status) { dbg("%s - urb->status = %d", __FUNCTION__, urb->status); if (urb->status == -EPROTO) { /* reschedule needed */ } return ; } dbg("%s - %i chars to write", __FUNCTION__, urb->actual_length); tty = port->tty; if (tty && urb->actual_length) { tty_buffer_request_room(tty, urb->actual_length+1); for (i = 0; i < urb->actual_length; ++i) tty_insert_flip_char(tty, data[i], TTY_NORMAL); tty_flip_buffer_push(tty); } iuu_rxcmd ( urb ); } static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf, int count) { struct iuu_private *priv = usb_get_serial_port_data(port); unsigned int flags; dbg("%s - enter", __FUNCTION__ ); /* buffer already filled but not commited */ if ( priv->writelen > 0 ) return (0); /* fill the buffer */ spin_lock_irqsave(&priv->lock, flags); memcpy(priv->writebuf,buf,count); priv->writelen = count ; spin_unlock_irqrestore(&priv->lock, flags); return (count); } static int iuu_bulk_write(struct usb_serial_port *port) { struct iuu_private *priv = usb_get_serial_port_data(port); unsigned long flags; int result ; dbg("%s - enter", __FUNCTION__ ); memset(port->write_urb->transfer_buffer,IUU_UART_ESC,1); memset(port->write_urb->transfer_buffer+1,IUU_UART_TX,1); memset(port->write_urb->transfer_buffer+2,priv->writelen,1); memcpy (port->write_urb->transfer_buffer+3,priv->writebuf, priv->writelen); usb_fill_bulk_urb (port->write_urb, port->serial->dev, usb_sndbulkpipe (port->serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer,priv->writelen+3, iuu_rxcmd, port); result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) return 0; priv->writelen = 0 ; return result ; } static void iuu_rxcmd( struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *) urb->context; int result ; dbg("%s - enter", __FUNCTION__ ); memset(port->write_urb->transfer_buffer,IUU_UART_RX,1); usb_fill_bulk_urb (port->write_urb, port->serial->dev, usb_sndbulkpipe (port->serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, 1, read_rxcmd_callback, port); result = usb_submit_urb(port->write_urb, GFP_ATOMIC); } static void read_rxcmd_callback ( struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *) urb->context; int result ; dbg("%s - enter", __FUNCTION__ ); dbg("%s - urb->status = %d", __FUNCTION__, urb->status); usb_fill_bulk_urb (port->read_urb, port->serial->dev, usb_rcvbulkpipe (port->serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, 256, iuu_uart_read_callback, port); result = usb_submit_urb(port->read_urb, GFP_ATOMIC); dbg("%s - submit result = %d", __FUNCTION__, result); return ; } static int iuu_reset(struct usb_serial_port *port,u8 wt) { struct iuu_private *priv = usb_get_serial_port_data(port); int result ; dbg("%s - enter", __FUNCTION__ ); /* Prepare the reset sequence */ memset(port->write_urb->transfer_buffer,IUU_RST_SET,1); memset(port->write_urb->transfer_buffer+1,IUU_DELAY_MS,1); memset(port->write_urb->transfer_buffer+2,wt,1); memset(port->write_urb->transfer_buffer+3,IUU_RST_CLEAR,1); /* send the sequence */ usb_fill_bulk_urb (port->write_urb, port->serial->dev, usb_sndbulkpipe (port->serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, 4, iuu_rxcmd, port); result = usb_submit_urb(port->write_urb, GFP_ATOMIC); priv->reset = 0; return result ; } static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf, int count) { struct iuu_private *priv = usb_get_serial_port_data(port); unsigned int flags; dbg("%s - enter", __FUNCTION__ ); /* buffer already filled but not commited */ if ( priv->writelen > 0 ) return (0); /* fill the buffer */ spin_lock_irqsave(&priv->lock, flags); memcpy(priv->writebuf,buf,count); priv->writelen = count ; spin_unlock_irqrestore(&priv->lock, flags); return (count); } ------------------End of Code--------------------------- The Oops: Jul 26 07:05:25 teo kernel: [ 330.075383] iuutool-0.0.5/kern_module/iuu_phoenix-0.2/V2.6/iuu_phoenix.c: read_buf_callback - urb->status = 0 Jul 26 07:05:25 teo kernel: [ 330.075387] iuutool-0.0.5/kern_module/iuu_phoenix-0.2/V2.6/iuu_phoenix.c: read_buf_callback - 1 chars to write Jul 26 07:05:25 teo kernel: [ 330.075396] iuutool-0.0.5/kern_module/iuu_phoenix-0.2/V2.6/iuu_phoenix.c: iuu_rxcmd - enter Jul 26 07:05:25 teo kernel: [ 330.075433] iuutool-0.0.5/kern_module/iuu_phoenix-0.2/V2.6/iuu_phoenix.c: iuu_uart_write - enter Jul 26 07:05:25 teo kernel: [ 330.076332] iuutool-0.0.5/kern_module/iuu_phoenix-0.2/V2.6/iuu_phoenix.c: read_rxcmd_callback - enter Jul 26 07:05:25 teo kernel: [ 330.076336] iuutool-0.0.5/kern_module/iuu_phoenix-0.2/V2.6/iuu_phoenix.c: read_rxcmd_callback - urb->status = 0 Jul 26 07:05:25 teo kernel: [ 330.076345] iuutool-0.0.5/kern_module/iuu_phoenix-0.2/V2.6/iuu_phoenix.c: read_rxcmd_callback - submit result = 0 Jul 26 07:05:25 teo kernel: [ 330.077331] iuutool-0.0.5/kern_module/iuu_phoenix-0.2/V2.6/iuu_phoenix.c: iuu_uart_read_callback - enter Jul 26 07:05:25 teo kernel: [ 330.077335] iuutool-0.0.5/kern_module/iuu_phoenix-0.2/V2.6/iuu_phoenix.c: iuu_bulk_write - enter Jul 26 07:05:36 teo kernel: [ 339.977148] BUG: unable to handle kernel paging request at virtual address 6d41acec Jul 26 07:05:36 teo kernel: [ 339.997006] printing eip: Jul 26 07:05:36 teo kernel: [ 340.016554] defd7473 Jul 26 07:05:36 teo kernel: [ 340.035729] *pde = 00000000 Jul 26 07:05:36 teo kernel: [ 340.054642] Oops: 0000 [#1] Jul 26 07:05:36 teo kernel: [ 340.073199] SMP DEBUG_PAGEALLOC Jul 26 07:05:36 teo kernel: [ 340.091718] Modules linked in: iuu_phoenix ppdev lp yenta_socket rsrc_nonstatic pcmcia_core bridge ipv6 dm_snapshot dm_mirr or dm_mod 8139too tsdev psmouse rtc parport_pc parport floppy serio_raw pcspkr i2c_i801 usbserial i2c_core usblp shpchp pci_hotplug intel_agp agpgart st e vdev ext3 jbd mbcache raid1 md_mod ide_generic ide_cd cdrom ide_disk piix b44 mii generic aic7xxx scsi_transport_spi uhci_hcd thermal processor fan ehci_h cd usb_storage ide_core sd_mod scsi_mod usbcore Jul 26 07:05:36 teo kernel: [ 340.179144] CPU: 0 Jul 26 07:05:36 teo kernel: [ 340.179145] EIP: 0060:[<defd7473>] Not tainted VLI Jul 26 07:05:36 teo kernel: [ 340.179147] EFLAGS: 00010202 (2.6.21 #2) Jul 26 07:05:36 teo kernel: [ 340.248489] EIP is at serial_chars_in_buffer+0x72/0x84 [usbserial] Jul 26 07:05:36 teo kernel: [ 340.272047] eax: c9d11bf8 ebx: c9d11bf8 ecx: 00000000 edx: 6d41ab68 Jul 26 07:05:36 teo kernel: [ 340.296129] esi: 00000000 edi: ca55ff3c ebp: c90c2804 esp: c9021be8 Jul 26 07:05:36 teo kernel: [ 340.320615] ds: 007b es: 007b fs: 00d8 gs: 0033 ss: 0068 Jul 26 07:05:36 teo kernel: [ 340.345592] Process mpcs-0.8k-rc16- (pid: 3607, ti=c9020000 task=c8e2b5b0 task.ti=c9020000) Jul 26 07:05:36 teo kernel: [ 340.346616] Stack: c90c27f8 c0211064 00000001 00000000 c90c27f8 c0214fec 00128ab7 c90c27f8 Jul 26 07:05:36 teo kernel: [ 340.372944] c0214ef2 ca55ff3c c0211129 00000000 00000000 00000000 c9021e9c ca55ff3c Jul 26 07:05:36 teo kernel: [ 340.400052] c9021e94 c0171950 c9021fac bfd4bc40 bfd4bc48 00000000 c9021e94 c9021e94 Jul 26 07:05:36 teo kernel: [ 340.427769] Call Trace: Jul 26 07:05:36 teo kernel: [ 340.482820] [<c0211064>] tty_ldisc_ref_wait+0xc/0x86 Jul 26 07:05:36 teo kernel: [ 340.511235] [<c0214fec>] normal_poll+0xfa/0x11f Jul 26 07:05:36 teo kernel: [ 340.539506] [<c0214ef2>] normal_poll+0x0/0x11f Jul 26 07:05:36 teo kernel: [ 340.567713] [<c0211129>] tty_poll+0x4b/0x63 Jul 26 07:05:36 teo kernel: [ 340.596168] [<c0171950>] do_sys_poll+0x19a/0x327 Jul 26 07:05:36 teo kernel: [ 340.624807] [<c017244d>] __pollwait+0x0/0xac Jul 26 07:05:36 teo kernel: [ 340.653485] [<c011c41d>] default_wake_function+0x0/0xc Jul 26 07:05:36 teo kernel: [ 340.682239] [<c011c41d>] default_wake_function+0x0/0xc Jul 26 07:05:36 teo kernel: [ 340.710473] [<c022b2a2>] dma_pool_alloc+0x1c0/0x1ca Jul 26 07:05:36 teo kernel: [ 340.738530] [<c013aa22>] __lock_acquire+0xb30/0xbc4 Jul 26 07:05:36 teo kernel: [ 340.766608] [<c013aa22>] __lock_acquire+0xb30/0xbc4 Jul 26 07:05:36 teo kernel: [ 340.794355] [<c01630a1>] cache_flusharray+0x3f/0xea Jul 26 07:05:36 teo kernel: [ 340.822029] [<c013aa22>] __lock_acquire+0xb30/0xbc4 Jul 26 07:05:36 teo kernel: [ 340.849340] [<c01291c6>] lock_timer_base+0x15/0x2f Jul 26 07:05:36 teo kernel: [ 340.876811] [<c0119188>] change_page_attr+0x1c/0x291 Jul 26 07:05:36 teo kernel: [ 340.904011] [<c013aa22>] __lock_acquire+0xb30/0xbc4 Jul 26 07:05:36 teo kernel: [ 340.930929] [<deea2f62>] ide_execute_command+0x2e/0xa5 [ide_core] Jul 26 07:05:36 teo kernel: [ 340.957918] [<c01292dd>] __mod_timer+0x9f/0xa9 Jul 26 07:05:36 teo kernel: [ 340.984584] [<c02a674c>] _spin_lock_irqsave+0x39/0x41 Jul 26 07:05:36 teo kernel: [ 341.011073] [<c01cc56b>] vsnprintf+0x450/0x48c Jul 26 07:05:36 teo kernel: [ 341.037479] [<c0121289>] release_console_sem+0x1a0/0x1b9 Jul 26 07:05:36 teo kernel: [ 341.063968] [<c013aa22>] __lock_acquire+0xb30/0xbc4 Jul 26 07:05:36 teo kernel: [ 341.090184] [<defcc78e>] iuu_uart_write+0x47/0x70 [iuu_phoenix] Jul 26 07:05:36 teo kernel: [ 341.116369] [<c013aa22>] __lock_acquire+0xb30/0xbc4 Jul 26 07:05:36 teo kernel: [ 341.142298] [<c0191593>] dnotify_parent+0x1a/0x5d Jul 26 07:05:36 teo kernel: [ 341.168041] [<c0210299>] tty_ldisc_deref+0x55/0x64 Jul 26 07:05:36 teo kernel: [ 341.193291] [<c016756e>] vfs_write+0xef/0x12a Jul 26 07:05:36 teo kernel: [ 341.218136] [<c0103d20>] sysenter_past_esp+0x8d/0x99 Jul 26 07:05:36 teo kernel: [ 341.243218] [<c0139ad5>] trace_hardirqs_on+0x126/0x150 Jul 26 07:05:37 teo kernel: [ 341.268493] [<c0171b11>] sys_poll+0x34/0x37 Jul 26 07:05:37 teo kernel: [ 341.293883] [<c0103cf0>] sysenter_past_esp+0x5d/0x99 Jul 26 07:05:37 teo kernel: [ 341.319471] ======================= Jul 26 07:05:37 teo kernel: [ 341.344183] Code: ee fd de 00 74 2d c7 44 24 08 cc 9d fd de c7 44 24 04 6d a0 fd de c7 04 24 a2 a0 fd de e8 8e a4 14 e1 eb 0f 8b 03 8b 50 04 89 d8 <ff> 92 84 01 00 00 eb 05 b8 ed ff ff ff 83 c4 10 5b c3 53 83 ec Jul 26 07:05:37 teo kernel: [ 341.395493] EIP: [<defd7473>] serial_chars_in_buffer+0x72/0x84 [usbserial] SS:ESP 0068:c9021be8 I suspect iuu_bulk_write of course But where exactly ??? Thanks, Alain ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel