4.3. Interrupções e Ajuste de IRQ

Uma requisição de interrupção (IRQ) é uma requisição para serviço, enviada em nível de hardware. Interrupções podem ser enviadas por linhas de hardware dedicadas ou através de um bus de hardware como um pacote de informações(um Message Signaled Interrupt, ou MSI).
Quando as interrupções são habilitadas, o recebimento de um IRQ solicita uma troca para contexto de interrupção. O código de expedição de interrupções do Kernel recupera o número do IRQ e sua lista de associados de Rotinas de Serviço de Interrupçao (ISRs) registradas, e chama cada ISR. O ISR é consciente das interruções e ignora interrupções redundantes do mesmo IRQ, depois enfileira um manuseador deferido para terminar o processamento de interrupções e evitar que o ISR ignore interrupções futuras.
O arquivo /proc/interrupts relaciona o número de interrupções por CPU por dispositivo de E/S. Ele exibe o número de IRQ, o número daquela interrupção manipulada por cada núcleo da CPU, o tipo de interrupção, e uma lista delimitada por vírgulas de motoristas que estão registrados para receber essa interrupção. (Consulte a página de manual proc (5) para mais detalhes: man 5 proc)
Os IRQs possuem uma propriedade de "afinidade" associada, smp_affinity, que define os núcleos da CPU que podem executar o ISR para aquele IRQ. Esta propriedade pode ser usada para aprimorar o desempenho de aplicativo atribuindo a afinidade de interrupção e a afinidade do thread do aplicativo para um ou mais núcleos específicos. Isto permite o compartilhamento da linha do cache entre interrupções especificadas e threads de aplicativo.
O valor da afinidade de interrupção para um número do IRQ específico é armazenado no arquivo associado /proc/irq/IRQ_NUMBER/smp_affinity, que pode ser visualizado e modificado pelo usuário root. O valor armazenado neste arquivo é um bit-mask hexadecimal representando todos os núcleos da CPU no sistema.
Por exemplo, para configurar a afinidade de interrupção para o driver Ethernet em um servidor com quatro núcleos CPU, determine primeiro o número IRQ associado ao driver Ethernet:
# grep eth0 /proc/interrupts
32:   0     140      45       850264      PCI-MSI-edge      eth0
Use o número IRQ para localizar o arquivo smp_affinity apropriado:
# cat /proc/irq/32/smp_affinity 
f
O valor padrão para o smp_affinity é f, ou seja, o IRQ pode ser atentido em qualquer CPU no sistema. Configurar este valor para 1, como se segue, significa que somente a CPU 0 pode atender esta interrupção:
# echo 1 >/proc/irq/32/smp_affinity
# cat /proc/irq/32/smp_affinity
1
Vírgulas podem ser utilizadas para delimitar valores smp_affinity para grupos discretos de 32 bits. Isto é necessário em sistemas com mais do que 32 núcleos. Por exemplo, o seguinte exemplo demonstra que o IRQ 40 é atendido em todos os núcleos de um sistema de núcleo de 64:
# cat /proc/irq/40/smp_affinity
ffffffff,ffffffff
Para atender ao IRQ 40 somente acima de 32 núcleos de um sistema de núcleo 64, você deve fazer o seguinte:
# echo 0xffffffff,00000000 > /proc/irq/40/smp_affinity
# cat /proc/irq/40/smp_affinity
ffffffff,00000000

Nota

Nos sistemas que suportam direcionamento de interrupção, modificar o smp_affinity de um IRQ define o hardware para que a decisão de atenter uma interrução com uma CPU específica seja feita em nível de hardware, sem intervenção do kernel.