wake_up & wait_event are counting events ?
Hello, I am trying to correctly register interrupt in kernel for user interface: irq handler ========= static irqreturn_t irq_handler(int irq, void *dev_id) { struct elbit_irq_dev *elbit_irq = &elbit_irq_devices[0]; printk("irq in\n"); <<==== clear interrupt in fpga here or after the call to wake_up, (at the bottom of routine below ) ? atomic_set(&elbit_irq->flag, 1); wake_up_interruptible(&elbit_irq->pollw); return IRQ_HANDLED; } ioctl for waiting on interrupts ====================== static long elbit_device_ioctl( struct file *filp, /* ditto */ unsigned int ioctl_num, /* number and param for ioctl */ unsigned long ioctl_param) { struct elbit_irq_dev *elbit_irq = &elbit_irq_devices[0]; switch (ioctl_num) { case IOCTL_WAIT_IRQ: atomic_set(&elbit_irq->flag, 0); wait_event_interruptible(elbit_irq->pollw, atomic_read(&elbit_irq->flag) != 0) ; break; default: break; } return 0; } my questions: 1. does wake_up and wait_event are countable, i.e. if there are 2 interrupts for example before wait_event is called, does it mean it wake_event will not sleep on 2 consecutive calls ? 2. should we put the clear of interrupts in fpga in the interrupt before or after the wake_up ? can we put them instead in the userspace handler (IOCTL_WAIT_IRQ) instead of clearing the interrupt in the interrupt handler ? Thank you, Ran
Hi! On 15:14 Thu 19 Jan , Ran Shalit wrote:
Hello,
I am trying to correctly register interrupt in kernel for user interface:
irq handler =========
static irqreturn_t irq_handler(int irq, void *dev_id) { struct elbit_irq_dev *elbit_irq = &elbit_irq_devices[0]; printk("irq in\n");
<<==== clear interrupt in fpga here or after the call to wake_up, (at the bottom of routine below ) ?
atomic_set(&elbit_irq->flag, 1); wake_up_interruptible(&elbit_irq->pollw);
return IRQ_HANDLED; }
ioctl for waiting on interrupts ======================
static long elbit_device_ioctl( struct file *filp, /* ditto */ unsigned int ioctl_num, /* number and param for ioctl */ unsigned long ioctl_param) { struct elbit_irq_dev *elbit_irq = &elbit_irq_devices[0];
switch (ioctl_num) { case IOCTL_WAIT_IRQ: atomic_set(&elbit_irq->flag, 0); wait_event_interruptible(elbit_irq->pollw, atomic_read(&elbit_irq->flag) != 0) ; break;
default: break; } return 0; }
my questions: 1. does wake_up and wait_event are countable, i.e. if there are 2 interrupts for example before wait_event is called, does it mean it wake_event will not sleep on 2 consecutive calls ?
No, wait_event will sleep if the test "atomic_read(&elbit_irq->flag) != 0" says so. In your code there is a race condition: 1) interrupt handler sets flag to 1 2) ioctl sets it to 0 ==> wait_event_interruptible sleeps even tough it probably should not You may want to replace the atomic_set() with atomic_inc() and atomic_dec() if you want to wake up once every time the interrupt handler gets executed.
2. should we put the clear of interrupts in fpga in the interrupt before or after the wake_up ?
I do not think that this makes any difference.
can we put them instead in the userspace handler (IOCTL_WAIT_IRQ) instead of clearing the interrupt in the interrupt handler ?
I do not think that this will work. -Michi -- programing a layer 3+4 network protocol for mesh networks see http://michaelblizek.twilightparadox.com
participants (2)
-
michi1ļ¼ michaelblizek.twilightparadox.com -
Ran Shalit