tasklet race condition

From: Jeff DeFouw (defouwj@purdue.edu)
Date: Wed Feb 23 2000 - 00:31:27 EST


Somehow a tasklet can be mysteriously dropped from the tasklet queue list.
Tests were done in 2.3.47 SMP but the effects are felt back to 2.3.43 SMP.

I put some debugging messages into tasklet_hi_schedule (in this case
called from mark_bh). With very frequent calls to tasklet scheduling a
task may be marked TASKLET_STATE_SCHED but disappear from the tasklet
queue before ever being launched. It remains stuck in that condition. I
attached an else to the test_and_set_bit condition test in
tasklet_hi_schedule and had the function search the list for the status of
the task. I'll keep looking for the source of the problem, but I don't
know too much about the locking mechanisms so I'm not likely to get there
very fast. Does anyone have any comments on this?

I get these from my code even after several seconds of letting the module
keep trying to mark_bh(IMMEDIATE_BH) and wait. 9 out of 10 times the
tasklet never runs, and the other time it only runs once or twice.

Feb 22 23:18:57 wily-c-053 kernel: bh BUG: task scheduled but not on list!
Feb 22 23:18:57 wily-c-053 kernel: bh BUG: unlisted task is IMMEDIATE_BH!

extern __inline__ void tasklet_hi_schedule(struct tasklet_struct *t)
{
        if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
                int cpu = smp_processor_id();
                unsigned long flags;

if (t->func == bh_action && t->data == IMMEDIATE_BH)
printk(KERN_DEBUG "tasklet_hi_schedule: IMMEDIATE_BH\n");
                local_irq_save(flags);
                t->next = tasklet_hi_vec[cpu].list;
                tasklet_hi_vec[cpu].list = t;
                __cpu_raise_softirq(cpu, HI_SOFTIRQ);
                local_irq_restore(flags);
        }
else {
int cpu = smp_processor_id();
unsigned long flags;
struct tasklet_struct *chain;
int found = 0;

local_irq_save(flags);
chain = tasklet_hi_vec[cpu].list;
while (chain != NULL) {
 if (chain->func == t->func && chain->data == t->data)
  found = 1;
 chain = chain->next;
}
if (!found) {
 printk(KERN_DEBUG "bh BUG: task scheduled but not on list!\n");
 if (t->func == bh_action && t->data == IMMEDIATE_BH)
   printk(KERN_DEBUG "bh BUG: unlisted task is IMMEDIATE_BH!\n");
}
local_irq_restore(flags);
}
}

--
Jeff DeFouw <defouwj@purdue.edu>

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



This archive was generated by hypermail 2b29 : Wed Feb 23 2000 - 21:00:32 EST