From: Vojtech Pavlik <vojtech@suse.cz>
To: torvalds@osdl.org, vojtech@suse.cz, linux-kernel@vger.kernel.org
Subject: [PATCH 2/47] Fix locking in i8042.c and serio.c
Date: Thu, 29 Jul 2004 16:09:54 +0200 [thread overview]
Message-ID: <10911101942422@twilight.ucw.cz> (raw)
In-Reply-To: <10911101941048@twilight.ucw.cz>
You can pull this changeset from:
bk://kernel.bkbits.net/vojtech/input
===================================================================
ChangeSet@1.1612.24.2, 2004-05-28 18:24:08+02:00, vojtech@suse.cz
input: An attempt at fixing locking in i8042.c and serio.c
drivers/input/serio/i8042.c | 4 ++
drivers/input/serio/serio.c | 64 +++++++++++++++++++++++++++++++++++++-------
include/linux/serio.h | 2 -
3 files changed, 59 insertions(+), 11 deletions(-)
===================================================================
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c Thu Jul 29 14:42:23 2004
+++ b/drivers/input/serio/i8042.c Thu Jul 29 14:42:23 2004
@@ -95,6 +95,7 @@
/*
* The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to
* be ready for reading values from it / writing values to it.
+ * Called always with i8042_lock held.
*/
static int i8042_wait_read(void)
@@ -677,6 +678,7 @@
static int i8042_controller_init(void)
{
+ unsigned long flags;
/*
* Test the i8042. We need to know if it thinks it's working correctly
@@ -723,12 +725,14 @@
* Handle keylock.
*/
+ spin_lock_irqsave(&i8042_lock, flags);
if (~i8042_read_status() & I8042_STR_KEYLOCK) {
if (i8042_unlock)
i8042_ctr |= I8042_CTR_IGNKEYLOCK;
else
printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n");
}
+ spin_unlock_irqrestore(&i8042_lock, flags);
/*
* If the chip is configured into nontranslated mode by the BIOS, don't
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c Thu Jul 29 14:42:23 2004
+++ b/drivers/input/serio/serio.c Thu Jul 29 14:42:23 2004
@@ -67,12 +67,18 @@
struct list_head node;
};
-static DECLARE_MUTEX(serio_sem);
+
+spinlock_t serio_lock = SPIN_LOCK_UNLOCKED; /* protects serio_event_list and serio->dev */
+static DECLARE_MUTEX(serio_sem); /* protects serio_list and serio_dev_list */
static LIST_HEAD(serio_list);
static LIST_HEAD(serio_dev_list);
static LIST_HEAD(serio_event_list);
static int serio_pid;
+/*
+ * serio_find_dev() must be called with serio_sem down.
+ */
+
static void serio_find_dev(struct serio *serio)
{
struct serio_dev *dev;
@@ -96,22 +102,42 @@
static void serio_invalidate_pending_events(struct serio *serio)
{
struct serio_event *event;
+ unsigned long flags;
+
+ spin_lock_irqsave(&serio_lock, flags);
list_for_each_entry(event, &serio_event_list, node)
if (event->serio == serio)
event->serio = NULL;
+
+ spin_unlock_irqrestore(&serio_lock, flags);
}
void serio_handle_events(void)
{
- struct list_head *node, *next;
+ struct list_head *node;
struct serio_event *event;
+ unsigned long flags;
+
+
+ while (1) {
+
+ spin_lock_irqsave(&serio_lock, flags);
+
+ if (list_empty(&serio_event_list)) {
+ spin_unlock_irqrestore(&serio_lock, flags);
+ break;
+ }
- list_for_each_safe(node, next, &serio_event_list) {
+ node = serio_event_list.next;
event = container_of(node, struct serio_event, node);
+ list_del_init(node);
+
+ spin_unlock_irqrestore(&serio_lock, flags);
down(&serio_sem);
- if (event->serio == NULL)
+
+ if (event->serio == NULL) /*!!!*/
goto event_done;
switch (event->type) {
@@ -139,7 +165,6 @@
}
event_done:
up(&serio_sem);
- list_del_init(node);
kfree(event);
}
}
@@ -178,12 +203,18 @@
void serio_rescan(struct serio *serio)
{
+ unsigned long flags;
+ spin_lock_irqsave(&serio_lock, flags);
serio_queue_event(serio, SERIO_RESCAN);
+ spin_unlock_irqrestore(&serio_lock, flags);
}
void serio_reconnect(struct serio *serio)
{
+ unsigned long flags;
+ spin_lock_irqsave(&serio_lock, flags);
serio_queue_event(serio, SERIO_RECONNECT);
+ spin_unlock_irqrestore(&serio_lock, flags);
}
irqreturn_t serio_interrupt(struct serio *serio,
@@ -191,17 +222,22 @@
{
irqreturn_t ret = IRQ_NONE;
+ spin_lock_irq(&serio_lock);
+
if (serio->dev && serio->dev->interrupt) {
ret = serio->dev->interrupt(serio, data, flags, regs);
} else {
if (!flags) {
- if ((serio->type == SERIO_8042 ||
- serio->type == SERIO_8042_XL) && (data != 0xaa))
- return ret;
- serio_rescan(serio);
- ret = IRQ_HANDLED;
+ if ((serio->type != SERIO_8042 &&
+ serio->type != SERIO_8042_XL) || (data == 0xaa)) {
+ serio_queue_event(serio, SERIO_RESCAN);
+ ret = IRQ_HANDLED;
+ }
}
}
+
+ spin_unlock_irq(&serio_lock);
+
return ret;
}
@@ -292,7 +328,11 @@
/* called from serio_dev->connect/disconnect methods under serio_sem */
int serio_open(struct serio *serio, struct serio_dev *dev)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&serio_lock, flags);
serio->dev = dev;
+ spin_unlock_irqrestore(&serio_lock, flags);
if (serio->open && serio->open(serio)) {
serio->dev = NULL;
return -1;
@@ -303,9 +343,13 @@
/* called from serio_dev->connect/disconnect methods under serio_sem */
void serio_close(struct serio *serio)
{
+ unsigned long flags;
+
if (serio->close)
serio->close(serio);
+ spin_lock_irqsave(&serio_lock, flags);
serio->dev = NULL;
+ spin_unlock_irqrestore(&serio_lock, flags);
}
static int __init serio_init(void)
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h Thu Jul 29 14:42:23 2004
+++ b/include/linux/serio.h Thu Jul 29 14:42:23 2004
@@ -36,7 +36,7 @@
int (*open)(struct serio *);
void (*close)(struct serio *);
- struct serio_dev *dev;
+ struct serio_dev *dev; /* Accessed from interrupt, writes must be protected by serio_lock */
struct list_head node;
};
next prev parent reply other threads:[~2004-07-29 14:55 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-07-29 14:07 [patches] Input updates Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 1/47] Add 64-bit compatible ioctls for hiddev Vojtech Pavlik
2004-07-29 14:09 ` Vojtech Pavlik [this message]
2004-07-29 14:09 ` [PATCH 3/47] Fix an oops in poll() on uinput Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 4/47] Ensure exclusive access to variables in atkbd.c Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 5/47] Return 0 from uinput poll if device isn't yet created Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 6/47] Explicit variable access rules for psmouse.c Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 7/47] Add reporting of raw scancodes to atkbd.c Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 8/47] Use raw events generated by atkbd in keyboard.c to implement true rawmode for PS/2 keyboards Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 9/47] Fixes in serio locking Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 10/47] Disable the AUX LoopBack command in i8042.c on Compaq ProLiant Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 11/47] Make atkbd.c's atkbd_command() function immune to keys being pressed while running Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 12/47] More locking improvements (and a fix) for serio Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 13/47] Add a missing dmi_noloop declaration in i8042.c Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 14/47] logips2pp - do not call get_model_info 2 times Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 15/47] Fix compilation breakage when CONFIG_USB_HIDDEV not defined Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 16/47] Make hardware rawmode optional for AT-keyboards Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 17/47] Fix boundary checks for GUSAGE/SUSAGE in hiddev Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 18/47] Updates to the tsdev driver (raw protocol, calib ioctls, ...) Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 19/47] mousedev - better handle button presses when under load Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 20/47] mousedev - implement tapping for touchpads Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 21/47] Remove OSB4/Profusion hack in i8042 Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 22/47] rearrangements and cleanups in serio.c Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 23/47] Fix bad struct hidinput initialization in hid-tmff.c Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 24/47] Remove an extra dmi_noloop declaration in i8042.c Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 25/47] Enhancements/fixes for PSX pad support Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 26/47] when probing for ImExPS/2 mice, the ImPS/2 sequence needs to be sent first Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 27/47] Fix array overflows in keyboard.c when KEY_MAX > keycode > NR_KEYS > 128 Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 28/47] Add Dell SB Live! PCI ID to the emu10k1-gp driver Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 29/47] Add Audigy LS PCI ID to emu10k1-gp Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 30/47] Add CodeMercs IOWarrior to hid-core device blacklist Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 31/47] Fix Peter Nelson's e-mail address in gamecon.c Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 32/47] make connect and disconnect methods mandatory for serio Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 33/47] rename serio->driver to serio->port_data Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 34/47] more renames in serio in preparation for sysfs integration Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 35/47] switch to dynamic (heap) serio port allocation Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 36/47] allow serio drivers to create children ports Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 37/47] serio sysfs integration Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 38/47] allow users to manually rebind serio ports Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 39/47] allow marking some drivers as manual bind only Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 40/47] Add serio_raw driver Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 41/47] link (some) serio ports to their parent devices Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 42/47] Fix Kconfig so that the joydump module can be compiled Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 43/47] Move Compaq ProLiant DMI handling to i8042.c Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 44/47] This patch fixes another disconnect oops in hiddev Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 45/47] Re-add PC Speaker support for PPC Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 46/47] Fix a missing index in tmdc.c Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 47/47] Check the range for HIDIOC?USAGES num_values Vojtech Pavlik
2004-07-29 16:59 ` [patches] Input updates Vojtech Pavlik
2004-07-29 16:59 ` [PATCH 1/2] move input/serio closer to the top of drivers/Makefile so serio_bus is available early Vojtech Pavlik
2004-07-29 16:59 ` [PATCH 2/2] rearrange code in sunzilog to prevent deadlock Vojtech Pavlik
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=10911101942422@twilight.ucw.cz \
--to=vojtech@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox