Messages in this thread | | | Date | Tue, 19 Mar 2002 11:41:18 -0800 | From | Maksim Krasnyanskiy <> | Subject | Re: Killing tasklet from interrupt |
| |
> > 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. > > 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. How about something like this ?
void tasklet_kill_from_interrupt(struct tasklet_struct *t) { while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)); tasklet_unlock_wait(t); }
So, in your timer you would do: set_bit(CLOSING_PLEASE_DONT_SCHEDULE_ANYTHING, something->state); tasklet_kill_from_interrupt(something->tasklet); /* cleanup/kfree/etc */
> Look below, comments by me (you've got to love uncommented >code). So, it's not today that I will use tasklets. Well, I use them without any problems in Bluetooth code. May be you should redesign your code a bit. For example don't kill tasklets from the timer.
>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()). I'm sorry I must have missed skb->destructor part. How sock_wfree could affect flow ctl between TCP and netdev ? sock_wfree just wakes up process sleeping in sock_alloc_send_skb or alike.
>------------------------------------------------------------- > >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); > } "kill" means "wait until tasklet terminates and is not in the queue". So it's not a problem And you would not want to destroy _locked_ tasklet. You'd wait until it's unlocked.
Max
- 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/
| |