Forum Discussion
Linux UIO IRQ related periodic CPU usage
Thank you!
Unfortunately none of them work.
1. It is UIO irq only device, no memory region assigned to it.
2. Yes, I have done it before, it works, but I need the more stricter timing with IRQ.
3. It is an edge-triggered irq.
4. I've already tried everything (except the solution :D), nothing worked. I've made it clear/not to clear, tried with poll/select , swapped the orders etc.
Item 4: Still some question on the user application design:
Just to double confirm, WRITE() must always be after READ() and only after you are done with any data processing/event handling.
In the interrupt handler, any interrupt trigger will automatically disable the IRQ. The READ() will get a wakeup and at this point, the IRQ is disabled. The call to write() will re-enable the IRQ.
If you don't do a WRITE at all, do you see the CPU spikes? In this scenario, the IRQ should be disabled and not entertaining edge interrupt triggers. Check "cat /proc/interrupts" to see if the counts stopped.
And if you do a WRITE() from your test,
Check "cat /proc/interrupts" to see if the counts increment as expected or it storms with a huge number.
bool wait_for_irq (TX_IRQ_HANDLE_S* pHandle) { if (!pHandle || pHandle->txTrigIrqFd < 0) { std::cout << "ERROR: handle"; return false; } uint32_t info = 1; ssize_t nb = write(pHandle->txTrigIrqFd, &info, sizeof(info)); <- this re-enables IRQ, should always be only when you are ready to for the next event. if (nb != (ssize_t)sizeof(info)) { std::cout << "ERROR: writing"; return false; } nb = read(pHandle->txTrigIrqFd, &info, sizeof(info)); if (nb == (ssize_t)sizeof(info)) { return true; } return false; }
- yepp1 year ago
New Contributor
This was a "minimal" program for the forum, but yes, the re-enable (write) should be after the read, and also before the first read, we should enable the irq. I pasted to this minimal code appearently in the wrong order, however I tried every combination. Also with the correct READ->WRITE .
Yes, the interrupts are stopped coming when I don't re-enable it (= do not call write), but continued to waiting for it with read/poll/select. Also the /proc/interrupts counter is stopped, and the spikes in the CPU usage are gone.When I continue to re-enable the interrupts in the program, the irq counter continues from the number when it was stopped (not re-enabled).
I've already checked a few times for a storm:
- the cat /proc/interrupts shows no increment when the irq-s are not handled by the sw. (or the re-enable bit is not written back)
- I've double checked the kernel (compiled it with lots of debug messages), there is no storm for sure.