On 10/18/20 11:58 AM, William Breathitt Gray wrote:
On Wed, Oct 14, 2020 at 05:40:44PM -0500, David Lechner wrote:
On 9/26/20 9:18 PM, William Breathitt Gray wrote:
+static ssize_t counter_chrdev_read(struct file *filp, char __user *buf,
+                                  size_t len, loff_t *f_ps)
+{
+       struct counter_device *const counter = filp->private_data;
+       int err;
+       unsigned long flags;
+       unsigned int copied;
+
+       if (len < sizeof(struct counter_event))
+               return -EINVAL;
+
+       do {
+               if (kfifo_is_empty(&counter->events)) {
+                       if (filp->f_flags & O_NONBLOCK)
+                               return -EAGAIN;
+
+                       err = wait_event_interruptible(counter->events_wait,
+                                       !kfifo_is_empty(&counter->events));
+                       if (err)
+                               return err;
+               }
+
+               raw_spin_lock_irqsave(&counter->events_lock, flags);
+               err = kfifo_to_user(&counter->events, buf, len, &copied);
+               raw_spin_unlock_irqrestore(&counter->events_lock, flags);
+               if (err)
+                       return err;
+       } while (!copied);
+
+       return copied;
+}

All other uses of kfifo_to_user() I saw use a mutex instead of spin
lock. I don't see a reason for disabling interrupts here.

The Counter character device interface is special in this case because
counter->events could be accessed from an interrupt context. This is
possible if counter_push_event() is called for an interrupt (as is the
case for the 104_quad_8 driver). In this case, we can't use mutex
because we can't sleep in an interrupt context, so our only option is to
use spin lock.



The way I understand it, locking is only needed for concurrent readers
and locking between reader and writer is not needed.

Reply via email to