Например, enable/disable могут параллельно выполняться. Представь сетевую карту. На одном CPU обработчик прерывания запускает tasklet, на другом в это время выполняется функция закрытия устройства, которая его отключает.
Можно в коде драйвера предусмотреть все возможные случаи, ввести собственные синхронизации, но зачем плодить говно там, где этого можно не делать.
В общем, ладно. Я понял превратно. TC хочет спросить: «если tasklet'ы обрабатываются ksoftirqd, то почему они должны быть interrupt handler - like? Почему в них не может быть мютексов и прочего говна?»
А по-моему, это основной механизм. Я тут посмотрел - мои tasklet'ы вызываются через несколько миллисекунд после tasklet_schedule - как-то многовато для irq path.
Вспоминается еще старый трюк с консолями и задиранием приоритета ksoftirqd.
насколько я понимаю, исторически bh было сделано
для hardirq, теперь этот механизм обобобщен, есть
tasklets. тут я могу ошибаться, я не видел pre-2.6
ядер, но это не важно.
так или иначе, если hardirq handler взводит softirq_pending,
оно будет выполнено из irq_exit() path (забудем про
in_interrupt() для простоты). в этом случае ksoftirqd
будет задействован только если у нас «переполнение»,
см MAX_SOFTIRQ_RESTART. или если он уже running, но это,
опять-таки, автоматически ловится проверкой in_interrupt().
если же ты делаешь, скажем, tasklet_schedule() в process
context, тогда, разумеется, raise_softirq() полагается
на wakeup_softirqd().
мои tasklet'ы вызываются через несколько миллисекунд
после tasklet_schedule
если ты это делаешь из irq - многовато, согласен. один
из _возможных_ ответов, прерванная задача сделала
local_bh_disable(), тогда «точкой вызова» будет парный
local_bh_enable(), и __do_softirq() будет выполнен в
контексте этой задачи.
вообще, мне кажется что все это порядком устарело. без
особой необходимосьти лучше пользоваться queue_work().
>если ты это делаешь из irq - многовато, согласен. один из _возможных_ ответов, прерванная задача сделала local_bh_disable(), тогда «точкой вызова» будет парный local_bh_enable(),
Да, из irq. Но никакой магией с bh я не занимаюсь. Кроме того, задержка стабильна, так что я подозреваю планировщик. Надо будет задрать проритет ksoftirqd и посмотреть, что получится.
вообще, мне кажется что все это порядком устарело.
Я тоже :)
без особой необходимости лучше пользоваться queue_work()
очень странно. ну не может такого быть ;)
у тебя ведь не threaded irq?
даже интересно. я бы попробовал разобраться. для начала,
скажем, тупо напечатать current->pid/comm/preempt_count
перед tasklet_schedule() и из t->func().