2003-01-02 19:03:13

by Bjorn Helgaas

[permalink] [raw]
Subject: [PATCH] Fix CPU bitmask truncation (1 of 2)

The consensus is that this fixes a real bug in 2.4.20. The
rationale is (in Linus' words):

> 1 << cpu

> is clearly an int, and as such will have undefined behaviour for cpu >
> bits-of-int.

> The promotion to unsigned long happens _after_ the shift has already
> happened as an int, since nothing in the sub-expression needs promotion
> per se.

I'll send the initialization patch separately, in case you don't
want that one.

diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c Mon Dec 16 11:58:42 2002
+++ b/kernel/sched.c Mon Dec 16 11:58:42 2002
@@ -116,7 +116,7 @@

#define idle_task(cpu) (init_tasks[cpu_number_map(cpu)])
#define can_schedule(p,cpu) \
- ((p)->cpus_runnable & (p)->cpus_allowed & (1 << cpu))
+ ((p)->cpus_runnable & (p)->cpus_allowed & (1UL << cpu))

#else

@@ -359,7 +359,7 @@
if (task_on_runqueue(p))
goto out;
add_to_runqueue(p);
- if (!synchronous || !(p->cpus_allowed & (1 << smp_processor_id())))
+ if (!synchronous || !(p->cpus_allowed & (1UL << smp_processor_id())))
reschedule_idle(p);
success = 1;
out: