diff options
author | Jeff Dike <jdike@addtoit.com> | 2007-02-10 10:44:01 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-11 19:51:21 +0100 |
commit | 84f48d4f2b511db15fda67fd38462b91abd0af53 (patch) | |
tree | 7de15447387c3ace3dfda3b4dabc0b6d3dd1c643 /arch/um/drivers | |
parent | [PATCH] uml: audio driver formatting (diff) | |
download | linux-84f48d4f2b511db15fda67fd38462b91abd0af53.tar.xz linux-84f48d4f2b511db15fda67fd38462b91abd0af53.zip |
[PATCH] uml: mconsole locking
Locking fixes. Locking was totally lacking for the mconsole_devices, which
got a spin lock, and the unplugged pages data, which got a mutex.
The locking of the mconsole console output code was confused. Now, the
console_lock (renamed to client_lock) protects the clients list.
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/drivers')
-rw-r--r-- | arch/um/drivers/mconsole_kern.c | 21 | ||||
-rw-r--r-- | arch/um/drivers/net_kern.c | 1 | ||||
-rw-r--r-- | arch/um/drivers/ssl.c | 1 | ||||
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 1 |
4 files changed, 18 insertions, 6 deletions
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 832d5c766ca8..b4dbd102da0e 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -337,13 +337,15 @@ void mconsole_stop(struct mc_request *req) mconsole_reply(req, "", 0, 0); } -/* This list is populated by __initcall routines. */ - +static DEFINE_SPINLOCK(mc_devices_lock); static LIST_HEAD(mconsole_devices); void mconsole_register_dev(struct mc_device *new) { + spin_lock(&mc_devices_lock); + BUG_ON(!list_empty(&new->list)); list_add(&new->list, &mconsole_devices); + spin_unlock(&mc_devices_lock); } static struct mc_device *mconsole_find_dev(char *name) @@ -367,6 +369,7 @@ struct unplugged_pages { void *pages[UNPLUGGED_PER_PAGE]; }; +static DECLARE_MUTEX(plug_mem_mutex); static unsigned long long unplugged_pages_count = 0; static struct list_head unplugged_pages = LIST_HEAD_INIT(unplugged_pages); static int unplug_index = UNPLUGGED_PER_PAGE; @@ -402,6 +405,7 @@ static int mem_config(char *str, char **error_out) diff /= PAGE_SIZE; + down(&plug_mem_mutex); for(i = 0; i < diff; i++){ struct unplugged_pages *unplugged; void *addr; @@ -447,7 +451,7 @@ static int mem_config(char *str, char **error_out) printk("Failed to release memory - " "errno = %d\n", err); *error_out = "Failed to release memory"; - goto out; + goto out_unlock; } unplugged->pages[unplug_index++] = addr; } @@ -457,6 +461,8 @@ static int mem_config(char *str, char **error_out) } err = 0; +out_unlock: + up(&plug_mem_mutex); out: return err; } @@ -487,6 +493,7 @@ static int mem_remove(int n, char **error_out) } static struct mc_device mem_mc = { + .list = LIST_HEAD_INIT(mem_mc.list), .name = "mem", .config = mem_config, .get_config = mem_get_config, @@ -629,7 +636,7 @@ struct mconsole_output { struct mc_request *req; }; -static DEFINE_SPINLOCK(console_lock); +static DEFINE_SPINLOCK(client_lock); static LIST_HEAD(clients); static char console_buf[MCONSOLE_MAX_DATA]; static int console_index = 0; @@ -684,16 +691,18 @@ static void with_console(struct mc_request *req, void (*proc)(void *), unsigned long flags; entry.req = req; + spin_lock_irqsave(&client_lock, flags); list_add(&entry.list, &clients); - spin_lock_irqsave(&console_lock, flags); + spin_unlock_irqrestore(&client_lock, flags); (*proc)(arg); mconsole_reply_len(req, console_buf, console_index, 0, 0); console_index = 0; - spin_unlock_irqrestore(&console_lock, flags); + spin_lock_irqsave(&client_lock, flags); list_del(&entry.list); + spin_unlock_irqrestore(&client_lock, flags); } #ifdef CONFIG_MAGIC_SYSRQ diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index eede892a4f38..c1838645ae28 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -690,6 +690,7 @@ static int net_remove(int n, char **error_out) } static struct mc_device net_mc = { + .list = LIST_HEAD_INIT(net_mc.list), .name = "eth", .config = net_config, .get_config = NULL, diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index 1e82430b8444..fe400acc9751 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -64,6 +64,7 @@ static struct line_driver driver = { .symlink_from = "serial", .symlink_to = "tts", .mc = { + .list = LIST_HEAD_INIT(driver.mc.list), .name = "ssl", .config = ssl_config, .get_config = ssl_get_config, diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index f4db97efc014..c1d40fb738e6 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -828,6 +828,7 @@ out: * ubd-specific locks. */ static struct mc_device ubd_mc = { + .list = LIST_HEAD_INIT(ubd_mc.list), .name = "ubd", .config = ubd_config, .get_config = ubd_get_config, |