Re: [PATCH] for SMP problems in n_tty.c, serial.c

From: Alan Modra (alan@linuxcare.com.au)
Date: Mon Mar 20 2000 - 08:50:15 EST


Hi Ted, Andrew,
   Here's the version with SMP spinlock serial.c

Things to check in serial.c:
a) Whether I've caught all deadlocks. save_flags, cli sequence is OK to
   do muliple times; spin_lock_irqsave isn't.
b) Whether it's safe to unlock earlier in startup and register_serial to
   avoid (a)
c) Whether I've FUBAR'd scr_info use.
d) Whether there is sufficient protection for global vars.

Tested on UP with DEBUG_SPINLOCK, but I don't have a SMP machine handy to
properly test this patch.

Regards, Alan Modra

-- 
Linuxcare. Support for the Revolution.

For the benefit of the list: what this patch does is fix a number of bugs which will be hit (probably only very occasionally) by users who have SMP machines. In addition, I've removed the global cli()'s in serial.c, which are relatively slow on SMP machines, and replaced them with spinlocks. That's the part of this patch that especially needs testing and scrutiny. Find a bug, and tell me how silly I am.

ChangeLog * include/linux/circ_buf.h: New file.

* include/linux/tty.h: Include linux/circ_buf.h (struct tty_struct): Delete read_buf, read_head, read_tail, read_cnt. Add read, head_lock, tail_lock. Change type of canon_head to int.

* include/linux.serialP.h: Include linux/circ_buf.h (struct async_struct): Delete xmit_buf, xmit_head, xmit_tail, xmit_cnt. Add xmit, xmit_lock.

* drivers/char/n_tty.c: Throughout file, remove references to read_cnt, and replace with CIRC_CNT, CIRC_SPACE, CIRC_CNT_TO_END, or CIRC_SPACE_TO_END as appropriate. Change read_buf, read_head, read_tail to read.buf, read.head, read.tail to suit new circ_buf struct. Use two spinlocks, one for read.head, one for read.tail so both readers and writers can access the buffer simultaneously. Don't use MIN as it references its args twice. (n_tty_chars_in_buffer): Simplify. Remove unnecessary spinlock. (n_tty_receive_room): Full buffer is now N_TTY_BUF_SIZE - 1. Don't return one less than actual available. (n_tty_receive_buf): Localise variables to blocks. (copy_from_read_buf): Remove unnecessary spinlock when finding count in buffer. Protect against multiple SMP readers. (read_chan): Protect against multiple SMP readers while searching for eol.

* drivers/char/tty_ioctl.c: Throughout file, remove references to read_cnt, and replace with CIRC_CNT, CIRC_SPACE, CIRC_CNT_TO_END, or CIRC_SPACE_TO_END as appropriate. Change read_buf, read_head, read_tail to read.buf, read.head, read.tail to suit new circ_buf struct.

* drivers/char/tty_io.c (tty_fasync): Set minimun_to_wake to new full buffer size, N_TTY_BUF_SIZE - 1.

* drivers/char/pty.c (MIN): Delete. (pty_write): Replace usage of MIN, as it evaluates its arguments twice, and may call ldisc.receive_room twice. Localise variables to blocks.

*drivers/char/selection.c (MIN): Delete. (paste_selection): Replace usage of MIN.

*drivers/char/serial.c: Throughout file, remove references to xmit_cnt, and replace with CIRC_CNT, CIRC_SPACE, CIRC_CNT_TO_END, or CIRC_SPACE_TO_END as appropriate. Change xmit_buf, xmit_head, xmit_tail to xmit.buf, xmit.head, xmit.tail to suit new circ_buf struct. Replace save_flags, cli, .., restore_flags with spinlock equivalent. Don't use MIN as it references its args twice. (rs_interrupt): Hold xmit_lock spinlock for duration. (rs_interrupt_single): Same here, (rs_interrupt_multi): And here. (rs_timer): Use local save_flags, cli here instead of global. (shutdown): Clear info->xmit.buf before we free page. (rs_put_char): Don't xmit.head++, as it leaves xmit.head with an illegal value for a short time. (rs_write_room): Don't return one less than actual available. (line_info): Only use info->MCR when info != &scr_info. Use static scr_info. (detect_uart_irq): Use static scr_info. (autoconfig): Here too. (rs_init): Init scr_info. (cleanup_module): Clear tmp_buf before freeing page.


- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Mar 23 2000 - 21:00:29 EST