0

In LDD3's scull_p_poll function, if I understand correctly, if poll_wait is not woken up and a timeout occurs, poll returns zero.

static unsigned int scull_p_poll(struct file *filp, poll_table *wait)
{
    struct scull_pipe *dev = filp->private_data;
    unsigned int mask = 0;

    /*
     * The buffer is circular; it is considered full
     * if "wp" is right behind "rp" and empty if the
     * two are equal.
     */
    down(&dev->sem);
    poll_wait(filp, &dev->inq,  wait);
    poll_wait(filp, &dev->outq, wait);
    if (dev->rp != dev->wp)
        mask |= POLLIN | POLLRDNORM;    /* readable */
    if (spacefree(dev))
        mask |= POLLOUT | POLLWRNORM;   /* writable */
    up(&dev->sem);
    return mask;
}

Is this a correct assumption as to how poll_wait will work? This is what I took away from Why do we need to call poll_wait in poll? and How to add poll function to the kernel module code?

As all examples I have seen return zero if not a valid POLLIN or POLLRDNORM state exists, I assume zero is the correct timeout return. Can anyone clarify this or point me to documentation that shows this? I have not read deeper than poll.h

Community
  • 1
  • 1
johnnymopo
  • 158
  • 9
  • Are you failed to understand [answer](http://stackoverflow.com/a/30240320/3440745) to the first linked question? **`poll_wait` doesn't wait at all**. Mask, returning `scull_p_poll` is AND-ed with the mask requested in `select`/`poll` system call and resulted mask is compared with 0. If resulted mask is non-zero, device is treated as *ready*, and system call returns. Otherwise, device is treated as *not ready*, and system call waits (outside of `scull_p_poll`!). Actual implementation of *poll*-related system calls is in `fs/select.c`. – Tsyvarev Nov 10 '15 at 18:06
  • ahh, thanks for pointing me to fs/select.c - I did not actually understand it but your repeating "poll_wait doesn't wait at all" hammered it into my head. I get it now – johnnymopo Nov 10 '15 at 18:15

1 Answers1

0

In the given example, let's say that you have a userspace app polls your driver like below for a read case.

   struct pollfd pofd;
   pofd.fd = open("/dev/scull", O_RDONLY | O_NONBLOCK);
   pofd.events = POLLIN | POLLRDNORM;
   pofd.revents = 0;

   /* Notice no timeout given. */
   ret = poll(&pofd, 1, -1);

   if (pofd.revents | POLLIN) {
      printf("POLLIN done, reading from the device.\n");
      ret = read(pofd.fd, receive, BUFFER_LENGTH);
      ......
   }

Once the data ready condition will be accomplished, you need to wake the waitqueue up in your kernelspace device driver like :

wake_up_interruptible(&dev->inq);
cagdas
  • 1,634
  • 2
  • 14
  • 27