3

I read some related posts:

(1) From Robert Love: http://permalink.gmane.org/gmane.linux.kernel.kernelnewbies/1791

You cannot sleep in an interrupt handler because interrupts do not have a backing 
process context, and thus there is nothing to reschedule back into. In other 
words, interrupt handlers are not associated with a task, so there is nothing to 
"put to sleep" and (more importantly) "nothing to wake up". They must run 
atomically.

(2) From Which context are softirq and tasklet in?

If sleep is allowed, then the linux cannot schedule them and finally cause a 
kernel panic with a dequeue_task error. The interrupt context does not even 
have a data structure describing the register info, so they can never be scheduled 
by linux. If it is designed to have that structure and can be scheduled, the 
performance for interrupt handling process will be effected.

So in my understanding, interrupt handlers run in interrupt context, and can not sleep, that is to say, can not perform the context switch as normal processes do with backing mechanism.

But a interrupt handler can be interrupted by another interrupt. And when the second interrupt handler finishes its work, control flow would jump back to the first interrupt handler.

How is this "restoring" implemented without normal context switch? Is it like normal function calls with all the registers and other related stuff stored in a certain stack?

Community
  • 1
  • 1
feirainy
  • 497
  • 1
  • 4
  • 11
  • 1
    Robert Love: *...because interrupts do not have _a backing process context_* and Softirq/tasklet: *the interrupt context does not even have a **data structure** describing the register info*. In both cases, the technical description would be they do not have a `thread_info`, a `task_struct` or a `struct mm`. You need a `task_struct` to be scheduled. Interrupts, etc free ride in the `thread_info` as a *stack* that stacks the kernel contexts. – artless noise Dec 23 '13 at 16:39

3 Answers3

7

The short answer is that an interrupt handler, if it can be interrupted by an interrupt, is interrupted precisely the same way anything else is interrupted by an interrupt.

Say process X is running. If process X is interrupted, then the interrupt handler runs. To the extent there is a context, it's still process X, though it's now running interrupt code in the kernel (think of the state as X->interrupt if you like). If another interrupt occurs, then the interrupt is interrupted, but there is still no special process context. The state is now X->first_interrupt->second_interrupt. When the second interrupt finishes, the first interrupt will resume just as X will resume when the first interrupt finishes. Still, the only process context is process X.

You can describe these as context switches, but they aren't like process context switches. They're more analogous to entering and exiting the kernel -- the process context stays the same but the execution level and unit of code can change.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • So the "context" like registers of the first interrupt handler is stored in the kernel stack when interrupted by the second interrupt, just like the way process X is interrupted by the first interrupt. – feirainy Dec 23 '13 at 07:00
  • @feirainy Exactly. Yes. The process context is hijacked (or 'borrowed' if you like) by the interrupt handler rather than switched. This keeps the cost of interrupts low. – David Schwartz Dec 23 '13 at 08:19
1

The interrupt routine will store some CPU state and registers before enter real interrupt handler, and will restore these information before returning to interrupted task. Normally, this kind of storing and restoring is not called context-switch, as the context of interrupted process is not changed.

Chris Tsui
  • 452
  • 3
  • 10
0

As of 2020, interrupts (hard IRQ here) in Linux do not nest on a local CPU in general. This is at least mentioned twice by group/maintainer actively contributing to Linux kernel:

From NAPI updates written by Jakub Kicinski in 2020:

…Because normal interrupts don't nest in Linux, the system can't service any new interrupt while it's already processing one.

And from Bootlin in 2022:

…Interrupt handlers are run with all interrupts disabled on the local CPU…

So this question is probably less relevant nowadays, at least for Linux kernel.

07 0xff
  • 11
  • 2