lkml.org 
[lkml]   [2003]   [Aug]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: tasklet_kill will always hang for recursive tasklets on a UP
    > Hi,
    > While going thru the code for tasklet_kill(), I cannot figure out
    > how recursive tasklets (tasklets that schedule themselves from within
    > their tasklet handler) can be killed by this function. To me it looks that
    > tasklet_kill will never complete for such tasklets.

    It is realy a sophisticated piece of code! I think it is not
    the only bug you found. Some weeks ago I pointed out another
    problem with tasklet_kill but got no answer.

    To work our questions out is not done in just 1 minute :-(
    And I was not able to find the person, who is responsible for the code.

    As far as I can see, you missed nothing.
    The tasklet enters itself to the "task_vec" list, because the
    SCHED-Bit is always resetted, when "tasklet_schedule" is called.
    It will always succeed.

    Maybe you have a look to another (my) problem:

    The function "tasklet_schedule" schedules a tasklet only, if the SCHED-Bit
    ist _not_ set. So the trick is, to _set_ the SCHED-Bit and
    to _not_ enter the tasklet in the "task_vec" list (ok, you showed
    that this trick can fail). But anyway, if you look at the
    code, tasklet_kill resets the bit in any case!!! It would have to
    set the bit, not to reset it. Any comments?

    void tasklet_kill(struct tasklet_struct *t)
    {
    ...
    while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
    do
    yield();
    while (test_bit(TASKLET_STATE_SCHED, &t->state));
    }
    tasklet_unlock_wait(t);
    clear_bit(TASKLET_STATE_SCHED, &t->state);
    }


    > void tasklet_kill(struct tasklet_struct *t)
    > {
    > ...
    > ...
    > while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
    > current->state = TASK_RUNNING;
    > do
    > sys_sched_yield();
    > while (test_bit(TASKLET_STATE_SCHED, &t->state));
    > }
    > ...
    > ...
    > }
    >
    > The above while loop will only exit if TASKLET_STATE_SCHED is not set
    > (tasklet is not scheduled).
    > Now if we see tasklet_action
    >
    > static void tasklet_action(struct softirq_action *a)
    > {
    > ...
    > ...
    > if (!atomic_read(&t->count)) {
    > --> TASKLET_STATE_SCHED is set here
    > if(!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
    > BUG();
    > t->func(t->data);
    > --> if we schedule the tasklet inside its handler,
    > --> TASKLET_STATE_SCHED will be set here also
    > tasklet_unlock(t);
    > continue;
    > }
    > ...
    > ...
    > }
    >
    > The only small window when TASKLET_STATE_SCHED is not set is between the
    > time when test_and_clear_bit above clears it and by the time the tasklet
    > handler again calls tasklet_schedule(). But since tasklet_kill is called
    > from user context the while loop in tasklet_kill checking for
    > TASKLET_STATE_SCHED to be cleared cannot interleave between the above two
    > lines in tasklet_action and hence tasklet_kill will never come out of the
    > while loop.
    > This is true only for UP machines.
    >
    > Pleae point me out if I am missing something.
    >
    > Thanx
    > tomar
    >
    >
    > -
    > 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/
    >
    -
    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/

    \
     
     \ /
      Last update: 2005-03-22 13:48    [W:0.024 / U:0.988 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site