Skip to content

Commit

Permalink
Input: serio_raw - perform proper locking when adding clients to list
Browse files Browse the repository at this point in the history
Make sure we hold serio lock when adding clients to client list so that
we do not race with serio_raw_release() removing clients from the same
list.

Reviewed-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
  • Loading branch information
Dmitry Torokhov committed Oct 11, 2011
1 parent 7c5bbb2 commit 843e784
Showing 1 changed file with 5 additions and 3 deletions.
8 changes: 5 additions & 3 deletions drivers/input/serio/serio_raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,10 @@ static int serio_raw_open(struct inode *inode, struct file *file)
file->private_data = client;

kref_get(&serio_raw->kref);

serio_pause_rx(serio_raw->serio);
list_add_tail(&client->node, &serio_raw->client_list);
serio_continue_rx(serio_raw->serio);

out:
mutex_unlock(&serio_raw_mutex);
Expand Down Expand Up @@ -138,18 +141,17 @@ static int serio_raw_release(struct inode *inode, struct file *file)

static int serio_raw_fetch_byte(struct serio_raw *serio_raw, char *c)
{
unsigned long flags;
int empty;

spin_lock_irqsave(&serio_raw->serio->lock, flags);
serio_pause_rx(serio_raw->serio);

empty = serio_raw->head == serio_raw->tail;
if (!empty) {
*c = serio_raw->queue[serio_raw->tail];
serio_raw->tail = (serio_raw->tail + 1) % SERIO_RAW_QUEUE_LEN;
}

spin_unlock_irqrestore(&serio_raw->serio->lock, flags);
serio_continue_rx(serio_raw->serio);

return !empty;
}
Expand Down

0 comments on commit 843e784

Please sign in to comment.