aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha/kernel/srmcons.c
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2012-03-05 08:51:58 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-08 14:42:21 -0500
commitee024d494ab75426bc77e0c053700915f0a1a16d (patch)
treef679d17f39f8dc46836bdc72a6d74703943e121f /arch/alpha/kernel/srmcons.c
parent5e88e6c4e8b044a1d275f1a599128b95046d2968 (diff)
ALPHA: srmcons, fix racy singleton structure
The test and the assignment were racy. Make it really a singleton. This is achieved by one global variable initialized at the module init. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Matt Turner <mattst88@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/alpha/kernel/srmcons.c')
-rw-r--r--arch/alpha/kernel/srmcons.c40
1 files changed, 5 insertions, 35 deletions
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c
index f1fdf178bcb4..2c89ce5c9ab6 100644
--- a/arch/alpha/kernel/srmcons.c
+++ b/arch/alpha/kernel/srmcons.c
@@ -33,7 +33,7 @@ struct srmcons_private {
33 struct tty_struct *tty; 33 struct tty_struct *tty;
34 struct timer_list timer; 34 struct timer_list timer;
35 spinlock_t lock; 35 spinlock_t lock;
36}; 36} srmcons_singleton;
37 37
38typedef union _srmcons_result { 38typedef union _srmcons_result {
39 struct { 39 struct {
@@ -154,43 +154,10 @@ srmcons_chars_in_buffer(struct tty_struct *tty)
154} 154}
155 155
156static int 156static int
157srmcons_get_private_struct(struct srmcons_private **ps)
158{
159 static struct srmcons_private *srmconsp = NULL;
160 static DEFINE_SPINLOCK(srmconsp_lock);
161 unsigned long flags;
162 int retval = 0;
163
164 if (srmconsp == NULL) {
165 srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL);
166 spin_lock_irqsave(&srmconsp_lock, flags);
167
168 if (srmconsp == NULL)
169 retval = -ENOMEM;
170 else {
171 srmconsp->tty = NULL;
172 spin_lock_init(&srmconsp->lock);
173 setup_timer(&srmconsp->timer, srmcons_receive_chars,
174 (unsigned long)srmconsp);
175 }
176
177 spin_unlock_irqrestore(&srmconsp_lock, flags);
178 }
179
180 *ps = srmconsp;
181 return retval;
182}
183
184static int
185srmcons_open(struct tty_struct *tty, struct file *filp) 157srmcons_open(struct tty_struct *tty, struct file *filp)
186{ 158{
187 struct srmcons_private *srmconsp; 159 struct srmcons_private *srmconsp = &srmcons_singleton;
188 unsigned long flags; 160 unsigned long flags;
189 int retval;
190
191 retval = srmcons_get_private_struct(&srmconsp);
192 if (retval)
193 return retval;
194 161
195 spin_lock_irqsave(&srmconsp->lock, flags); 162 spin_lock_irqsave(&srmconsp->lock, flags);
196 163
@@ -236,6 +203,9 @@ static const struct tty_operations srmcons_ops = {
236static int __init 203static int __init
237srmcons_init(void) 204srmcons_init(void)
238{ 205{
206 spin_lock_init(&srmcons_singleton.lock);
207 setup_timer(&srmcons_singleton.timer, srmcons_receive_chars,
208 (unsigned long)&srmcons_singleton);
239 if (srm_is_registered_console) { 209 if (srm_is_registered_console) {
240 struct tty_driver *driver; 210 struct tty_driver *driver;
241 int err; 211 int err;