Re: [PATCH] preemptive kernel behavior change: don't be rude

Roger Larsson (roger.larsson@norran.net)
Fri, 5 Apr 2002 22:03:09 +0200


Hi Robert,

This does not look symmetrical, add and sub and bitops...

> +#define PREEMPT_ACTIVE 0x4000000

> + /*
> + * if entering from preempt_schedule, off a kernel preemption,
> + * go straight to picking the next task.
> + */
> + if (unlikely(preempt_get_count() & PREEMPT_ACTIVE))
> + goto pick_next_task;
> +

> + do {
> + current_thread_info()->preempt_count += PREEMPT_ACTIVE;
> + schedule();
> + current_thread_info()->preempt_count -= PREEMPT_ACTIVE;
> + barrier();

And since it has to be zero to end up in the routine anyway...

asmlinkage void preempt_schedule(void)
{
BUG_ON(current_thread_info()->preempt_count != 0);

do {
/* Problem: suppose a new interrupt happens before we got to set
* preempt_count... then we will call this routine recursively.
* innermost will select the correct process, but wont it be scheduled
* away in enclosing preempt_schedule() - schedule() will be called
* with PREEMPT_ACTIVE but not TIF_NEED_RESCHED...
* (goto pick_next_task) */

current_thread_info()->preempt_count = PREEMPT_ACTIVE;

/* interrupts here might cause calls to preempt_schedule() but those will
bounce off above since preempt_count != 0 */

schedule();
current_thread_info()->preempt_count = 0;

/* interrupt here will possibly preempt the right process - no problem */

/* need to check if any interrupt happened during the preemption off time,
* this case is in fact unlikely */
while (unlikely(test_thread_flag(TIF_NEED_RESCHED)));
}

/RogerL

-- 
Roger Larsson
Skellefteċ
Sweden

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/