LINUX.ORG.RU

Обработчик NF_IP_LOCAL_IN для нетфильтра


0

0

Добрый день. Пишу некий хук для нетфильтра(ядро 2.6.10 на однопроцессорной системе), который занимается декодированием пришедших по сети данных. Тип хука NF_IP_LOCAL_IN. Насколько я понимаю хук выполняется из softirq (NET_RX_SOFTIRQ net_rx_action), соответственно в момент выполнения отключено вытеснение (как видим в функции ksoftirqd). Так как декодирование достаточно долгое, и эксперименты показали что иногда функция декодирования приводит к тому что мы начинаем терять пакеты в бэклог, было решено вынести декодер в отдельный поток(условно поток ядра B). Теперь происходит следующее, сам хук просто берет данные из sk_buff и кладет их в некий буфер, которые в дальнейшем обработает поток B. Следовательно необходимо синхронизировать доступ к буферу (использую спинлоки). Насколько я поняла на однопроцессорной системе макрос spin_lock просто отключает вытеснение (preempt_disable), соответственно мы не можем делать вызовы которые могут привести к засыпанию треда внутри лока.

А теперь вопрос. Если поток B захватил spinlock, может ли его каким либо образом вытеснить ksoftirqd и обработать softirq? Единственное место получается где это может произойти, (с учетом того что и в потоке B и в хуке нет переключения контекста) это возврат из обработки аппаратного прерывания. Но если посмотреть на код (ret_from_intr для i386, для всех остальных архитектур наверно также?) то мы видим следующее:

ENTRY(resume_kernel)
    cmpl $0,TI_preempt_count(%ebp)  # non-zero preempt_count ? 
    jnz restore_all

то есть проверка какая-то все-таки есть, следовательно вытеснить наш поток B обработчик softirq все-таки не может?

Правильно ли я понимаю принцип работы?



Последнее исправление: irishka (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.