Kernel Korner - Dynamic Interrupt Request Allocation for Device Drivers

Interrupts are how hardware gets software's attention. Here's how they work.
IRQ Allocation

A snapshot of interrupts already in use on the system is stored in the /proc directory. The $cat /proc/interrupt command displays the data related to the interrupts. The following output was displayed on my machine:

CPU0
  0:   82821789          XT-PIC  timer
  1:        122          XT-PIC  i8042
  2:          0          XT-PIC  cascade
  8:          1          XT-PIC  rtc
 10:     154190          XT-PIC  eth0
 12:        100          XT-PIC  i8042
 14:      21578          XT-PIC  ide0
 15:         18          XT-PIC  ide1
NMI:          0
ERR:          0

The first column is the IRQ line (vector ranges from 32–47), and the next column is the number of times the interrupts are delivered in the CPU after booting the system. The third column is related to the PIC, and the last column is the list of the device names that have registered handlers for the corresponding interrupt.

The simplest way to load a device driver dynamically is first to find the unused IRQ line in the system. A request_irq function is used to allocate a specified IRQ line number for a device. The syntax for the request_irq follows and is declared in linux/sched.h:

int
request_irq (unsigned int irq,
             void (*handler) (int, void *,
                              struct pt_regs *),
             unsigned long flags,
             const char *device, void *dev_id);

The details of the arguments in this function are:

  • unsigned int irq: interrupt number, which we want to request from the system.

  • void (*handler) (int, void *, struct pt_regs *): whenever an interrupt is generated, we have to write ISRs to handle the interrupt; otherwise, the processor simply acknowledges it and does nothing else for that interrupt. This argument is the pointer to the handler function. The syntax for the handler function is:

    void
    handler (int irq, void *dev_id,
             struct pt_regs *regs);
    

    The first argument is the IRQ number, which we already have mentioned in the request_irq function. The second argument is a device identifier, using major and minor numbers to identify which device is in charge of the current interrupt event. The third argument is used to save the process' context in the kernel stack before the processor starts executing the interrupt handler function. This structure is used when the system resumes the execution of the earlier process. Normally, device driver writers need not worry about this argument.

  • unsigned long flags: the flags variable is used for interrupt management. The SA_INTERRUPT flag is set for fast interrupt handler, and it disables all the maskable interrupt. SA_SHIRQ is set when we want to share the irq with more than one device, SA_PROBE is set if we are interested in probing a hardware device using the IRQ line, and SA_RANDOM is used to seed the kernel random number generator. For more details of this flag, see /usr/src/linux/drivers/char/random.c.

  • constant char *device: a device name that holds the IRQ.

  • void *dev_id: the device identifier—it's a pointer to the device structure. When the interrupt is shared, this field points to the particular device.

The request_irq function returns 0 on success and -EBUSY when the allocation has failed. EBUSY is the error number of 16, which is described in the /usr/src/linux/include/asm/errno.h file. The free_irq function releases the IRQ number from the device. The syntax for this function is:

free_irq (unsigned int irq, void *dev_id);

The explanation for the arguments is the same as above.

An ISR is invoked whenever an interrupt occurs. The operations to be performed on the cause of the interrupt are described in the ISR. The kernel maintains a table in memory, which contains the addresses of the interrupt routines (interrupt vectors). When an interrupt occurs, the processor checks the address of the ISR in the interrupt vector table and then executes. The task of the ISR is to react to the device according to the nature of the interrupt, such as read or write data. Typically, the ISR wakes up sleeping processes on the device if the interrupt signals the event for which they are waiting.

The amount of time the processor takes to respond to an interrupt is called interrupt latency. Interrupt latency is composed of hardware propagation time, register saving time and software propagation time. Interrupt latency should be minimal to improve the system's performance; for this reason, the ISR should be short and disable interrupts only for a brief time. Other interrupts can occur while interrupts are disabled, but the processor does not allow them until interrupts are re-enabled. If more than one interrupt is blocked, the processor allows them in priority order when it is ready for interrupt service.

Device driver developers should disable interrupts in driver code only when necessary, because the system does not update the system timers, transfer network packets to and from buffers and so on during the interrupt disabling. Driver developers should write ISRs to release the processor for other tasks. In real-world scenarios, however, ISRs handle lengthy tasks. In such situations, the ISR can do only the time-critical communication with the hardware to disable the interrupt and use the tasklet to perform most of the actual data transfer processing. The tasklet is the advanced feature in the latest Linux kernel that does certain operations related to the interrupt during safe times. The tasklet is the software interrupt, and it can be interrupted by other interrupts. The internals of the interrupts have been explained in detail by Bovet and Cesati (see the on-line Resources), and the implementation of the interrupts in device driver perspective is presented by Rubini and Corbet (see Resources).

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

interrupt requests

jhude's picture

can i just ask what are the different interrupt requests used in programming assembly language?

understanding IRQs

jmnsilva's picture

My output:

~> cat /proc/interrupts
CPU0
0: 8731569 XT-PIC timer
1: 267 XT-PIC i8042
2: 0 XT-PIC cascade
4: 52894 XT-PIC serial
8: 2 XT-PIC rtc
9: 0 XT-PIC acpi
10: 32009 XT-PIC eth1, ohci_hcd, ohci_hcd, eth0, SiS SI7012
11: 0 XT-PIC ehci_hcd
12: 100465 XT-PIC i8042
14: 40665 XT-PIC ide0
15: 74294 XT-PIC ide1
NMI: 0
LOC: 0
ERR: 0
MIS: 0

poses me some questions:

1) what does LOC and MIS mean?

2) why so many devices for the some IRQ?

3) is it possible to redefine a better allocation of IRQs? or is that irrelevant?

4) why the same device in different IRQs?

Do this questions have simple answers?

Thanks

Thanks for your help.

Mulugeta's picture

Thank you very much for your detail information about computer. Kepp it up.Please can give the detail answers of these questions?
1) what does LOC and MIS mean?
2) why so many devices for the some IRQ?
3) is it possible to redefine a better allocation of IRQs? or is that irrelevant?
4) why the same device in different IRQs?

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState