diff options
author | bde <bde@FreeBSD.org> | 2001-12-28 18:08:10 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 2001-12-28 18:08:10 +0000 |
commit | b0e8a2af1f722c2ac2c13de4daeec09b9891e402 (patch) | |
tree | 03b32fd6acbd0f7c12f41bf4e0cfccfc4af66a05 /sys/dev | |
parent | 4b91e746b48e55b71f486cb2aa4f822054148c8f (diff) | |
download | FreeBSD-src-b0e8a2af1f722c2ac2c13de4daeec09b9891e402.zip FreeBSD-src-b0e8a2af1f722c2ac2c13de4daeec09b9891e402.tar.gz |
Fixed locking bugs in rev.1.346:
(1) Don't attempt aquire the non-recursive lock sio_lock recursively.
Doing so caused unbounded recursion in some setups. E.g., if DDB,
BREAK_TO_DEBUGGER and WITNESS are configured; if the debugger is
entered using a break, then WITNESS will actually detect the invalid
recursion and will add to it attempting to print a message about it.
(2) Don't use sio_lock before it has been initialized. The old check
(sio_inited != 0) didn't work when sio_inited was boolean because
sio_inited was set too early, and became just wrong when sio_inited
was changed to a tri-state variable in rev.1.348.
Reported and fixed in another way by: fenner (1)
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/sio/sio.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index 5133064..76eade6 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -3092,6 +3092,7 @@ siocnputc(dev, c) dev_t dev; int c; { + int need_unlock; int s; struct siocnstate sp; Port_t iobase; @@ -3101,13 +3102,16 @@ siocnputc(dev, c) else iobase = siocniobase; s = spltty(); - if (sio_inited) + need_unlock = 0; + if (sio_inited == 2 && !mtx_owned(&sio_lock)) { mtx_lock_spin(&sio_lock); + need_unlock = 1; + } siocnopen(&sp, iobase, comdefaultrate); siocntxwait(iobase); outb(iobase + com_data, c); siocnclose(&sp, iobase); - if (sio_inited) + if (need_unlock) mtx_unlock_spin(&sio_lock); splx(s); } |