diff mbox series

[6/8] gpiolib: actually protect the line event kfifo with mutex

Message ID 20191127133510.10614-7-brgl@bgdev.pl
State New
Headers show
Series gpiolib: add an ioctl() for monitoring line status changes | expand

Commit Message

Bartosz Golaszewski Nov. 27, 2019, 1:35 p.m. UTC
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

The read_lock mutex is supposed to prevent collisions between reading
and writing to the line event kfifo but it's actually only taken when
the events are being read from it. Also take the lock when adding the
events and checking if kfifo is empty.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/gpio/gpiolib.c | 8 ++++++++
 1 file changed, 8 insertions(+)
diff mbox series

Patch

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 17796437d7be..d094b1be334d 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -818,8 +818,10 @@  static __poll_t lineevent_poll(struct file *filep,
 
 	poll_wait(filep, &le->wait, wait);
 
+	mutex_lock(&le->read_lock);
 	if (!kfifo_is_empty(&le->events))
 		events = EPOLLIN | EPOLLRDNORM;
+	mutex_unlock(&le->read_lock);
 
 	return events;
 }
@@ -838,7 +840,9 @@  static ssize_t lineevent_read(struct file *filep,
 		return -EINVAL;
 
 	do {
+		mutex_lock(&le->read_lock);
 		if (kfifo_is_empty(&le->events)) {
+			mutex_unlock(&le->read_lock);
 			if (filep->f_flags & O_NONBLOCK)
 				return -EAGAIN;
 
@@ -846,6 +850,8 @@  static ssize_t lineevent_read(struct file *filep,
 					!kfifo_is_empty(&le->events));
 			if (ret)
 				return ret;
+		} else {
+			mutex_unlock(&le->read_lock);
 		}
 
 		if (mutex_lock_interruptible(&le->read_lock))
@@ -969,7 +975,9 @@  static irqreturn_t lineevent_irq_thread(int irq, void *p)
 		return IRQ_NONE;
 	}
 
+	mutex_lock(&le->read_lock);
 	ret = kfifo_put(&le->events, ge);
+	mutex_unlock(&le->read_lock);
 	if (ret)
 		wake_up_poll(&le->wait, EPOLLIN);