diff options
author | Jeff Dike <jdike@addtoit.com> | 2007-02-10 04:43:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-11 13:51:21 -0500 |
commit | d79a580936396bbcd2f4fae2c6215f9cf81e3c0d (patch) | |
tree | 72c91c7475e2562c5459c4d6d0499cdd671e0b50 /arch/um/include/line.h | |
parent | 5cf885d01f30be710a339976c485f92bb8a8946d (diff) |
[PATCH] uml: console locking fixes
Clean up the console driver locking. There are various problems here,
including sleeping under a spinlock and spinlock recursion, some of which are
fixed here. This patch deals with the locking involved with opens and closes.
The problem is that an mconsole request to change a console's configuration
can race with an open. Changing a configuration should only be done when a
console isn't opened. Also, an open must be looking at a stable
configuration. In addition, a get configuration request must observe the same
locking since it must also see a stable configuration. With the old locking,
it was possible for this to hang indefinitely in some cases because open would
block for a long time waiting for a connection from the host while holding the
lock needed by the mconsole request.
As explained in the long comment, this is fixed by adding a spinlock for the
use count and configuration and a mutex for the actual open and close.
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um/include/line.h')
-rw-r--r-- | arch/um/include/line.h | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/arch/um/include/line.h b/arch/um/include/line.h index 5f232ae89fbb..b79643eeee08 100644 --- a/arch/um/include/line.h +++ b/arch/um/include/line.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #include "linux/tty.h" | 11 | #include "linux/tty.h" |
12 | #include "linux/interrupt.h" | 12 | #include "linux/interrupt.h" |
13 | #include "linux/spinlock.h" | 13 | #include "linux/spinlock.h" |
14 | #include "linux/mutex.h" | ||
14 | #include "chan_user.h" | 15 | #include "chan_user.h" |
15 | #include "mconsole_kern.h" | 16 | #include "mconsole_kern.h" |
16 | 17 | ||
@@ -32,15 +33,17 @@ struct line_driver { | |||
32 | 33 | ||
33 | struct line { | 34 | struct line { |
34 | struct tty_struct *tty; | 35 | struct tty_struct *tty; |
36 | spinlock_t count_lock; | ||
37 | int valid; | ||
38 | |||
39 | struct mutex open_mutex; | ||
35 | char *init_str; | 40 | char *init_str; |
36 | int init_pri; | 41 | int init_pri; |
37 | struct list_head chan_list; | 42 | struct list_head chan_list; |
38 | int valid; | 43 | |
39 | int count; | ||
40 | int throttled; | ||
41 | /*This lock is actually, mostly, local to*/ | 44 | /*This lock is actually, mostly, local to*/ |
42 | spinlock_t lock; | 45 | spinlock_t lock; |
43 | 46 | int throttled; | |
44 | /* Yes, this is a real circular buffer. | 47 | /* Yes, this is a real circular buffer. |
45 | * XXX: And this should become a struct kfifo! | 48 | * XXX: And this should become a struct kfifo! |
46 | * | 49 | * |
@@ -57,7 +60,8 @@ struct line { | |||
57 | }; | 60 | }; |
58 | 61 | ||
59 | #define LINE_INIT(str, d) \ | 62 | #define LINE_INIT(str, d) \ |
60 | { .init_str = str, \ | 63 | { .count_lock = SPIN_LOCK_UNLOCKED, \ |
64 | .init_str = str, \ | ||
61 | .init_pri = INIT_STATIC, \ | 65 | .init_pri = INIT_STATIC, \ |
62 | .valid = 1, \ | 66 | .valid = 1, \ |
63 | .lock = SPIN_LOCK_UNLOCKED, \ | 67 | .lock = SPIN_LOCK_UNLOCKED, \ |