NFsec Logo

Sterowanie przerwaniami sprzętowymi w systemie Linux

24/06/2011 w Administracja Brak komentarzy.  (artykuł nr 320, ilość słów: 2314)

Z

a każdym razem, kiedy część naszego sprzętu komputerowego takiego jak np. dysk twardy, czy karta sieciowa – wymaga poświęcenia uwagi ze strony procesora (CPU) – wywołuje przerwanie (ang. interrupt) lub żądanie przerwania (IRQInterrupt ReQuest). Przerwanie takie “mówi” procesorowi, że właśnie zaistniało pewne zdarzenie, które musi zostać natychmiast obsłużone – dlatego procesor powinien porzucić swoją dotychczasową pracę i zająć się tym zdarzeniem. W celu uniknięcia zgłaszania przez wiele urządzeń tych samych przerwań, system IRQ został tak zaplanowany, aby każde urządzenie w systemie komputerowym posiadało swój własny, specjalny nr przerwania, czyniący go niepowtarzalnym.

Zaczynając od wersji jądra 2.4 system Linux otrzymał możliwość przypisywania określonych przerwań do określonych procesorów (lub ich grup). Pierwotnie funkcja ta opracowywana w ramach projektu Red Hat Content Accelerator została rozwinięta jako niezależny mechanizm jądra określany terminem SMP IRQ Affinity (ang. Symmetric MultiProcessing Interrupt ReQuest Affinity) i pozwala na sterowanie sposobem w jaki nasz system będzie odpowiadał na różne zdarzenia związane ze sprzętem. Daje nam to możliwość przydzielania i rozkładania pracy, którą obciążony jest nasz serwer. Oczywiście, w celu wykorzystania tej technologii potrzebna nam będzie maszyna, która posiada więcej niż jeden procesor (SMP) oraz jądro w wersji 2.4 lub wyższej.

SMP Affinity jest kontrolowane i może być manipulowane przez pliki znajdujące się w wirtualnym systemie plików /proc, a dokładniej katalogu /proc/irq/. W katalogu tym znajdują się inne katalogi, których nazwy odpowiadają numerom przerwań sprzętowych znajdujących się w naszym systemie (jednak nie wszystkie mogą być tutaj wyszczególnione). W każdym z tych katalogów znajduje się plik o nazwie “smp_affinity“. To za jego pomocą określamy, który i ile procesorów ma zająć się danym przerwaniem. Pierwszym krokiem do wyskalowania odpowiednich urządzeń jest zorientowanie się, którego przerwania używa jakie urządzenie. Informacje te dostępne są w pliku /proc/interrupts:

root@darkstar:~# cat /proc/interrupts 
            CPU0       CPU1       CPU2       CPU3       
   0:         29          7          8          6   IO-APIC-edge      timer
   1:          1          0          2          1   IO-APIC-edge      i8042
   8:          0          1          0          0   IO-APIC-edge      rtc0
   9:          0          0          0          0   IO-APIC-fasteoi   acpi
  14:      12498         14      12818         17   IO-APIC-edge      ata_piix
  15:          0          0          0          0   IO-APIC-edge      ata_piix
  16:     182383        144     279295        162   IO-APIC-fasteoi   hda_intel, nvidia
  18:     139573         56        249         78   IO-APIC-fasteoi   uhci_hcd:usb4, snd0106
  20:      56159       1873       3019       1848   IO-APIC-fasteoi   ahci
  21:       5274     382153       5294     382136   IO-APIC-fasteoi   ehci_hcd:usb1, usb2
  22:          0          0          0          0   IO-APIC-fasteoi   uhci_hcd:usb3
  23:          0          0          0          0   IO-APIC-fasteoi   uhci_hcd:usb5
 NMI:          0          0          0          0   Non-maskable interrupts
 LOC:    1155507    1131555    1300727    1159863   Local timer interrupts
 SPU:          0          0          0          0   Spurious interrupts
 PMI:          0          0          0          0   Performance monitoring interrupts
 IWI:          0          0          0          0   IRQ work interrupts
 RES:      41001      37232      35187      40728   Rescheduling interrupts
 CAL:       8153      32832       6373       6241   Function call interrupts
 TLB:      32092      41628      36624      44183   TLB shootdowns
 TRM:          0          0          0          0   Thermal event interrupts
 THR:          0          0          0          0   Threshold APIC interrupts
 MCE:          0          0          0          0   Machine check exceptions
 MCP:         22         22         22         22   Machine check polls
 ERR:          3
 MIS:          0

Jak widać powyżej jest to 4 procesorowa maszyna (w rzeczywistości są to dwa procesory dwurdzeniowe). Pierwsza kolumna (bez etykiety) jest listą IRQ używanych w systemie. Wiersze opisane literami (np. “NMI”, “LOC”) są częścią innych sterowników używanych w systemie, które nie są dla nas dostępne z tego poziomu. Na przykład NMI (ang. Non-Maskable Interrupts) są to przerwania, których nie można wyłączyć za pomocą maski przerwań. Służą one do obsługi nienaprawialnych błędów wymagających natychmiastowej uwagi – takie jak błędy chipsetu, czy pamięci (bit parzystości, ECC).

Od drugiej aż do czwartej kolumny (z etykietami CPU0 – CPU3) pokazywana jest ilość razy jaką dany procesor obsłużył wybrane żądanie IRQ. Na przykład wszystkie dwa procesory obsłużyły mniej więcej taką samą liczbę przerwań dla IRQ 14 (CPU0 – 12498, CPU2 – 12818). Zanim dojdziemy do szóstej kolumny należy w tym momencie wspomnieć, że systemy wieloprocesorowe (uniprocesorowe produkowane od 2 września 2000 r. – PC 2001) sterują statyczną i dynamiczną dystrybucją przerwań pomiędzy procesorami za pomocą układów APIC (ang. Advnaced Programmable Interrupt Controller). To właśnie zaawansowane programowalne kontrolery przerwań są odpowiedzialne za obsługę przerwań sprzętowych (stały się zamiennikami dla kontrolerów przerwań w stylu PC, obsługującym SMP). Te rozproszone układy składają się z I/O APIC (APIC wejścia / wyjścia), który znajduje się w chipsecie płyty głównej oraz Local APIC (lokalnym APIC) znajdującym się w samym procesorze. Docierające poprzez linie IRQ przerwanie jest rejestrowane przez I/O APIC, które następnie informuje o tym Local APIC. Ten z kolei pozwala podejmować decyzję, czy dana jednostka obliczeniowa może w danej chwili współpracować z magistralą APIC. Między innymi dlatego w systemach SMP zaleca się stosowanie jednakowych, lokalnych układów APIC w każdym procesorze wchodzącym w skład serwera. W praktyce oznacza to używanie procesorów dokładnie z tej samej serii produkcyjnej np. dwóch procesorów Intel(R) Xeon(R) CPU E5420 @ 2.5 GHz. W starszych komputerach jednoprocesorowych APIC lokalny i I/O były domyślnie wyłączone i musiały być włączane ręcznie za pomocą parametru jądra apic. Aktualnie (szczególnie dla systemów 64-bitowych) są one domyślnie włączone. To samo tyczy się systemu Linux, który standardowo posiada obsługę tego kontrolera.

Wracając do szóstej kolumny – mówi ona nam o tym, czy sterownik danego urządzenia jest powiązany z obsługą przerwań za pomocą kontrolera I/O APIC. Głównym powodem, dla którego należy zwracać uwagę na tę kolumnę jest fakt, że przypisywanie określonych przerwań do określonych procesorów jest możliwe tylko dla tych urządzeń, których przerwania obsługiwane są przez I/O APIC. Ostatnia – siódma kolumna – określa jakie urządzenie jest przypisane do jakiego przerwania. Jeśli skróty te nam nic nie mówią możemy wykorzystać polecenie: lspci -v | more, w celu uzyskania bardziej szczegółowego opisu:

00:1f.2 SATA controller: Intel SATA AHCI Controller (rev 09) (prog-if 01 [AHCI 1.0])
	Subsystem: Dell Device 01c1
	Flags: bus master, 66MHz, medium devsel, latency 0, IRQ 20
	I/O ports at fe00 [size=8]
	I/O ports at fe10 [size=4]
	I/O ports at fe20 [size=8]
	I/O ports at fe30 [size=4]
	I/O ports at fec0 [size=32]
	Memory at f0000000 (32-bit, non-prefetchable) [size=1K]
	Capabilities: 
	Kernel driver in use: ahci
	Kernel modules: ahci

W ten sposób wiemy, że kontroler dysków SATA obsługiwany jest przez IRQ 20, a te z kolei przetwarzane jest przez I/O APIC. Spójrzmy teraz jak wygląda rzeczywista obsługa tego przerwania przez procesory:

root@darkstar:~# cat /proc/irq/20/smp_affinity 
01

Wartość 01 jest maską bitową określającą, do którego procesora będą kierowane żądania IRQ 20. Liczba znajdująca się w pliku “smp_affinity” jest przedstawiona w formacie szesnastkowym, a każda zapisana w nim cyfra reprezentuje grupę 4 procesorów (pierwsze 4 procesory z lewej reprezentowane są przez ostatnią wartość z prawej). Dlatego w celu prawidłowej manipulacji przerwaniami musimy przekształcić nasz układ bitów z binarnego na szesnastkowy jeszcze przed ich ustawieniem w wirtualnym systemie plików /proc.

            Binarny      Hex 
    CPU 0    0001         1 
    CPU 1    0010         2
    CPU 2    0100         4
    CPU 3    1000         8

Czyli wartość heksadecymalna 01 oznacza, że do obsługi IRQ 20 został wyznaczony pierwszy procesor – CPU0. Jeśli chcemy teraz, aby przerwanie to było obsługiwane zarówno przez CPU0 oraz CPU2 musimy dodać wartości binarne 0001 oraz 0100, co da nam 0101 (hex: 1+4 = 5):

echo 05 > /proc/irq/20/smp_affinity

Dla wszystkich czterech procesorów dodajemy wszystkie wartości: 1+2+4+8 = F (1111):

echo 0f > /proc/irq/20/smp_affinity

Jeśli dla danego przerwania zostanie zdefiniowanych wiele procesorów – będzie ono zawsze używało najmniej obciążonego. Nazywa się to najniższym priorytetem routingu APIC (ang. lowest priority APIC routing). Jakie zastosowanie może mieć SMP IRQ Affinity w codziennym użytkowaniu serwerów wieloprocesorowych? Na przykład możemy rozłożyć obciążenie związane z wieloma kartami sieciowymi w wieloprocesorowej maszynie pełniącej rolę routera – przypisując przerwania jednej karty do jednego z wielu procesorów. W przypadku serwerów bazodanowych możemy przypisać określoną liczbę procesorów do obsługi kontrolerów dyskowych, a wydzielając jeden do obsługi ruchu sieciowego w celu poprawienia jego czasów odpowiedzi. Wszystko tak naprawdę zależy od ilości posiadanych jednostek obliczeniowych i roli jaką pełni nasz serwer. Jeśli nie zależy nam na ręcznym rozkładaniu przerwań sprzętowych możemy również skorzystać z IRQ Balance, który służy do “niewidzialnego” dla nas rozdzielania przerwań na procesory i rdzenie znajdujące się w naszym systemie komputerowym, w celu znalezienia kompromisu pomiędzy wydajnością, a oszczędnością energii (i nie tylko).

Więcej informacji: źródła jądra: /Documentation/x86/i386/IO-APIC.txt, /Documentation/IRQ-affinity.txt, Bagiński M., K. Wasielewska, “Sprzętowa implementacja SMP w systemie Linux” (2003), SMP IRQ Affinity, irqbalance

Kategorie K a t e g o r i e : Administracja

Tagi T a g i : , , , , , , , , , ,

Komentowanie tego wpisu jest zablokowane.