CPU0 jest zalany przerwaniami eth1

12

Mam maszynę Wirtualną Ubuntu, działającą w Xen XCP opartym na Ubuntu. Obsługuje niestandardową usługę HTTP opartą na FCGI nginx.

Pod ab pierwszym obciążeniem rdzeń procesora jest nasycony, a reszta jest niedociążona.

W /proc/interruptsWidzę, że CPU0 służy rząd wielkości więcej niż jakikolwiek inny przerwania rdzenia. Większość z nich pochodzi eth1.

Czy mogę coś zrobić, aby poprawić wydajność tej maszyny wirtualnej? Czy istnieje sposób na bardziej równomierne zrównoważenie przerwań?


Krwawe szczegóły:

$ uname -a
Linux MYHOST 2.6.38-15-virtual # 59-Ubuntu SMP Pt 27 kwietnia 16:40:18 UTC 2012 i686 i686 i386 GNU / Linux

$ lsb_release -a
Brak dostępnych modułów LSB.
Identyfikator dystrybutora: Ubuntu
Opis: Ubuntu 11.04
Wydanie: 11.04
Nazwa kodowa: natty

$ cat / proc / interrupts 
           CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7       
283: 113720624 0 0 0 0 0 0 0 xen-dyn-event eth1
284: 1 0 0 0 0 0 0 0 xen-dyn-event eth0
285: 2254 0 0 3873799 0 0 0 0 xen-dyn-event blkif
286: 23 0 0 0 0 0 0 0 xen-dyn-event hvc_console
287: 492 42 0 0 0 0 0 295324 xen-dyn-event xenbus
288: 0 0 0 0 0 0 0 222294 xen-percpu-ipi callfuncsingle7
289: 0 0 0 0 0 0 0 0 xen-percpu-virq debug7
290: 0 0 0 0 0 0 0 151302 xen-percpu-ipi callfunc7
291: 0 0 0 0 0 0 0 3236015 xen-percpu-ipi zmieniono7
292: 0 0 0 0 0 0 0 60064 xen-percpu-ipi spinlock7
293: 0 0 0 0 0 0 0 12355510 xen-percpu-virq timer7
294: 0 0 0 0 0 0 803174 0 xen-percpu-ipi callfuncsingle6
295: 0 0 0 0 0 0 0 0 xen-percpu-virq debug6
296: 0 0 0 0 0 0 60027 0 xen-percpu-ipi callfunc6
297: 0 0 0 0 0 0 5374762 0 xen-percpu-ipi zmieniony6
298: 0 0 0 0 0 0 64976 0 xen-percpu-ipi spinlock6
299: 0 0 0 0 0 0 15294870 0 xen-percpu-virq timer6
300: 0 0 0 0 0 264441 0 0 xen-percpu-ipi callfuncsingle5
301: 0 0 0 0 0 0 0 0 xen-percpu-virq debug5
302: 0 0 0 0 0 79324 0 0 xen-percpu-ipi callfunc5
303: 0 0 0 0 0 3468144 0 0 xen-percpu-ipi zmieniony 5
304: 0 0 0 0 0 66269 0 0 xen-percpu-ipi spinlock5
305: 0 0 0 0 0 12778464 0 0 xen-percpu-virq timer5
306: 0 0 0 0 844591 0 0 0 xen-percpu-ipi callfuncsingle4
307: 0 0 0 0 0 0 0 0 xen-percpu-virq debug4
308: 0 0 0 0 75293 0 0 0 xen-percpu-ipi callfunc4
309: 0 0 0 0 3482146 0 0 0 xen-percpu-ipi resched4
310: 0 0 0 0 79312 0 0 0 xen-percpu-ipi spinlock4
311: 0 0 0 0 21642424 0 0 0 xen-percpu-virq timer4
312: 0 0 0 449141 0 0 0 0 xen-percpu-ipi callfuncsingle3
313: 0 0 0 0 0 0 0 0 xen-percpu-virq debug3
314: 0 0 0 95405 0 0 0 0 xen-percpu-ipi callfunc3
315: 0 0 0 3802992 0 0 0 0 xen-percpu-ipi resched3
316: 0 0 0 76607 0 0 0 0 xen-percpu-ipi spinlock3
317: 0 0 0 16439729 0 0 0 0 xen-percpu-virq timer3
318: 0 0 876383 0 0 0 0 0 xen-percpu-ipi callfuncsingle2
319: 0 0 0 0 0 0 0 0 xen-percpu-virq debug2
320: 0 0 76416 0 0 0 0 0 xen-percpu-ipi callfunc2
321: 0 0 3422476 0 0 0 0 0 xen-percpu-ipi resched2
322: 0 0 69217 0 0 0 0 0 xen-percpu-ipi spinlock2
323: 0 0 10247182 0 0 0 0 0 xen-percpu-virq timer2
324: 0 393514 0 0 0 0 0 0 xen-percpu-ipi callfuncsingle1
325: 0 0 0 0 0 0 0 0 xen-percpu-virq debug1
326: 0 95773 0 0 0 0 0 0 xen-percpu-ipi callfunc1
327: 0 3551629 0 0 0 0 0 0 xen-percpu-ipi resched1
328: 0 77823 0 0 0 0 0 0 xen-percpu-ipi spinlock1
329: 0 13784021 0 0 0 0 0 0 Zegar xen-percpu-virq1
330: 730435 0 0 0 0 0 0 0 xen-percpu-ipi callfuncsingle0
331: 0 0 0 0 0 0 0 0 debugowanie xen-percpu-virq0
332: 39649 0 0 0 0 0 0 0 xen-percpu-ipi callfunc0
333: 3607120 0 0 0 0 0 0 0 xen-percpu-ipi zmieniony0
334: 348740 0 0 0 0 0 0 0 xen-percpu-ipi spinlock0
335: 89912004 0 0 0 0 0 0 0 xen-percpu-virq timer0
NMI: 0 0 0 0 0 0 0 0 Przerwania niemaskowalne
LOC: 0 0 0 0 0 0 0 0 Lokalne przerwania timera
SPU: 0 0 0 0 0 0 0 0 Fałszywe przerwania
PMI: 0 0 0 0 0 0 0 0 Przerwania monitorowania wydajności
IWI: 0 0 0 0 0 0 0 0 Przerwania pracy IRQ
RES: 3607120 3551629 3422476 3802992 3482146 3468144 5374762 3236015 Przerwania zmiany harmonogramu
CAL: 770084 489287 952799 544546 919884 343765 863201 373596 Przerwania wywołania funkcji
TLB: 0 0 0 0 0 0 0 0 Zrzuty TLB
TRM: 0 0 0 0 0 0 0 0 Przerwania zdarzenia termicznego
THR: 0 0 0 0 0 0 0 0 Próg przerywa APIC
MCE: 0 0 0 0 0 0 0 0 Wyjątki sprawdzania maszyny
MCP: 0 0 0 0 0 0 0 0 Ankiety sprawdzające maszynę
ERR: 0
MIS: 0
Alexander Gladysh
źródło
Dodatkowe pytanie: czy istnieje sposób na zmniejszenie liczby przerwań eth1?
Alexander Gladysh

Odpowiedzi:

10

Zajrzyj do /proc/irq/283katalogu. Istnieje smp_affinity_listplik, który pokazuje, które procesory otrzymają przerwanie 283. Dla ciebie ten plik prawdopodobnie zawiera „0” (i smp_affinityprawdopodobnie zawiera „1”).

Możesz zapisać zakres procesora do smp_affinity_listpliku:

echo 0-7 | sudo tee /proc/irq/283/smp_affinity_list

Możesz też napisać maskę bitów, w której każdy bit odpowiada procesorowi, aby smp_affinity:

printf %x $((2**8-1)) | sudo tee /proc/irq/283/smp_affinity

Jednak wiadomo , że brak równowagi ma własne wyobrażenie o powinowactwie każdego przerwania i może cofnąć twoje aktualizacje. Dlatego najlepiej jest całkowicie odinstalować irqbalance. Lub przynajmniej zatrzymaj go i wyłącz go przed ponownym uruchomieniem.

Jeśli nawet bez nierównowagi masz dziwne smp_affinityprzerwanie 283 po ponownym uruchomieniu, będziesz musiał ręcznie zaktualizować powinowactwo procesora w jednym ze skryptów startowych.

chutz
źródło
irqbalancejuż działa. Może nie jest poprawnie skonfigurowany? Jak to sprawdzić?
Alexander Gladysh
Może powinieneś po prostu wyłączyć nierównowagę, uruchomić ponownie, sprawdzić, czy to pomoże. Przerwania są domyślnie dość dobrze zrównoważone.
chutz
FYI: /proc/irq/283/smp_affinityma 01to teraz (nikt nie zmienił tych rzeczy na tym komputerze zgodnie z moją najlepszą wiedzą - więc to musi być domyślny system).
Alexander Gladysh
Przepraszam, zaktualizowałem swoją odpowiedź. przyczyną jest prawdopodobnie nierównowaga. Po prostu się go pozbądź. Nie wiem, jaka powinna być domyślna wartość, ale z doświadczenia widziałem, że domyślnie jest to „WSZYSTKIE procesory”.
chutz
Wyłączenie irqbalance(przez ENABLED=0w /etc/default/irqbalance) nie pomaga. Po ponownym uruchomieniu irqbalancejest stop/waiting, ale /proc/irq/283/smp_affinitynadal jest 01.
Alexander Gladysh
2

Jeśli masz odpowiedni model Intel NIC, możesz znacznie poprawić wydajność.

Cytując pierwszy akapit:

Procesory wielordzeniowe i najnowsze adaptery Ethernet (w tym 82575, 82576, 82598 i 82599) pozwalają zoptymalizować przepływy przesyłania TCP, przypisując przepływy wykonania poszczególnym rdzeniom. Domyślnie Linux automatycznie przypisuje przerwania rdzeniom procesora. Obecnie istnieją dwie metody automatycznego przypisywania przerwań, moduł równoważenia IRQ w kałuży i demon równoważenia IRQ w przestrzeni użytkownika. Oba oferują kompromisy, które mogą obniżyć zużycie procesora, ale nie maksymalizują szybkości przesyłania IP. Optymalną przepustowość można uzyskać, ręcznie przypinając kolejki adaptera Ethernet do określonych rdzeni procesora.

W przypadku przekazywania IP para kolejki nadawczo-odbiorczej powinna wykorzystywać ten sam rdzeń procesora i zmniejszać synchronizację pamięci podręcznej między różnymi rdzeniami. Można tego dokonać, przypisując przerwania transmisji i odbioru do określonych rdzeni. Począwszy od jądra Linuksa 2.6.27, w kolejkach 82575, 82576, 82598 i 82599 można używać wielu kolejek. Dodatkowo włączono wiele kolejek transmisyjnych w przerwanych komunikatach przerwań (MSI-X). MSI-X obsługuje większą liczbę przerwań, które można zastosować, pozwalając na bardziej szczegółową kontrolę i kierowanie przerwań do określonych procesorów.

Zobacz: Przypisywanie przerwań rdzeniom procesora za pomocą kontrolera Ethernet Intel® 82575/82576 lub 82598/82599

Matt
źródło
2

W rzeczywistości zaleca się, szczególnie w przypadku krótkotrwałych powtarzających się procesów, aby wszystkie przerwy generowane przez kolejkę urządzeń były obsługiwane przez ten sam procesor zamiast równoważenia przerwania IRQ, dzięki czemu można uzyskać lepszą wydajność, jeśli pojedynczy procesor poradzi sobie z przerwaniem eth1 *** wyjątek podany poniżej

Źródło, do którego odsyłam powyżej, pochodzi z Linux Symposium i polecam przeczytanie kilku akapitów na temat SMP IRQ Affinity, ponieważ przekona cię to bardziej niż ten post.

Dlaczego?

Przypomnij sobie, że każdy procesor ma swoją własną pamięć podręczną, oprócz możliwości dostępu do pamięci głównej, sprawdź ten schemat . Po uruchomieniu przerwania rdzeń procesora będzie musiał pobrać instrukcje, aby obsłużyć przerwanie z pamięci głównej, co zajmuje znacznie więcej czasu niż w przypadku instrukcji znajdujących się w pamięci podręcznej. Gdy procesor wykona zadanie, będzie miał te instrukcje w pamięci podręcznej. Powiedzmy teraz, że ten sam rdzeń procesora prawie cały czas obsługuje to samo przerwanie, funkcja obsługi przerwań raczej nie opuści pamięci podręcznej rdzenia procesora, zwiększając wydajność jądra.

Alternatywnie, gdy IRQ jest zrównoważone, może przypisać przerwanie do obsługi przez inny procesor, wtedy nowy rdzeń procesora prawdopodobnie nie będzie miał funkcji obsługi przerwań w pamięci podręcznej, a uzyskanie odpowiedniego modułu obsługi z głównego zajmie dużo czasu. pamięć.

Wyjątek : jeśli rzadko używasz przerwania eth1, co oznacza, że ​​upływa wystarczająco dużo czasu, aby pamięć podręczna została nadpisana przez wykonanie innych zadań, co oznacza, że ​​dane przechodzą przez ten interfejs sporadycznie z długimi przerwami pomiędzy ... wtedy najprawdopodobniej nie zobaczysz tych korzyści bo są, kiedy używasz procesu z wysoką częstotliwością.

Wniosek

Jeśli twoje przerwanie występuje bardzo często, po prostu powiąż to przerwanie, aby było obsługiwane tylko przez określony procesor. Ta konfiguracja żyje w

 /proc/'IRQ number'/smp_affinity

lub

/proc/irq/'IRQ number'/smp_affinity

Zobacz ostatni akapit w sekcji SMP IRQ Affinity ze źródła podanego powyżej, zawiera instrukcje.

Alternatywnie

Możesz zmienić częstotliwość podnoszenia flagi przerwań, zwiększając rozmiar MTU (duże ramki), jeśli sieć na to pozwala, lub zmieniaj, aby flaga była podnoszona po odebraniu większej liczby pakietów zamiast przy każdym pakiecie LUB zmień upłynął limit czasu, więc zwiększ przerwę po upływie określonego czasu. Ostrożnie z opcją time, ponieważ rozmiar bufora może być pełny, zanim skończy się czas. Można to zrobić za pomocą ettoolu przedstawionego w powiązanym źródle.

ta odpowiedź zbliża się do długości, w której ludzie nie będą jej czytać, więc nie będę wchodził w szczegóły, ale w zależności od twojej sytuacji istnieje wiele rozwiązań ... sprawdź źródło :)

brat-bilo
źródło