Задача: Установите свой дополнительный обработчик прерываний (на любой IRQ, например сетевой карты, численное значение IRQ указывайте параметром загрузки модуля). Модуль должен диагностировать полученные прерывания в журнал и подсчитывать их число.
Код: Выделить всё
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/jiffies.h>
#define LOG(...) printk( KERN_INFO "=== "__VA_ARGS__ )
#define ERR(...) printk( KERN_ERR "=== "__VA_ARGS__ )
#define SHARED_IRQ 1
#define NAME_LEN 12
#define IRQ_ID 321
static int irq = SHARED_IRQ; // контролируемая IRQ
module_param( irq, int, 0 );
static unsigned int delay = 1; // интервал индикации, сек.
module_param( delay, uint, 0 );
static atomic64_t counter = ATOMIC_LONG_INIT( 0 );
static volatile long unsigned int next;
static irqreturn_t handler( int irq, void *id ) {
atomic64_inc( &counter );
if( time_after( jiffies, next ) ) { // прошло больше интервала
LOG( "%ld => %lld\n", jiffies, atomic64_read( &counter ) );
next = jiffies + delay;
}
return IRQ_NONE;
}
int init_module( void ) {
char dev[ NAME_LEN ];
int ret;
sprintf( dev, "handler-%02d", irq );
if( ( ret = request_irq( irq, handler, IRQF_SHARED, dev, (void*)IRQ_ID ) ) != 0 )
ERR( "can't install handler for IRQ=%d\n", irq );
else {
LOG( "module installed\n" );
delay *= HZ;
next = jiffies + delay; // отметка старта
}
return ret;
}
void cleanup_module( void ) {
synchronize_irq( irq );
free_irq( irq, (void*)IRQ_ID );
LOG( "module removed: registered %llu events\n", atomic64_read( &counter ) );
}
MODULE_LICENSE( "GPL v2" );
MODULE_AUTHOR( "Oleg Tsiliuric <olej@front.ru>" );
Код: Выделить всё
bash-4.2$ uname -r
3.14.8-200.fc20.i686
bash-4.2$ cat /proc/cpuinfo | grep 'model name' | wc -l
2
bash-4.2$ cat /proc/cpuinfo | grep 'model name' | head -n1
model name : Genuine Intel(R) CPU T2300 @ 1.66GHz
Код: Выделить всё
-bash-4.2$ watch 'cat /proc/interrupts | grep i915'
Every 2,0s: cat /proc/interrupts | grep i915 Sat Feb 7 13:43:11 2015
16: 75572 187050 IO-APIC-fasteoi i915, enp2s14
Код: Выделить всё
bash-4.2$ sudo insmod irqs.ko irq=16 delay=5
[sudo] password for Olej:
bash-4.2$ dmesg | tail -n10
[ 9182.522817] === 8882522 => 8430
[ 9183.528192] === 8883528 => 8582
[ 9184.533577] === 8884533 => 8736
[ 9185.371191] === module removed: registered 8864 events
[25756.938801] === module installed
[25761.940308] === 25461940 => 751
[25766.945543] === 25466945 => 1507
[25771.950789] === 25471950 => 2273
[25776.956032] === 25476956 => 3027
[25781.961263] === 25481961 => 3777
bash-4.2$ sudo rmmod irqs.ko