Showing posts with label interrupt handling. Show all posts
Showing posts with label interrupt handling. Show all posts

Wednesday, March 12, 2014

why to use request_threaded_irq?

I know for many this function may be very clear, but I found it really difficult to digest this function. So lets start it :

Why we need it ?
From the starting, it was desired for kernel to reduce the time for which processor stays in interrupt context. To solve this initially they introduced Top half and bottom half concept, in which they keep time critical task in top half and rest of the work they kept in bottom half. When processor is executing the interrupt handler it is in interrupt context with interrupts disabled on that line, which is not good because if it is a shared line, other interrupts won't be handled during this time, which in turn effect the overall system latency.
               To overcome this problem, kernel developers came up with the request_threaded_irq() method which futher reduces the time.

How it works?
Before going further with the functionality, lets check the function definition first

int request_threaded_irq (unsigned int irq,
 irq_handler_t handler,
 irq_handler_t thread_fn,
 unsigned long irqflags,
 const char * devname,
 void * dev_id);



Difference between this function and usual request_irq function is the extra thread_fn. 
Now lets understand the functionality, request_threaded_irq() breaks handler code in two parts, 1st handler and 2nd thread function. Now main functionality of handler is to intimate Hardware that it has received the interrupt and wake up thread function. As soon as handler finishes, processor is in process context. 
so processor is free to receive new interrupts. It improves the overall latency.

Misc:
Some driver code uses request_threaded_irq() with NULL as a value for handler, in that scenario kernel will invoke the default handler, which simply wakeup the thread function.

When to use request_threaded_irq instead of bottom halves ?
Answer lies in the driver's requirement, if it wants to sleep put the code in thread fn and user threaded function. 

Monday, February 10, 2014

Spin lock

Lets start with spin lock. First we will understand what is it and further I will try to cover few doubts about it, which could be quite useful in Interviews.

What is Spin lock :
Spin lock is a lock that can be held by at most one thread of execution. Suppose one thread is trying to acquire a spin lock, so first it will check whether this spinlock is held by other thread or not, if it is available it will acquire the lock otherwise it will constantly keep on checking (busy looping) for this lock.

Properties :
1. It should be held for small duration only, because during the time a spin lock is held no other thread can be scheduled on that processor.
2. On uni processor, if spin lock is held, it means it will now behave as kernel preemption is disable. As no other thread can run.
3. On Multi processor, no other thread will be able to take this spin lock.
4. If interrupt handler needs to use lock, they can use spinlock. Also we must ensure that local interrupts are disable before obtaining the lock. Otherwise, it is possible for an interrupt handler to interrupt the kernel code while lock is held. This in turn will make interrupt handler to spins, waiting for the lock to become available while lock holder thread will wait interrupt handler to complete. This is deadlock.

Now another scenario, Suppose you disabled interrupt on local processor and a process is holding the lock. At the same time interrupt came on other processor, it will make process to release the spinlock.


Wednesday, February 5, 2014

Why Interrupts can't sleep ? And Nested Interrupt

So Lets start with a simple and very important question, why Interrupt can't sleep.

First go back to our understanding to User Context, there we can sleep why? because when you sleep in it, you can call schedule() which can ask other processes to run.

But when you are in Interrupt context, the only thing residing on that Processor is the Interrupt handler(of the respective interrupt). So if you sleep now, there is nothing else to schedule. So its like processor itself is in sleep which is not good at all.

Nested Interrupt

Now there are few things associated with Interrupt, like nested interrupts. So Nested interrupt is when you are running and interrupt handler and more interrupts come on the same line. So in interrupt handler you are getting another interrupt.

When this situation arises ?
Suppose for some reason you need to call enable_irq() in interrupt handler, so it means you are telling your hardware that you are ready to receive the new interrupt.

How Kernel Handles it ?
For this situation, Kernel have third mode called System Mode( apart from user and kernel mode). This is also a privileged mode. So if you want to enable nested interrupt you should change mode to system, and then you should enable interrupt. Before enabling interrupt, you keep LR and SPSR of IRQ mode in Stack of System mode.
This way we save LR and SPSR from being corrupted. And once the new interrupt handled it can return to the previous interrupt and finally it can go back to original location.
you can refer this link for more clarity.