Date: Sun, 10 Aug 2003 12:50:44 -0400 From: Don Bowman <don@sandvine.com> To: Don Bowman <don@sandvine.com>, "'freebsd-hackers@freebsd.org'" <freebsd-hackers@freebsd.org> Subject: RE: hang in sio driver when interrupt occurs while in siocnputc() Message-ID: <FE045D4D9F7AED4CBFF1B3B813C8533702742202@mail.sandvine.com>
next in thread | raw e-mail | index | archive | help
> From: Don Bowman > > I find that if the kernel is in the middle of a printf, > is using a serial console, and a key is pressed, that i > may end up stuck in the siointr. I added a counter to > siointr1() so that if it receives more than 100 characters > in a single interrupt it panics. What I find happens is > that the chip (a winbond w83627HF in this case, 16550 compat) > claims to have more characters to read (the fifo is not empty), > but no interrupt is pending. The siointr1() loops forever on > this, reading the com_data register. > > I created a simple kernel module that, on command from a sysctl, > outputs many characters in a callout. When this is going, I hit > enter a few times, and my panic occurs. > > Debugger(c03093aa) at Debugger+0x35 > panic(c0330173,ce098000,3f8,ff807e60,8) at panic+0xb8 > siointr1(ce098000,c0382788,3f8,ff807e44,c02c1e40) at siointr1+0x146 > siointr(ce098000) at siointr+0x17 > Xfastintr4(ff807e60,3f8,1c200,45,0) at Xfastintr4+0x20 > siocnputc(c0362c44,45) at siocnputc+0x4d > cnputc(45,1,63,0,ff807f40) at cnputc+0x4c > putchar(45,ff807f60) at putchar+0x9d > kvprintf(ce3bd75c,c01cb490,ff807f60,a,ff807f7c) at kvprintf+0x38e > printf(ce3bd75c,45,0,ce3bd670,ff807fa8) at printf+0x44 > so_timeout(0,40000000,ffffffff,0,ffffffff) at so_timeout+0x3b > softclock(0,ff800018,c02e0010,ce090010,ffffffff) at softclock+0xfe > doreti_swi(0,ff808000,0,0,f323a000) at doreti_swi+0xf > idle_loop() at idle_loop+0x44 > > siocnputc() just takes spltty(), which doesn't prevent > the interrupt from happening. > > this doesn't seem right, do you think that the siocn* routines > should take COM_LOCK()? > > This is on RELENG_4. The system is SMP. > > Further, it appears the intent of siocnopen() is to disable interrupts on the particular uart, since its overwriting other registers: sp->ier = inb(iobase + com_ier); outb(iobase + com_ier, 0); /* spltty() doesn't stop siointr() */ but i'm nonetheless getting an interrupt. @ the offset I'm at in siocnputc siocnputc+0x48: call siocnopen siocnputc+0x4d: pushl %ebx i'm in the process of calling siocnopen(), so it hasn't got to that interrupt disable code yet. --don
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?FE045D4D9F7AED4CBFF1B3B813C8533702742202>