2
votes

As I know, we can verify that we are in interrupt context by involving in_interrupt() in linux kernel. And the implementation of the in_interrupt() function is counting by the thread_info->preempt_count when entering or exiting hardirq or softirq. So, when the in_interrupt() return none-zero, it indicates that we are processing in hardirq or softirq.

However, My question is when we involve the local_bh_disable() function, it does increase the thread_info->preempt_count, so the in_interrupt() function return none-zero. Thus, how could we determine if we are in the interrupt context now. And in my opinion, atomic context is that local interrupt is disabled

Here is a circumstances that I'm now in kernel mode, and I want to access the userland address space, but I don't know whether running in the process context or interrupt context, because of accessing userland address space in interrupt context is invalid, so I want to determine whether being in the process context by involving the in_interrupt() function. Then I got the return value greater than zero, thus, I will think that I am now in interrupt context and won't access the userland. However, maybe there are some function that imply involving the local_bh_disable to increase the thread_info->preempt_count to disable the sortirq, but in fact that, we are in process context and just disabling the softirq, thus, we could access the userland address space safely but we make a mistake.

2

2 Answers

2
votes

There are several interesting functions in preempt_mask.h:

  • in_irq(): hardware interrupt
  • in_softirq(): Are we in a softirq context?
  • in_interrupt(): Interrupt context?
  • in_nmi(): Are we in NMI context?
  • in_atomic(): Are we running in atomic context? WARNING: this macro cannot always detect atomic context

Please note that in normal circumstances, a driver should not need to use any of these functions.

1
votes

I think in_interrupt() is a BAD design!

If your codes ruuning in process context, you did not need to invoke in_interrupt().

in_serving_softirq() indicates you are in real softirq context do_softirq() not local_bh_disable().