Saksham Jain
Saksham Jain

Reputation: 557

When does preempt_count() & PREEMPT_ACTIVE == 0?

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

Answers (1)

kavadias
kavadias

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

Related Questions