Re: Killing tasklet from interrupt

Jean Tourrilhes (jt@bougret.hpl.hp.com)
Mon, 18 Mar 2002 15:33:47 -0800


On Mon, Mar 18, 2002 at 03:20:50PM -0800, Maksim Krasnyanskiy wrote:
>
> > > You have the tasklet kill itself the next time it executes. Set some
> > > flag so it knows it should give up its timer-slot and expire. The
> > > interrupt sets the flag. It doesn't do anything else.
> >
> > I already have this flag and my code mostly work like this, so
> >that would be trivial to do.
> > I looked at the code, and you are right, killing the tasklet
> >within itself is by far the safest way to do it.
> Sounds like what you need is tasklet_disable.
> tasklet_kill needs process context so you can't use it in timer.
>
> >It's a shame that the code doesn't explitely allow for it (i.e. you will
> >deadlock every time
> >in tasklet_unlock_wait(t);).
> Use tasklet_disable_nosync within the tasklet itself.
>
> Max

Well. I thought about that. Not possible.
tasklet_disable is not the answer, because if the tasklet was
scheduled, it will stay forever in the tasklet queue. Also, I need to
forget forever about getting rid of the tasklet within the tasklet
itself, because it will just crash.
Look below, comments by me (you've got to love uncommented
code). So, it's not today that I will use tasklets.

Regards,

Jean

P.S. : By the way, regarding flow control between TCP and netdevice
(our previous e-mail exchange with Paul), have you investigated the
effect of skb->destructor; (for example sock_wfree()).

-------------------------------------------------------------

static void tasklet_action(struct softirq_action *a)
{
int cpu = smp_processor_id();
struct tasklet_struct *list;

local_irq_disable();
list = tasklet_vec[cpu].list;
tasklet_vec[cpu].list = NULL;
local_irq_enable();

while (list) {
struct tasklet_struct *t = list;

list = list->next;

if (tasklet_trylock(t)) {
if (!atomic_read(&t->count)) {
if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
BUG();
// Call tasklet handler
t->func(t->data);
// If tasklet was killed/destroyed/kfree above, we will die
tasklet_unlock(t);
continue;
}
tasklet_unlock(t);
}

// Tasklet is disabled, put back in tasklet queue
local_irq_disable();
t->next = tasklet_vec[cpu].list;
tasklet_vec[cpu].list = t;
__cpu_raise_softirq(cpu, TASKLET_SOFTIRQ);
local_irq_enable();
}
}

-
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/