Reputation: 557
I am looking at scheduler code in Linux:
if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
if (unlikely(signal_pending_state(prev->state, prev))) {
prev->state = TASK_RUNNING;
} else {
deactivate_task(rq, prev, DEQUEUE_SLEEP);
prev->on_rq = 0;
As I understand, if the prev
task is uninterruptible, this code will deactivate the task (and remove from runqueue) provided
preempt_count() & PREEMPT_ACTIVE == 0
Can someone explain to me what is preempt_count
in thread_info
for and when will this condition met or not?
Upvotes: 4
Views: 1661
Reputation: 1142
preempt_count
is the counter used by preempt_disable()
and preempt_enable()
, which enables their nested use. Higher order bits of preempt_count
are used for hardirq and softirq counters, an NMI bit and a PREEMPT_ACTIVE
bit. These are defined in include/linux/preempt_mask.h
. In x86 architectures a PREEMPT_NEED_RESCHED
bit is also used in preempt_count
, for optimization of deciding to reschedule.
Now, I am not clear on the exact need for the PREEMPT_ACTIVE
bit in preempt_count
. In kernel version 3.17, which I have worked on, PREEMPT_ACTIVE
is set in preempt_count
exactly before calling __schedule()
and reset immediately after the call, in all cases, except when it is called from schedule()
. This would mean, inside __schedule()
, PREEMPT_ACTIVE
is set in preempt_count
, when __schedule()
was called because of kernel preemption, i.e., not intentionally for some other OS functionality, which would use schedule()
. What would such "other OS functionality" be varies, depending on whether you build the kernel with CONFIG_PREEMPT
, CONFIG_PREEMPT_VOLUNTARY
, or CONFIG_PREEMPT_NONE
, but it includes explicit blocking on a mutex.
Upvotes: 1