LINUX.ORG.RU

[kernel dev] 'nobody cared' during interrupt


0

0

Добрый день.

Пишу дрова для pcie платы, и при каждом срабатывании irq кернел ругается точно таким же образом как и вот здесь http://www.linux.org.ru/forum/general/3591160. irqpoll пробовал - не помогает. В прерывании делаю dma_unmap_single() и kfifo_put(). Подозрения на kfifo_put(). Оно использует spinlock блокировку.

Вопрос: можно ли в interrupt context вызывать kfifo_put со spinlock. Или же это баг ядра?

Кухня: http://www.asus.com/search.aspx?searchitem=1&searchkey=P4-P5N9300 проц - селерон 4 гига памяти. дистр - дебиан, ядро - 2.6.26-2-bigmem.

Спасибо.

/* * If 99,900 of the previous 100,000 interrupts have not been handled * then assume that the IRQ is stuck in some manner. Drop a diagnostic * and try to turn the IRQ off. * * (The other 100-of-100,000 interrupts may have been a correctly * functioning device sharing an IRQ with the failing one) * * Called under desc->lock */

static void __report_bad_irq(unsigned int irq, struct irq_desc *desc,

Читали?

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

frey ★★
()
Ответ на: комментарий от frey

Точнее отключать их в самом девайсе, shared irq наверно не замаскируешь.

frey ★★
()

Обработчик должен вернуть статус IRQ_NONE или IRQ_HANDLED. Видимо обработчик повешен с флагом IRQF_SHARED и возвращает неопределённый статус, соответсвенно, ядро решает что IRQ не обработан и пытается дернуть следующий обработчк, которого либо нет, либо он не признает IRQ за своего. Вот ядро и ругается что irq # nobody cared.

jr_A
()
Ответ на: комментарий от frey

Нет, так глубоко я ещё вникнуть не успел.

Позвольте мне немного рассказать о дейвайсе. Им служит fpga чип от xilinx. Работает он так: когда я готов принять данные (dma allocation и всё такое), записываю в один из регистров устройства один. Устройство делает dma transfer и ждёт дальше. Т.е. по идее прерывание должно быть только одно.

Прерывание у меня не shared. В request_irq() я не укызываю флаг IRQF_SHARED.

Спасибо за инфу, обязательно почитаю.

nanoo_linux
() автор топика
Ответ на: комментарий от jr_A

К сожалению, доступ к машине будет только завтра. Если по памяти, то приблизительно такой.

static irqreturn_t x_interrupt_handler(int irq, void *dev)
{
  pci_unmap_single(ppdev, dma_addr, dma_size, DMA_FROMDEVICE);
  kfifo_get(fifo, dma_virt_addr, dma_size);
  if(task)
    wake_up_process(task);

  return IRQ_HANDLED;
}

утстанавливаю я его в ф-ии probe для pci устройств прибилизтельно так:

...
 if( 0 > request_irq(xilinx_irq_pin,
                &x_interrupt_handler,
                0,
                "xilinx_pcie",
                dev))
       printk("interrupt line %d is busy\n", xilinx_irq_pin);
...

Сообщение «interrupt line is busy» появляется в логах только если noapic при загрузке. Но этот режим я не использую.

nanoo_linux
() автор топика
Ответ на: комментарий от jr_A

Да, pci_enable_device есть, а в remove disable отрабатывает. У меня xilinx_irq_pin = 10. Это число я беру из конфигурационного пространства при помощи pci_read_config_byte().

Им служит fpga чип от xilinx.

апмдз цезарь?

Нет, вот это http://www.surface-concept.com/html/fast_electronics.html портирую на линукс. Это для науки железяка.

А про цезяря я и не слыхал :) Чип тот же стоит - spartan3.

nanoo_linux
() автор топика
Ответ на: комментарий от jr_A

На этот вопрос я отвечу только завтра ибо точно уже не помню :)

nanoo_linux
() автор топика
Ответ на: комментарий от nanoo_linux

>У меня xilinx_irq_pin = 10. Это число я беру из конфигурационного пространства при помощи pci_read_config_byte().

Бери его из dev->irq, после вызова pci_enable_device(). Они (весьма вероятно) могут не совпадать.

tim239 ★★
()
Ответ на: комментарий от nanoo_linux
           CPU0       
  0:        161   IO-APIC-edge      timer
  1:          2   IO-APIC-edge      i8042
  4:          2   IO-APIC-edge    
  7:          1   IO-APIC-edge    
  8:         81   IO-APIC-edge      rtc0
  9:          0   IO-APIC-fasteoi   acpi
 10:          0   IO-APIC-edge      xilinx_pci
 12:          4   IO-APIC-edge      i8042
 20:          0   IO-APIC-fasteoi   ohci_hcd:usb3
 21:         13   IO-APIC-fasteoi   ehci_hcd:usb2
 22:        152   IO-APIC-fasteoi   ehci_hcd:usb1, hda_intel
 23:          0   IO-APIC-fasteoi   ohci_hcd:usb4
 29:       2927   PCI-MSI-edge      ahci
 30:       3998   PCI-MSI-edge      eth0
NMI:          0   Non-maskable interrupts
LOC:      26796   Local timer interrupts
SPU:          0   Spurious interrupts
PMI:          0   Performance monitoring interrupts
PND:          0   Performance pending work
RES:          0   Rescheduling interrupts
CAL:          0   Function call interrupts
TLB:          0   TLB shootdowns
TRM:          0   Thermal event interrupts
THR:          0   Threshold APIC interrupts
MCE:          0   Machine check exceptions
MCP:         10   Machine check polls
ERR:          1
MIS:          0

сегодня утром поставил ядро 2.6.33 прерывания теперь вообще не срабатываeт. [offtop] кстати поменяли kfifo апи [/offtop]

nanoo_linux
() автор топика
Ответ на: комментарий от tim239

вместо

pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &xilinx_irq_number);

написал так

xilinx_irq_number = dev->irq;

теперь у меня в логах вот такое вот:

[ 3176.039069] irq arrived
[ 3176.039073] irq arrived
[ 3176.039077] irq arrived
[ 3176.039081] irq arrived
[ 3176.039085] irq arrived
[ 3176.039089] irq arrived
[ 3176.039093] irq arrived
[ 3176.039097] irq arrived
[ 3176.039101] irq arrived
[ 3176.039105] irq arrived
[ 3176.039109] irq arrived
[ 3176.039113] irq arrived
[ 3176.039117] irq arrived
[ 3176.039121] irq arrived
[ 3176.039124] irq arrived
[ 3176.039128] irq arrived

т.е. прерывания генерируються сами по себе, без моего участия и без всякой на то причины.

я счастлив :)

nanoo_linux
() автор топика
Ответ на: комментарий от tim239

Оссцилограф то есть, только pci express же. Там всё в tlp пакетах передаётся. Я тут кажется нашел в чем проблема, надо только проверить. В общем, если решится, отпишусь.

nanoo_linux
() автор топика
Ответ на: комментарий от nanoo_linux

Проблем было несколько, оказывается.

Первыя, из за чего 'nobody cared' - надо было действительно номер прерывания брать из dev-irq, а не из pci_read_config_byte, ибо они не совпадают.

Вторая - ошибка в fpga дизайне. После первого прерывания устройство начинало их генерировать просто так, без всякой на то причины. Отключить их програмно - никак. Пробовал разные методы - только перезагрузка.

Надо доставать книжки по vhdl. :/

nanoo_linux
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.