Предоставить пример минимального кода будет сложно, но я предоставлю некоторый sudo-код, который, надеюсь, поможет понять точку / вопрос.
TL; DR: Моя рабочая очередь запускается, прерывается, а затем никогда не заканчивается, вызываязависание процессора.
Я создаю сетевой драйвер для устройства PCIe.Для языка Tx = host out, Rx = host in. Для Tx стороны я использую рабочие очереди (work_struct).Итак.
ndo_start_xmit(){
//Perform some operations and load a DMA.
}
request_irq(irq_handler);
INIT_WORK(work,work_handler);
irq_handler(){
//Check what caused the IRQ
if(ndo_xmit_dma caused irq){
schedule_work(work);
}
}
work_handler(){
if(xmit_called){
spin_lock()
//Do some stuff
spin_unlock()
}
}
Тогда для стороны Rx это похоже, но теперь использует NAPI вместо workqueue, потому что я учусь и, честно говоря, могу перевести всю работу в napi (пожалуйста, укажите, решит ли это проблему).
irq_handler(){
if(Rx caused the irq){
napi_schedule();
}
}
//Do a bunch of napi releated stuff (never try to grab the spin_lock).
Так в чем же проблема?Ну, в середине моего work_handler для Tx и Rx происходит IRQ (пока ничего страшного).IRQ, очевидно, выводит меня из рабочей очереди, на которой запланирован NAPI.Теперь вместо того, чтобы возвращаться к рабочей очереди, она обрабатывает функцию NAPI (опять же, это не так уж сложно для моей программы, я уверен, что это приоритетная вещь).Затем вызовы моего ядра ndo_start_xmit снова попадают в spin_lock, после чего процессор останавливается.Ни при каких условиях программа никогда не возвращается к запланированной, но прерванной работе из work_handler.При тестировании это фактически было прервано между двумя операторами печати, так что я знаю, что он никогда даже не делал частичного возврата.
Так почему workqueue никогда не возвращается?Есть ли способ решить это?Мое первоначальное предположение - flush_work, но это больше похоже на исправление проблемы, а не на ее устранение.Было бы лучше переместить мою Tx schedule_work, чтобы быть частью обработчика NAPI вместо этого?
Спасибо за понимание.
ОБНОВЛЕНИЕ: Это после того, как я принял совершенно хороший ответ.В последующем обсуждении я предложил несколько экземпляров NAPI.Проще говоря, 1 NAPI на нетдев, в противном случае появляется много проблем.Я не мог отличить причину напи с помощью только структуры напи (возможно, кто-то видит способ, которым я не делаю, кроме злоупотребления бюджетным числом).Что касается моей проблемы, я обнаружил, что это была проблема с 3 шагами.Рабочая очередь была прервана RX irq / napi.Затем Rx napi был заблокирован вызовом ndo_start_xmit.ndo_start_xmit пытается захватить тот же спин-блокировку, который использовал рабочая очередь, поэтому я застрял в положении, в котором ничто не может двигаться, следовательно, происходит останов процессора.