2

I have a PCIe device that will send a hardware interrupt when a data buffer is ready to be read. I believe the best approach for this is to use signals but I'm not entirely sure how. What I believe I need to do is:

  1. Save the PID of the user space application so the driver knows where to send the signal
  2. In the interrupt handler of the PCIe device driver, send a signal to the user space application
  3. In the User space application implement a signal handler function for processing the signal

I'm not sure how to do either of these. How/Where do I save the PID of the user space application? How do I send a signal to that specific PID from the driver's interrupt handler (I believe I should use the kill command but I'm more interested in the syntax of getting the PID)? How do I have the user space application wait for the signal after saving its PID? Is it possible to have the user space application continue to run after saving its PID, run the signal handler function when a signal is received, and continue running where it was before the signal arrived? (similar to how an ISR works)

Chris
  • 402
  • 1
  • 5
  • 18
  • 3
    Not sure if signals are the correct way to do that. Maybe a char device fit better here? Then the userspace application could use `select` or `poll` to know when to process the buffer. – cha0site Jul 06 '12 at 17:43
  • Well I need the buffer read in the user space application to function like an interrupt. I don't want to have some other version of polling implemented. Currently I just poll the device for a specific flag that gets set when the buffer is full. Maybe this is still possible with a char device though I'm not too familiar with them. – Chris Jul 06 '12 at 17:48
  • 2
    `poll(2)` is not a good name for what the function does - it doesn't actually poll, it waits for an event (like `select(2)`). See the linux device drivers book here: http://www.xml.com/ldd/chapter/book/ch05.html#t4 – cha0site Jul 06 '12 at 17:54

3 Answers3

2

Don't use signals for this. Implement a character device. The userspace application will open it, then call read and will be blocked until your driver determines there is data available.

See Linux Device Drivers chapter 3, I think.

Paul Coccoli
  • 546
  • 1
  • 4
  • 16
  • Maybe a char device is what I need, but I'm still not sure if it os. The device periodically sends an interrupt to the driver which needs to then communicate that this interrupt arrived to the user space application. The data is always available but the user space application should only read the data periodically so that it has time to print it all out. Currently the user space application polls waiting for a flag to change which is toggled on the device. It seems like adding a char device is unnecessary overhead. Why shouldn't signals be used? – Chris Jul 06 '12 at 19:45
  • 1
    How does the application know where to read the data from? What happens if an interrupt occurs while the user space application is reading the data buffer? All of these details are taken care of if you use established designs like char devices. There are a lot of rules of what you can and can't do in interrupt handlers. Are you prepared to deal with those? – Paul Coccoli Jul 06 '12 at 20:36
  • The application reads and writes to direct memory locations on the device. If a char device is used this will still take place. The interrupt is generated on the device by setting a bit in a specific register which causes the interrupt handler on the driver to run. The interrupt handler won't run again until the bit is cleared and set again. The device doesn't clear this bit and must be done by either the driver or the application. Sending multiple standard signals (kill) only lets one be queued. I'm already using an interrupt handler in the driver so those rules are currently being dealt with – Chris Jul 06 '12 at 20:58
  • If you're intent on using signals, then you need a way for your application to talk to your driver. This is usually done via a char device. You could use `ioctl` to pass the app's pid to the driver. Not sure how to find the task_struct. Maybe [http://stackoverflow.com/questions/8547332/kernel-efficient-way-to-find-task-struct-by-pid] – Paul Coccoli Jul 06 '12 at 21:09
  • Hmm signals just seemed like it would be simple and easy. It doesn't look like signals are supported the same easy way in the version of linux I am using. I guess char driver is the way to go but I have no idea what to do with that yet. – Chris Jul 06 '12 at 22:25
  • Signals **seem** like a good idea. They aren't. Some of our first Linux drivers used signals, and we ran into a variety of issues. In newer drivers, we use select(). – myron-semack Aug 01 '12 at 13:42
0

Have to handle interrupt directly in kernel. In order to pass PID to kernel, have to use the device file abstraction (e.g. ioctl() calls), but it provides asynchronous notification through read/select as well so signal solution is replaced.

renonsz
  • 571
  • 1
  • 4
  • 17
0

This is an old question, but to manage IRQ from application userspace, the better way now is to use UIO driver and poll/select call on /dev/uioX.

FabienM
  • 3,421
  • 23
  • 45