0

Im looking at this macro from the linux kernel which has to do with handling cpu-specific variables

#define get_cpu_var(var)                                                \
(*({                                                                    \
        preempt_disable();                                              \
        this_cpu_ptr(&var);                                             \
})) 

Why do we disable preemption? Isnt preemption something that cant happen when you are in the kernel? (Since the kernel is the one doing the preemption)

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
tomer.z
  • 1,033
  • 1
  • 10
  • 25

1 Answers1

3

Why do we disable preemption?

To avoid having the thread preempted and rescheduled on a different processor core.

Isnt preemption something that cant happen when you are in the kernel?

This was true when there was still a big kernel lock. Having one global lock means that if you block in-kernel, no other thread may enter the kernel. Now, with the more fine-grained locking, sleeping in the kernel is possible. Linux can be configured at build-time for other preemption models, e.g. CONFIG_PREEMPT.

While your normal desktop kernel is probably configured with CONFIG_PREEMPT_VOLUNTARY, some distributions also ship CONFIG_PREEMPT as a separate low-latency kernel package, e.g. for audio use. For real-time use cases, The preempt_rt patchset even makes most spinlocks preemptible (hence the name).

a3f
  • 8,517
  • 1
  • 41
  • 46
  • I see, last time I was working on the linux kernel was in version 2.6 or 2.4, so that was the case in older versions right (no preemption), it just changed for the newer ones right? – tomer.z Mar 21 '18 at 19:43
  • @tomer.z Linux v2.6.39 removed the big kernel lock. Whether your kernel is preemptible depends on configuration, if you are using a normal Desktop distribution's kernel, it should be configured with `CONFIG_PREEMPT_VOLUNTARY`. The non-voluntary preemption ones are geared towards audio or real-time usage. – a3f Mar 21 '18 at 19:48
  • So how exactly does that work? Im a user space thread, im running then making a syscall, so I get jumped to the kernel, running there doing stuff, so why would I suddenly get preempted when Im in the kernel? Because my time slice ran out? If so how am I preempted? Handler of a clock interrupt that fires when a time slice runs our or...? @a3f – tomer.z Mar 21 '18 at 20:55
  • @tomer.z Voluntary preemption = There are preemption points throughout the kernel (`might_sleep`). Forcible preemption = each interrupt (including timer interrupts when time slices run out) is a possible preemption point. – a3f Mar 21 '18 at 21:09
  • And does `preempt_disable();` prevent force preemption? The way I remember it from when the kernel had a big lock is while you are running in the kernel you cant be preempted at all, and when you finish your business and about to go back to user space your time slice is checked and if its done you go to another process instead of back to user space, so Im trying to understand how this dynamic work now @a3f – tomer.z Mar 21 '18 at 21:13
  • Yes, `preempt_disable` disables preemption if the kernel is preemptible. – a3f Mar 21 '18 at 21:17
  • Meaning that if I dont call `preempt_disable` a thread running in the kernel can be preempted if, for example, the user space process's time slice runs out? Even if I am mid-function inside the kernel? – tomer.z Mar 21 '18 at 21:23
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/167295/discussion-between-a3f-and-tomer-z). – a3f Mar 21 '18 at 21:24