How Tasklets works? - linux

Does interrupts are disabled while tasklets are being processed since they should run in interrupt context.If they are disbled while a tasklet is being processed then what is the point of calling them bottom halve mechanism since it is same case as top of where the interrupts are disabled.
Or is it like tasklets will be useful only on multi processor system where the interrupts are generated on one processor and the corresponding tasklet is scheduled on another processor with interrupts being disbled on another processor when the tasklet is running.
Please clarify.

Linux divides interrupt processing in two parts:
First, you handle the interrupt request (IRQ) in as simple a manner as possible, doing as little as you can, and scheduling a softirq/tasklet to do the heavier part of the processing.
Then, the softirq/tasklet gets scheduled, and the heavy processing starts.
The contexts in Linux are:
NMI context
hardirq context: the first part of interrupt processing above.
softirq context: the second part of interrupt processing above.
interrupt context: any of the above.
process/user context: running on behalf of a process, e.g: due to a syscall. The opposite of interrupt context.
atomic context: interrupt context, or in process context in a section of code that must be atomic (cannot be interrupted), e.g: because we have taken a spinlock.
Interrupts are not disabled while running a tasklet. Further invocations of the same tasklet are.

Related

Exactly when tasklet runs after it is schedule by ISR?

I written my ISR and my tasklet ran immediately. BUT, I have seen people saying that tasklet runs only when it gets CPU attention. This is a very generic term CPU attention so i recite for those responders. I mean exactly which moment cpu attention goes to tasklet execution and what happen to the state of CPU ?
Secondly, if suppose that i am keep on getting hard interrupt then when will tasklet get chance to run? Is it possible that tasklet may not get chance to run? How does kernel take care these things ?
TL;DR: Tasklets are run by ksoftirq threads who are handled by Scheduler.
Tasklet is just a form of softirq (it is handled by them with TASKLET_SOFTIRQ priority), so rules on when running tasklets applies to them. Here they are according to Robert Love's book "Linux Kernel
Development":
In the return from hardware interrupt code path
In the ksoftirq kernel thread
In any code that explicitly checks for and executes pending softirqs, such as the networking subsystem
It seems that case (1) will not work if threadirqs=true (kernel boot parameter) which is default value.
UPD: Some notes on ksoftirq relation with Scheduler.
That is what seem to happen:
In hardirq handler you wake up ksoftirq (due to tasklet_schedule())
Thus wake_up_process() checks if ksoftirq may preempt current thread
If (2) is true TIF_NEED_RESCHED flag is set
On the return from hardirq (ret_from_intr - in x86) TIF_NEED_RESCHED flag is checked
If (4) is true, schedule() is called trying to pick next thread to be executed.
There is high chance that ksoftirq will be considered as preempt candidate in (2-3) and it will be picked in (5), but if there are competitors, ksoftirq have to wait till next schedule() cycle - current thread surrenders (i.e. sleeping), clock tick happens, syscall or new interrupt.

What will happen to the state of the tasklet when tasklet is running and hardware interrupt triggered?

What will happen to the state of the tasklet when tasklet is executing and hardware interrupt triggered in the middle of tasklet execution ?
Tasklet are the bottom half. They run in softirq context and not in hardware interrupt context. So hardware interrupts are always enabled. When hardware interrupts is triggered while executing tasklets then it will interrupt the tasklet. Then top half is run on the respective IRQ stack and acknowledge the interrupt. This behavior is especially useful with interrupt handlers, where the hardware interrupt must be managed as quickly as possible, but most of the data management can be safely delayed to a later time. Actually, a tasklet, just like a kernel timer, is executed (in atomic mode) in the context of a soft interrupt, a kernel mechanism that executes asynchronous tasks with hardware interrupts enabled.
Check tasklet_schedule function.
It will save the state of the interrupt system and restore interrupts to their previous state and return after do_softirq operation.
Tasklets run in interrupt context. So code in tasklets should not sleep (or be interrupted). If the tasklet is interruped by an interrupt, your system crashes. To prevent interrupts while running tasklet you have to prevent the interrupts by using spinlock_irq_save()

what will happen to tasklet execution if interrupt occurs in between

The things I know about tasklet:
Tasklet runs with all interrupt enabled.
The tasklet runs in interrupt context.
It can't be sleep.
It runs in atomic way.
it has the assurance to be scheduled never late than next tick.
My questions:
Since in bottom half all interrupts are enabled, what happened If a tasklet is running and in between any interrupt comes. (If interrupts are disabled during tasklet execution then what is the benefit of tasklet)?
Why is the surety that tasklet will always be scheduled upto next tick?
Is it correct to say that tasklets are softirq with priority level 0(Hi priority tasklet) and priority level 6(Normal taslet)?
*Since in bottom half all interrupts are enabled, what happened If a tasklet is running and in between any interrupt comes. (If interrupts are disabled during tasklet execution then what is the benefit of tasklet)?*
From what i understand Tasklet (which is built on soft IRQ) runs in soft IRQ context which essentially means it runs in context of whatever process was running when the process was interrupted by Hard IRQ (so it is borrowing stack) , so an interrupt again would return back to tasklet execution.
*Is it correct to say that tasklets are softirq with priority level 0(Hi priority tasklet) and priority level 6(Normal taslet)?*
Yes tasklets are essentially wrappers built on Soft IRQ.

Linux Interrupts Concurency

Are interrupts executed on all processors, or only on one?
For instance, when I type, do all processors handle the interrupt? Or only one of them and the rest carry on with other taks?
Here's a high-level view of the low-level processing. I'm describing a simple typical architecture, real architectures can be more complex or differ in ways that don't matter at this level of detail.
When an interrupt occurs, the processor looks if interrupts are masked. If they are, nothing happens until they are unmasked. When interrupts become unmasked, if there are any pending interrupts, the processor picks one.
Then the processor executes the interrupt by branching to a particular address in memory. The code at that address is called the interrupt handler. When the processor branches there, it masks interrupts (so the interrupt handler has exclusive control) and saves the contents of some registers in some place (typically other registers).
The interrupt handler does what it must do, typically by communicating with the peripheral that triggered the interrupt to send or receive data. If the interrupt was raised by the timer, the handler might trigger the OS scheduler, to switch to a different thread. When the handler finishes executing, it executes a special return-from-interrupt instruction that restores the saved registers and unmasks interrupts.
The interrupt handler must run quickly, because it's preventing any other interrupt from running. In the Linux kernel, interrupt processing is divided in two parts:
The “top half” is the interrupt handler. It does the minimum necessary, typically communicate with the hardware and set a flag somewhere in kernel memory.
The “bottom half” does any other necessary processing, for example copying data into process memory, updating kernel data structures, etc. It can take its time and even block waiting for some other part of the system since it runs with interrupts enabled.

Can an interrupt handler be preempted?

I know that linux does nested interrupts where one interrupt can "preempt" another interrupt, but what about with other tasks.
I am just trying to understand how linux handles interrupts. Can they be preempted by some other user task/kernel task.
Reading Why kernel code/thread executing in interrupt context cannot sleep? which links to Robert Loves article, I read this :
some interrupt handlers (known in
Linux as fast interrupt handlers) run
with all interrupts on the local
processor disabled. This is done to
ensure that the interrupt handler runs
without interruption, as quickly as
possible. More so, all interrupt
handlers run with their current
interrupt line disabled on all
processors. This ensures that two
interrupt handlers for the same
interrupt line do not run
concurrently. It also prevents device
driver writers from having to handle
recursive interrupts, which complicate
programming.
So AFIK all IRQ's are disabled while within the interrupt handler, therefore it cannot be interrupted!?
Simple answer: An interrupt can only be interrupted by interrupts of higher priority.
Therefore an interrupt can be interrupted by the kernel or a user task if the interrupt's priority is lower than the kernel scheduler interrupt priority or user task interrupt priority.
Note that by "user task" I mean user-defined interrupt.

Resources