Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Jan 2004 02:08:41 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        "George V. Neville-Neil" <gnn@jchurch.neville-neil.com>
Cc:        FreeBSD-gnats-submit@freebsd.org
Subject:   Re: kern/61191: System panic on USB vs. Serial problems
Message-ID:  <20040112011638.X27256@gamplex.bde.org>
In-Reply-To: <200401110345.i0B3jeMG000454@jchurch.neville-neil.com>
References:  <200401110345.i0B3jeMG000454@jchurch.neville-neil.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, 10 Jan 2004, George V. Neville-Neil wrote:

> >Description:
> 	I am attempting to use my desktop as a console to my
> -CURRENT target system.  To do this I have hooked COM1 on the desktop to COM1
> on the target system with a nul modem, 9 pin, cable.  While my cu session is
> open on the target I get random crashes of my desktop.  I do not get a
> kernel core dump (alas) but the panic is:
>
> Jan 10 19:17:40 jchurch /kernel: panic: clist reservation botch
> ...
> My desktop has both the serial cable plugged into COM1 as well as a
> USB Keyboard and USB trackpad.  I know this is USB related for two reasons:
>
> 1) Someone else mentioned they were having similar problems.
>
> 2) The machine actually hangs, and only resets when I unplug the USB keyboard.

Apparently usb is still missing some spltty()'s or spltty() doesn't mask
usb interrupts.  spltty() is programmed to masked usb interrupts here
in RELENG_4:

% int
% uhidopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
% {
% 	struct uhid_softc *sc;
% 	usbd_status err;
% #if defined(__FreeBSD__) && defined(__i386__)
% 	static int hid_opened;
%
% 	if (hid_opened == 0) {
% 		int s;
% 		s = splhigh();
% 		tty_imask |= bio_imask;
% 		update_intr_masks();
% 		splx(s);
% 		hid_opened = 1;
% 	}
% #endif

This probably should work, but is not very robust.  It has extra code
to avoid changing the masks twice, but changing the masks more than
once may be needed to pick up new masks as new devices are attached.
I don't know if the obove is called for all systems with usb.

I think making splusb() (= splbio()) mask tty interrupts (using
bio_imask = tty_imask in the above) is not required, but would be safer.
Consider a usb interrupt.  It will not necessarily be masked by
spltty(), but its interrupt handler may call into the tty subsystem.
E.g.:

% void
% uhid_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
% {
% 	struct uhid_softc *sc = addr;
% ...
% 	(void) b_to_q(sc->sc_ibuf, sc->sc_isize, &sc->sc_q);
  	       ^^^^^^^

There are no problems here, since b_to_q() calls spltty() internally
and usb can't interrupt a critical region locked by spltty() (since
spltty() is stronger than splusb()).  However, some other entry points
require their callers to do the spltty().  Try adding SPLASSERT()s to
all of these to find broken callers (*).  The most important such entry
point is ttyinput(), but usb seems to only use it in ucom.c and umodem.c
and it is correctly spl'ed there.

(*) I'm not sure if SPLASSERT() works.  It is still in RELENG_4, but
proved to be so useful that there are almost no references to it in
the cvs repository except in the files that implemented it and in
commit messages.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040112011638.X27256>