Linux external event management - IRQ vs kthread poll

I am transferring a device driver from QNX to Linux. In QNX, the old driver used pthread with an infinite loop to monitor the occurrence of an interrupt, and not to register the true interrupt handler. To try to demonstrate the effectiveness of using register_irq () instead of a dedicated poll stream, I wrote two drivers on Linux. The corresponding code for each is shown below, and the question is below.

IRQ

Write a handler

irqreturn_t timing_interrupt_handler(int irq, void *dev_id) { u32 test; /* read device interrupt command/status register */ test = ioread32(timing_card[3].base); /* sanity check that the device reported the interrupt */ if ( test & (1 << 2) ) { /* clear interrupt status */ iowrite32( 0x0d, timing_card[3].base); /* toggle digital output line */ test = ioread32(timing_card[2].base); if ( test & 0x01 ) iowrite32(test & ~0x1, timing_card[2].base); else iowrite32(test | 0x1, timing_card[2].base); } return IRQ_HANDLED; } 

Register Handler

 rc = request_irq(irq_line, timing_interrupt_handler, IRQF_SHARED, "timing", timing_card); if ( rc ) { printk(KERN_ALERT "Failed to register irq %d\n", irq_line); return rc; } 

THREAD DEFINITION

Write stream function

 int poll_irq(void *data) { u32 test; /* until module unload */ while ( !kthread_should_stop() ) { /* read device interrupt command/status register */ test = ioread32(timing_card[3].base); /* sanity check that the device reported the interrupt */ if ( test & (1 << 2) ) { /* clear interrupt status */ iowrite32( 0x0d, timing_card[3].base); /* toggle digital output line */ test = ioread32(timing_card[2].base); if ( test & 0x01 ) iowrite32(test & ~0x1, timing_card[2].base); else iowrite32(test | 0x1, timing_card[2].base); } else usleep_range(9, 11); } return 0; } 

Start flow

 kthread = kthread_create(poll_irq, 0x0, "poll_IRQ_test"); wake_up_process(kthread); 

QUESTION

When I put two tracks on the oscilloscope - one controls the digital input of the card (which will cause an interrupt), and one of them monitors the digital output of the card (which will respond to the interrupt), I can measure the reaction time to the event.

The first β€œcorrect” method to register an IRQ takes about 80 microseconds.

The second method, which performs an endless stream, takes about 15-30 microseconds.

What gives? The advantage of the first is that it does not spend so much energy on processing, but why is the response time so dramatic? How bad is it to have this poll? How can one investigate and, ultimately, demonstrate the additional charge that the polling stream puts on the processor?

Thank you for your time!

The best

Scott

+4
source share
1 answer

The interrupt response time depends on the time during which your system (regardless of whether it is there) should deliver an interrupt, and by the time your processor (no matter what it is) should wake up from some energy-saving sleep mode.

The polling stream is powered by both processor time and power. To measure them, use something like top or powertop , or measure the power consumption directly on the hardware.

0
source

Source: https://habr.com/ru/post/1488764/


All Articles