How to set Priority level for ISR - linux-kernel

I am performing small test application in C, I want to add new ISR routine for my custom task. I read some part of it to insert new ISR. Also i got few articles to generate interrupt (int 3 windbg DbgBreak interrupt).
The part of I am not able find is how to define PRIORITY for my interrupt, whether its at raising interrupt or while new ISR entry
Any help appreciated.

Related

why does arm-linux switch to SVC mode to handle exception?

arm doc reads
This is because a fresh interrupt could occur at any time, which would cause
the core to store the return address of the new interrupt and overwrite the original interrupt.
When the original interrupt attempts to return to the main program, it will cause the system to
fail. The nested handler must change into an alternative kernel mode before re-enabling
interrupts in order to prevent this.
according to the context, the main reason is that new-coming irq would overwrite R14(LR), so that the first irq cannot return to main program.
In my understanding, to solve this problem, I just need to push R14(LR_irq), SPSR_irq to R13(SP_irq) before next irq raising.
There is no need for nested handler to switch to alternative mode before re-enabling interrupts.
Thank you!
Consider this situation:
When you're in a IRQ handler and then perform a C function call, at this point the LR has been changed; so, if you then nest an IRQ right away, the LR will be corrupt.

When save states while dealing with tasklets?

I'm reading Linux Kernel development and get confused in the tasklets chapter (https://doc.lagout.org/operating%20system%20/linux/Linux%20Kernel%20Development%2C%203rd%20Edition.pdf page143).
In the tasklet_schedule function, the interrupt state is saved while in the taslet_action it is not. The author explains that the context is not saved in taslet_action because the function knows that interrupts are always enabled. I fail to understand how does the set of interrupts interfere with saving the context? Thank you!
The author states that tasklet_schedule can be called with either interrupts disabled or enabled. Since it wants them disabled, it needs to save whether they are already disabled. Then after the work is done it knows whether to enable them (if they were enabled prior to the call it enables them, if they were disabled prior to the call it leaves them disabled). In contrast, tasklet_action is only called with interrupts enabled, so there is no point in checking their state. They always get disabled and enabled on return.
In case of tasklet_schedule :
We do not want interrupt to disturb us when we are scheduling a tasklet, so we have to disable it. But we also know that, when we are done with scheduling the tasklet, we want to go back to the state of IRQ as it was before schedule tasklet was called. To achieve this, we save the state of the IRQ register before doing anything, then disable the IRQ as per our requirement, do the scheduling, now before going back restore the state of the IRQ and then return from the function.
Now coming to the complicated part, Why dont we need to save the IRQ when executing the tasklet i.e when the handler calls the tasklet function ?
To understand that we need to look at two different paragraphs :
On page 141 :
The softirq handlers run with interrupts enabled and cannot
sleep .While a handler runs, softirqs on the current processor are
disabled.Another processor, however, can exe-cute other softirqs. If
the same softirq is raised again while it is executing, another
processor can run it simultaneously.
So this declares that interrupts are always enabled.
Now going to pg 143 :
Disable local interrupt delivery (there is no need to first save their state because the code here is always called as a softirq
handler and interrupts are always enabled) and retrieve the
tasklet_vec or tasklet_hi_vec list for this processor
So we can conclude that we dont need to save the IRQ state as we already know its state and it will remain so in all the conditions so we just disable the IRQ and enable it later.

who will pass the control to ISR while cpu is executing BH

Assume that an interrupt is occured in Unicore processor
As a general practice the scheduler is disabled and the cpu is serving the ISR
The ISR disables the current IRQ and schedules the bottom half (tasklet here) for the deferred work.
After ISR is served(IRQ is enabled) and now the processor got the change to serve the scheduled bottom half.
Mean-while again the interrupt is occurred, then the currently running BH is pre-empted and CPU executes the new ISR.
In this case who is responsible for switching the control from BH to ISR
My question is based on assuming that the scheduler is disabled and system is unicore processor.
Passing control to the Interrupt handlers are not done by the process scheduler. This is a hardware mechanism. In x86, The interrupt handling routines are specified by the IDT which the kernel usually setup in the beginning.
If you are really interested in the mechanism, you can further read this and this or your processor architecture's developer manual.

What is channel event system?

I am working on some project Where I have to deal with uc ATxmega128A1 , But being a beginner to a ucontrollers I want to know what is this channel event system regarding ucs.
I have referred a link http://www.atmel.com/Images/doc8071.pdf but not getting it.
The traditional way to do things the channel system can do is to use interrupts.
In the interrupt model, the CPU runs the code starting with main(), and continues usually with some loop. When an particular event occurs, such as a button being pressed, the CPU is "interrupted". The current processing is stopped, some registers are saved, and the execution jumps to some code pointed to by an interrupt vector called an interrupt handler. This code usually has instructions to save register values, and this is added automatically by the compiler.
When the interrupting code is finished, the CPU restores the values that the registers previously had and execution jumps back to the point in the main code where it was interrupted.
But this approach takes valuable CPU cycles. And some interrupt handlers don't do very much expect trigger some peripheral to take an action. Wouldn't it be great it these kinds of interrupt handlers could be avoided and have the mC have the peripherals talk directly to each other without pausing the CPU?
This is what the event channel system does. It allows peripherals to trigger each other directly without involving the CPU. The CPU continues to execute instructions while the channel system operates in parallel. This doesn't mean you can replace all interrupt handlers, though. If complicated processing is involved, you still need a handler to act. But the channel system does allow you to avoid using very simple interrupt handlers.
The paper you reference describes this in a little more detail (but assumes a lot of knowledge on the reader's part). You have to read the actual datasheet of your mC to find the exact details.

running multiple instances of a same interrupt parallely on an SMP system

Is it possible to run multiple instances of a same interrupt simultaneously on a multi processor system in linux?
If not possible, why do we need to synchronize between interrupt handlers using spin locks?
Thanks
Venkatesh
On a SMP architecture Advanced Programmable Interrupt Controller(APIC) is used to route the interrupts from peripherals to the CPU's.
the APIC, based on
1. the routing table (where interrupt affinity is set to a particular processor),
2. priority of the interrupt,
3. the load on the CPU's
For example, consider a interrupt is received at IRQ line 32, this goes through APIC,the interrupt is routed to a particular CPU, for now consider CPU0, this interrupt line is masked until the ISR is handled, which means you will not get a interrupt of the same type if ISR execution is in progress
Once ISR is handled, only then the interrupt line is unmasked for future interrupts
Is it possible to run multiple instances of a same interrupt simultaneously on a multi processor system in linux?
The interrupt handlers are generally serialized. Meaning, that only one instance of the handler would be running(on either of the processors). While this is running, if same type of interrupt is again generated, it is processed only after the current one is done, thus serialized. While "this" handler is being executed by one of the core, other core might service handler of a different instance.
Why do we need to synchronize between interrupt handlers using spin locks?
The spinlocks are used even in such cases as the data has to be protected against some other threads(for example bottom halved, user read/write handler functions, etc).
The scenario could be something like this :
my_ISR()
{
lock(&l);
// data is accessed here
unlock(&l);
}
my_other_thread()
{
lock(&l);
// same data is accessed here
unlock(&l);
}

Resources