2

Proper Locking Under a Preemptible Kernel: Keeping Kernel Code Preempt-Safe article says,

But keep in mind that 'irqs disabled' is a fundamentally unsafe way of disabling preemption - any spin_unlock() decreasing the preemption count to 0 might trigger a reschedule. A simple printk() might trigger a reschedule.

If IRQs are disabled, then the timer interrupt should be disabled on that CPU core as well. Naturally, it should disable the scheduler (preemption) in turn. Why is calling irqs disabled() an unsafe way to disable preemption?

Moreover, how might printk() trigger a reschedule?

4

Yes, if IRQs are disabled, the timer interrupt is disabled and task scheduling no longer occurs. The unsafe part is the “if”: if you’re relying on disabled IRQs, you need to be absolutely sure that all the code you run with IRQs disabled respects that. That can be quite difficult in the kernel since spinlocks disable and enable pre-emption themselves (along with IRQs in some cases), and many pieces of code use locks, including printk (to ensure that log messages don’t get mixed up). Any time a lock is released, you risk a reschedule (to run code that was waiting on the lock), even if IRQs are disabled: preempt_enable() explicitly calls __preempt_schedule() when its counter reaches zero, so no timer interrupt is required.

It’s thus safer to use the proper pre-emption support functions, especially in terms of future-proofing: you might be well aware of the constraints in the code you’re writing now, but someone else changing it won’t (and “someone else” includes “you in six months’ time”).

  • ...many pieces of code use locks, including printk (to ensure that log messages don’t get mixed up). Any time a lock is released, you risk a reschedule. However releasing a lock doesn't enable IRQ, isn't it? Unless IRQ is enabled, how can timer interrupt kick in? – Holmes.Sherlock Feb 6 '18 at 20:35
  • I guess the real bummer is printk() can enable IRQ as well: elixir.free-electrons.com/linux/v4.11/source/kernel/printk/… – Holmes.Sherlock Feb 6 '18 at 20:38
  • According to the quoted remark in the original post, ...any spin_unlock() decreasing the preemption count to 0 might trigger a reschedule. Even if preempt_count becomes zero, how can it trigger a reschedule if IRQs are disabled? – Holmes.Sherlock Feb 6 '18 at 21:03
  • 1
    Scheduling can happen without the timer interrupt: preempt_enable will force a reschedule if necessary. – Stephen Kitt Feb 9 '18 at 9:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.