6

http://lxr.linux.no/linux+v2.6.35/include/linux/preempt.h#L21

I am just trying get the linux source. I saw this preempt count and how does linux ensure the preempt count is atomic ? The code just increments the value.

Also I have an another question. why does interrupt handles need to maintain mutual exclusion. Because only one can execute at a time right ?

Also when interrupts are disabled what does OS do ? Ignore interrups or maintain a queue ?

mousey
  • 11,601
  • 16
  • 52
  • 59

3 Answers3

8

It increments preempt_count() - notice the () - which is a macro is defined as:

#define preempt_count() (current_thread_info()->preempt_count)

So it is incrementing a per-thread variable, which doesn't require any locking and is safe.


It's best to ask your multiple questions as separate questions, but briefly:

  • Interrupt handlers can in general be interrupted by other interrupt handlers;
  • Interrupt handlers can run on one CPU core while other kernel code is running on another core;
  • Interrupts are usually disabled using a hardware mechanism. These tend to remember pending interrupts, but only up to a maximum of one per interrupt vector.
caf
  • 233,326
  • 40
  • 323
  • 462
  • Thank you very much. can you pls answer my next questions too pls. – mousey Sep 03 '10 at 01:08
  • @caf, and mousey: If the inc/dec is also called by fault handlers or interrupt handlers, would it be safe? Or is there any rules saying that can not be done? Ideas? – minghua May 26 '13 at 01:55
  • @minghua: It's not allowed to be accessed in interrupt context - it makes no sense to do so anyway. – caf May 26 '13 at 14:55
  • @caf: That's my understanding too. But look at "netif_rx()", at the end it calls "put_cpu()" which in turn calls "preempt_enable()". Also "spin_unlock_irqrestore()" is often used in interrupt handlers, it does increment the preempt_count. Am I reading the code right? I'm looking at when CONFIG_PREEMPT is enabled. – minghua May 29 '13 at 02:00
  • Looking around I believe the count is operated by fault handlers and interrupt handlers too. Since fault handlers and interrupt handlers are strictly nested by design thus they do not cause a corruption to the count value. The handlers in interrupt context just use the count on whatever current thread is as long as the current thread cannot be switched till the handlers all return. Given this, the read-modify-write operation is not really atomic. It guarantees after the R-M-W finishes no more context switch will occur till the pairing "preempt_disable()" and till the count reaches zero. – minghua May 29 '13 at 15:50
2

The operation on the preempt_count variable is not atomic. The code region between an inc and a dec of a preempt_count of a thread is guaranteed not to be switched out by the scheduler. Context switching from the current thread in this code region can only happen in further embedded exceptions or interrupts. After the first inc operation completes, the further handlers will see the variable is non-zero thus not to cause a context switch. Before the inc finishes the thread can be switched out but that's ok as the code has not reached the guarded region.

Some details: The definition of an atomic variable should be something like "Atomic variables are the ones on whom the read modify write operation is done as one instruction with out any interruption". The "Read-Modify-Write" operation on a preempt_count can be interrupted by another exception handler or interrupt handler but only in strictly embedded manner, that's by the kernel design. Since those embedded operations are in pairs, thus the value of a preempt_count will not be corrupted eventually. Though a R-M-W operation can be interrupted and the current thread can be switched out (only if none of the multiple embedded inc has completed), but that is ok as the code has not reached the guarded region. Once the thread is switched back it will continue finish the R-M-W operation and from that point on the current thread will not be switched out till all the paired dec(s) all finish.

minghua
  • 5,981
  • 6
  • 45
  • 71
0

Every modern processor has some variant of the atomic test-and-set instruction.

msw
  • 42,753
  • 9
  • 87
  • 112