Linux: hrtimer_start in interrupt context - linux-kernel

Is hrtimer_start safe to call in interrupt context?

Looks like it is. Here it's called from GPIO IRQ handler.

Related

Difference btw interrupt and interrupt request

I am learning kernel interrupt handling and have question about probe_irq_on explanation http://www.linuxcertif.com/man/9/probe_irq_on/en/
"turns on IRQ detection. It operates by enabling all interrupts which have no handlers, while keeping the handlers for those interrupts NULL. The kernel's generic interrupt handling routine will disable these IRQs when an interrupt is received on them."
Does it say "interrupt is received on these IRQs" I always thought IRQ(Interrupt request) is same as Interrupt.So quite confused about this.
Is there any difference btw these two ??
Thanks
An interrupt request is just an indication to the CPU that a specific interrupt wants to happen. But perhaps interrupts are temporarily disabled, or another higher-priority interrupt is already going on.
Thus the interrupt itself doesn't happen until that request is serviced.
Here's some more reading for you about interrupt handlers.
The interrupt is the actual event that happens on the IRQ.

How does not disabling local interrupts in interrupt handler(which acquire lock) could lead to double-acquire deadlock?

In Linux Kernel Development book (Robert Love), It is mentioned that :
we must disable local interrupts before obtaining spinlock in
interrupt handler. Otherwise it is possible for an interrupt handler
to interrupt kernel code while the lock is held and attempt to
re-acquire the lock. Which finally can lead to double-acquire
deadlock.
Now my doubt is:
In general, doesn't do_IRQ() disables local interrupt ?
And if lock is acquire, it means thatpreempt_count variable is not zero, which makes that no other handler should get chance, as kernel is not preempt_safe. So how other interrupt handler can work in this situation ?
First, the do_IRQ() function dosn't disable the local interrupt, but some function written in assembly language does, which is the interrupt entrance. And later, before executing the interrupt function registering by request_irq(), in function handle_IRQ_event() a flag which also pass by request_irq() is compare with IRQF_DISABLED to determine whether we should enable the local interrupt when executing the interrupt function. So the answer to your question one is depending on the flags that you pass to the request_irq() function.
Second, preempt_count just means for kernel preemption in process context, but not for interrupt. To avoid interrupt handlers be executed in UP, the only way is involving the irqs_disable(). When the preempt_count is zero, it's said that the kernel can safely does the process switch, otherwise not.

For a shared interrupt line how do I find which interrupt handler to use?

For a shared interrupt line,I can have several interrupt handlers. The kernel will sequentially invoke all the handlers for that particular shared line.
As far as I know, each handler, when invoked informs the kernel whether it was the correct handler to be invoked or not.
My questions is how is this determined,is there a way it checks a memory mapped register that tells status of a particular device or is there some other hardware mechanism ? How does the handler know that the corresponding device is indeed the one that issued the interrupt or not ?
Is this information relayed through the interrupt controller that is between the devices and the processor interrupt line ??
The kernel will sequentially invoke all the handlers for that particular shared line.
Exactly. Say Dev1 and Dev2 shares the IRQ10. When an interrupt is generated for IRQ10, all ISRs registered with this line will be invoked one by one.
In our scenario, say Dev2 was the one that generated the interrupt. If Dev1's ISR is registered first, than its ISR (i.e Dev1's ISR) only called first. In that ISR, the interrupt status register will be verified for interrupt. If no interrupt bit is set (which is the case, cause Dev2 raised the interrupt) then we can confirm that interrupt was not generated by Dev1 - so Dev1's ISR should return to the kernel IRQ_NONE - which means:"I did not handled that interrupt", so on the kernel continues to the next ISR (i.e Dev2's ISR), which in turn, will indeed verify that its corresponding device generated the interrupt, thus, this handler should handle it and eventually return IRQ_HANDLED - which means:"I handled this one".
See the return values IRQ_NONE/IRQ_HANDLED for more information.
How does the handler know that the corresponding device issued the interrupt or not ?
By reading the Interrupt status register only.
Is this information relayed through the interrupt controller that is between the devices and the processor interrupt line ??
I'm not sure about this. But the OS will take care of calling ISRs based on the return values from ISR.

gcc --- __attribute__((interrupt( irq )))

i started with device driver for arm ... there i saw for each handler mention --- __attribute__((interrupt( irq ))) -.I am confused how this attribute will place a call to our driver routine ..??
IRQ of arm have following Vector address--- 0x00000018 (or 0xFFFF0018)
As there can be many interrupt handler on same line. Suppose if we have 4 device driver each with its own IRQ to be reistered.
Means some startup code will be provided by the GCC compiler for the IRQ handler & compiler will place call to our routine in that startup code for interrupt handler ..... Am i right ...?
From GCC docs for interrupt attribute:
The compiler generates function entry and exit sequences suitable for use in an interrupt handler when this attribute is present.
You can use objdump easily to see how this attribute changes your binary which should clarify the situation for you much better.
The attribute should ONLY be used by interrupt handler of the OS and NOT by interrupt handler of a specific driver. The OS will read the IRQ vector/number and call the appropriate driver function to service the IRQ. You only need to register your driver/ISR with the OS.

Calling XSpi_Transfer from within gpio interrupt context

In a microblaze environment on a virtex 5:
I have a situation where I need to do a spi transaction (XSpi_Transfer) to read from an external chip (mcp2515) in repsonse to an interrupt. The interrupt is triggered using the gpio interrupt feature of XGpio interface.
The problem I'm having is that the XSpi_Transfer hangs when called from interrupt context. Any hints on whether using XSpi from an interrupt is possible or not? I presume the issue is that the low level mechanism of the XSpi uses interrupts to perform low level fifo handling.

Resources