diff options
Diffstat (limited to 'arch/um/drivers/harddog_kern.c')
-rw-r--r-- | arch/um/drivers/harddog_kern.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c index 64ff22aa077b..94bbcb5b9227 100644 --- a/arch/um/drivers/harddog_kern.c +++ b/arch/um/drivers/harddog_kern.c | |||
@@ -44,12 +44,13 @@ | |||
44 | #include <linux/reboot.h> | 44 | #include <linux/reboot.h> |
45 | #include <linux/smp_lock.h> | 45 | #include <linux/smp_lock.h> |
46 | #include <linux/init.h> | 46 | #include <linux/init.h> |
47 | #include <linux/spinlock.h> | ||
47 | #include <asm/uaccess.h> | 48 | #include <asm/uaccess.h> |
48 | #include "mconsole.h" | 49 | #include "mconsole.h" |
49 | 50 | ||
50 | MODULE_LICENSE("GPL"); | 51 | MODULE_LICENSE("GPL"); |
51 | 52 | ||
52 | /* Locked by the BKL in harddog_open and harddog_release */ | 53 | static DEFINE_SPINLOCK(lock); |
53 | static int timer_alive; | 54 | static int timer_alive; |
54 | static int harddog_in_fd = -1; | 55 | static int harddog_in_fd = -1; |
55 | static int harddog_out_fd = -1; | 56 | static int harddog_out_fd = -1; |
@@ -62,12 +63,12 @@ extern int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock); | |||
62 | 63 | ||
63 | static int harddog_open(struct inode *inode, struct file *file) | 64 | static int harddog_open(struct inode *inode, struct file *file) |
64 | { | 65 | { |
65 | int err; | 66 | int err = -EBUSY; |
66 | char *sock = NULL; | 67 | char *sock = NULL; |
67 | 68 | ||
68 | lock_kernel(); | 69 | spin_lock(&lock); |
69 | if(timer_alive) | 70 | if(timer_alive) |
70 | return -EBUSY; | 71 | goto err; |
71 | #ifdef CONFIG_HARDDOG_NOWAYOUT | 72 | #ifdef CONFIG_HARDDOG_NOWAYOUT |
72 | __module_get(THIS_MODULE); | 73 | __module_get(THIS_MODULE); |
73 | #endif | 74 | #endif |
@@ -76,11 +77,15 @@ static int harddog_open(struct inode *inode, struct file *file) | |||
76 | sock = mconsole_notify_socket(); | 77 | sock = mconsole_notify_socket(); |
77 | #endif | 78 | #endif |
78 | err = start_watchdog(&harddog_in_fd, &harddog_out_fd, sock); | 79 | err = start_watchdog(&harddog_in_fd, &harddog_out_fd, sock); |
79 | if(err) return(err); | 80 | if(err) |
81 | goto err; | ||
80 | 82 | ||
81 | timer_alive = 1; | 83 | timer_alive = 1; |
82 | unlock_kernel(); | 84 | spin_unlock(&lock); |
83 | return nonseekable_open(inode, file); | 85 | return nonseekable_open(inode, file); |
86 | err: | ||
87 | spin_unlock(&lock); | ||
88 | return err; | ||
84 | } | 89 | } |
85 | 90 | ||
86 | extern void stop_watchdog(int in_fd, int out_fd); | 91 | extern void stop_watchdog(int in_fd, int out_fd); |
@@ -90,14 +95,16 @@ static int harddog_release(struct inode *inode, struct file *file) | |||
90 | /* | 95 | /* |
91 | * Shut off the timer. | 96 | * Shut off the timer. |
92 | */ | 97 | */ |
93 | lock_kernel(); | 98 | |
99 | spin_lock(&lock); | ||
94 | 100 | ||
95 | stop_watchdog(harddog_in_fd, harddog_out_fd); | 101 | stop_watchdog(harddog_in_fd, harddog_out_fd); |
96 | harddog_in_fd = -1; | 102 | harddog_in_fd = -1; |
97 | harddog_out_fd = -1; | 103 | harddog_out_fd = -1; |
98 | 104 | ||
99 | timer_alive=0; | 105 | timer_alive=0; |
100 | unlock_kernel(); | 106 | spin_unlock(&lock); |
107 | |||
101 | return 0; | 108 | return 0; |
102 | } | 109 | } |
103 | 110 | ||