0

Assume a pci-driver for the linux-kernel. This device can have multiple channels that can be "up'ed" or "down'ed" individually.
Each "up" calls the function .ndo_open and each "down" calls .ndo_stop.
This device needs only one interrupt-line which can be requested with request_irq (). Each request will create one interrupt-line. Important to note here is, that interrupt-lines are rare and they should not be created mindless. My question to this situation is, where should I use request_irq()?

In my opinion I have two possible solutions for this.

  1. Right in the probe(). This will only create one interrupt-line but it will always be created when the pc is turned on. So it might be unused.
  2. In .ndo_open. This will create the interrupt-line only when it is needed, but a multichannel device can create mutliple calls of .ndo_open which will result in multiple calls of request_irq()

I was not able to find any information about this situation in the kernel docs. If there is some guideline for this, can you please explain/show it to me? I also checked other pci-drivers from the git-repo but none (or at least the ones I checked) had this problem.

xMutzelx
  • 566
  • 8
  • 22
  • IIRC Each device should have a pointer to a custom structure where you can store additional data. What if you use it to store the information of the IRQ allocated? Then you could allocated it lazily and just once (be careful of multi-threading issues). – Margaret Bloom Apr 03 '19 at 10:25
  • @MargaretBloom Mhm, I also though about that because e.g. driver for sja1000 is also using this method. I am not sure if I get something wrong, but the custom structure is created for every "channel" therefor if we up it, it also creates a new interrupt-line, or am I wrong here? – xMutzelx Apr 03 '19 at 10:50
  • I believe you can use a global variable for anything that must be scoped module wise. That way you'll have a single IRQ allocated the first time open is called. – Margaret Bloom Apr 03 '19 at 15:21
  • Since it's a PCI device, you are going to need to call `irq_request` with the `IRQF_SHARED` flag. There is no particular reason why you can't request the same IRQ number for the same PCI device multiple times. Your interrupt handler needs to determine from the context pointer whether its channel is interrupting and return `IRQ_NONE` if it is not. – Ian Abbott Apr 03 '19 at 16:01
  • It depends how many IRQ lines device provides, i.o.w. does it have MSI/MSI-x support? If not, you may not call *request_irq()* multiple times. I guess you missed the fact that *request_irq()* does not allocate an interrupt. It’s done by *pci_alloc_irq_vectors()*. – 0andriy Apr 04 '19 at 07:02
  • Yeah, and the example of good handling small amount of interrupt lines is thunderbolt driver. – 0andriy Apr 04 '19 at 07:11
  • @0andriy I don't think there is anything stopping you calling `request_irq()` multiple times for the same PCI device as long as the calls have a unique `dev` context pointer. The context is completely opaque to `request_irq()`. But for performance, it is better to have a single IRQ handler for the PCI device and let it figure out which channels are interrupting. – Ian Abbott Apr 04 '19 at 09:48

0 Answers0