summaryrefslogtreecommitdiffstats
path: root/arch/alpha/kernel/srmcons.c
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2012-03-05 14:51:58 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-08 20:42:21 +0100
commitee024d494ab75426bc77e0c053700915f0a1a16d (patch)
treef679d17f39f8dc46836bdc72a6d74703943e121f /arch/alpha/kernel/srmcons.c
parentALPHA: srmcons, use timer functions (diff)
downloadlinux-ee024d494ab75426bc77e0c053700915f0a1a16d.tar.xz
linux-ee024d494ab75426bc77e0c053700915f0a1a16d.zip
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 {
struct tty_struct *tty;
struct timer_list timer;
spinlock_t lock;
-};
+} srmcons_singleton;
typedef union _srmcons_result {
struct {
@@ -154,43 +154,10 @@ srmcons_chars_in_buffer(struct tty_struct *tty)
}
static int
-srmcons_get_private_struct(struct srmcons_private **ps)
-{
- static struct srmcons_private *srmconsp = NULL;
- static DEFINE_SPINLOCK(srmconsp_lock);
- unsigned long flags;
- int retval = 0;
-
- if (srmconsp == NULL) {
- srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL);
- spin_lock_irqsave(&srmconsp_lock, flags);
-
- if (srmconsp == NULL)
- retval = -ENOMEM;
- else {
- srmconsp->tty = NULL;
- spin_lock_init(&srmconsp->lock);
- setup_timer(&srmconsp->timer, srmcons_receive_chars,
- (unsigned long)srmconsp);
- }
-
- spin_unlock_irqrestore(&srmconsp_lock, flags);
- }
-
- *ps = srmconsp;
- return retval;
-}
-
-static int
srmcons_open(struct tty_struct *tty, struct file *filp)
{
- struct srmcons_private *srmconsp;
+ struct srmcons_private *srmconsp = &srmcons_singleton;
unsigned long flags;
- int retval;
-
- retval = srmcons_get_private_struct(&srmconsp);
- if (retval)
- return retval;
spin_lock_irqsave(&srmconsp->lock, flags);
@@ -236,6 +203,9 @@ static const struct tty_operations srmcons_ops = {
static int __init
srmcons_init(void)
{
+ spin_lock_init(&srmcons_singleton.lock);
+ setup_timer(&srmcons_singleton.timer, srmcons_receive_chars,
+ (unsigned long)&srmcons_singleton);
if (srm_is_registered_console) {
struct tty_driver *driver;
int err;