Re: patch to drivers/char/serial.c to fix kernel lock-up

Truxton Fulton (trux@truxton.com)
Fri, 4 Dec 1998 14:39:40 -0800 (PST)


Hi Ted,

I know that the IRQ chain had a cycle, and that this was caused by
startup being called a second time during initialization (from
set_serial_info), because I made extensive use of printk to debug
the problem. Why this happens, I dont know. It may be the old
version of kermit I am using, it may be that I have shared serial
IRQs enabled (although for this particular port, ttyS1, it has IRQ
3 all to itself). It may be that I am running on a single CPU machine,
but compiled my kernel with SMP=1. I do know that this problem occured
with linux-2.1.130-pre3, but not with linux-2.1.115. Also, that the
problem only occurs when I run kermit as non-root (this may be
kermit's doing). The bug does happen after booting directly to
single user mode (no programs are running, nor are any other
serial ports open).

I used the strace output from kermit to create a test program to
demonstrate the bug. This could probably be trimmed down a little
and still demonstrate the bug. I verified that this program
completely hoses three different linux boxes. Try running this
as non-root:

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/ioctl.h>

main()
{
int h1, h2 ;
char argp[1024] ;
char argp2[1024] ;

h1=open("/dev/ttyS1", O_RDWR|O_NONBLOCK) ;
ioctl(h1, TCGETS, argp) ;
ioctl(h1, TCGETS, argp) ;
ioctl(h1, TCGETS, argp) ;
fcntl(h1, F_GETFL) ;
fcntl(h1, F_GETFL) ;
fcntl(h1, F_SETFL, O_RDWR) ;

h2=open("/dev/ttyS1", O_RDWR) ;
close(h2) ;

ioctl(h1, TCSETSW, argp) ;
ioctl(h1, TCGETS, argp) ;
ioctl(h1, TIOCGSERIAL, argp) ;
ioctl(h1, TCGETS, argp) ;
ioctl(h1, TIOCGSERIAL, argp) ;
ioctl(h1, TCGETS, argp2) ;
ioctl(h1, TIOCGSERIAL, argp) ;
ioctl(h1, TIOCSSERIAL, argp) ;
ioctl(h1, TCSETSW, argp2) ;

ioctl(h1, TCGETS, argp2) ;
ioctl(h1, TIOCGSERIAL, argp) ;

close(h1) ;
}

On Fri, 4 Dec 1998, Theodore Y. Ts'o wrote:

> Date: Fri, 4 Dec 1998 01:25:09 -0800 (PST)
> From: Truxton Fulton <trux@truxton.com>

> Please take this patch to drivers/char/serial.c. It fixes a problem I was
> having where the kernel would lock up solidly (infinite loop in serial.c).
> The problem is that startup() was being called multiple times, creating
> a cycle in the IRQ chain. This was happening under vanilla 2.1.130 after
> booting directly to single user mode. The lock-up would occur when I ran
> 'kermit -l /dev/ttyS1 -b 38400 -c' as any other user than root. For root,
> startup() would only be called once.

> Umm... can you give me more information about exactly how to reproduce
> this? I've tried, and I can't reproduce it. Note that startup() checks
> the flag ASYNC_INITIALIZED, and will exit if the port is already
> initialized. Therefore, running startup() multiple times doesn't cause
> a problem. It's also the case that a single open will not call
> startup() multiple times, so I'm very curious how you can to the
> conclusion that was actually what was going on.

> Given that no one else has reported anything vaguely like this, and the
> serial driver hasn't change significantly recently, I must conclude that
> you must be doing something different, or your system must be different
> in some way from most other people's.

> Are you using a SMP machine? Were any other serial ports open when you
> ran kermit? How are your irq's and ports configured? Etc.

> Before I apply your patch, I want to understand why it's necessary,
> because as near as I can tell, it shouldn't be needed at all.

> - Ted

-
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/