CPU0 est submergé d'interruptions eth1

12

J'ai une machine virtuelle Ubuntu, exécutée dans Xen XCP basé sur Ubuntu. Il héberge un service HTTP personnalisé basé sur FCGI, derrière nginx.

La charge du ab premier cœur de processeur est saturée et le reste est sous-chargé.

En /proc/interruptsje vois que CPU0 sert un ordre de grandeur plus d'interruptions que tout autre noyau. La plupart d'entre eux viennent eth1.

Puis-je faire quelque chose pour améliorer les performances de cette machine virtuelle? Existe-t-il un moyen d'équilibrer les interruptions de manière plus égale?


Détails sanglants:

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

$ lsb_release -a
Aucun module LSB n'est disponible.
ID du distributeur: Ubuntu
Description: Ubuntu 11.04
Sortie: 11.04
Nom de code: natty

$ cat / proc / interruptions 
           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 événement xen-dyn 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 0 débogage xen-percpu-virq7
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 replanifié7
292: 0 0 0 0 0 0 0 0 60064 spinlock xen-percpu-ipi7
293: 0 0 0 0 0 0 0 0 12355510 Minuterie xen-percpu-virq7
294: 0 0 0 0 0 0 803174 0 xen-percpu-ipi callfuncsingle6
295: 0 0 0 0 0 0 0 0 0 débogage xen-percpu-virq6
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 replanifié6
298: 0 0 0 0 0 0 64976 0 spinlock xen-percpu-ipi6
299: 0 0 0 0 0 0 0 15294870 0 minuterie xen-percpu-virq6
300: 0 0 0 0 0 264441 0 0 xen-percpu-ipi callfuncsingle5
301: 0 0 0 0 0 0 0 0 0 débogage xen-percpu-virq5
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 replanifié5
304: 0 0 0 0 0 66269 0 0 spinlock xen-percpu-ipi5
305: 0 0 0 0 0 12778464 0 0 minuterie xen-percpu-virq5
306: 0 0 0 0 844591 0 0 0 xen-percpu-ipi callfuncsingle4
307: 0 0 0 0 0 0 0 0 0 débogage xen-percpu-virq4
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 replanifié4
310: 0 0 0 0 79312 0 0 0 spinlock xen-percpu-ipi4
311: 0 0 0 0 21642424 0 0 0 minuterie xen-percpu-virq4
312: 0 0 0 449141 0 0 0 0 xen-percpu-ipi callfuncsingle3
313: 0 0 0 0 0 0 0 0 0 débogage xen-percpu-virq3
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 replanifié3
316: 0 0 0 76607 0 0 0 0 spinlock xen-percpu-ipi3
317: 0 0 0 16439729 0 0 0 0 minuterie xen-percpu-virq3
318: 0 0 876383 0 0 0 0 0 xen-percpu-ipi callfuncsingle2
319: 0 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 replanifié2
322: 0 0 69217 0 0 0 0 0 spinlock xen-percpu-ipi2
323: 0 0 10247182 0 0 0 0 0 minuterie xen-percpu-virq2
324: 0 393514 0 0 0 0 0 0 xen-percpu-ipi callfuncsingle1
325: 0 0 0 0 0 0 0 0 0 débogage xen-percpu-virq1
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 replanifié1
328: 0 77823 0 0 0 0 0 0 spinlock xen-percpu-ipi1
329: 0 13784021 0 0 0 0 0 0 minuterie 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 0 débogage 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 replanifié0
334: 348740 0 0 0 0 0 0 0 spinlock xen-percpu-ipi0
335: 89912004 0 0 0 0 0 0 0 minuterie xen-percpu-virq0
NMI: 0 0 0 0 0 0 0 0 Interruptions non masquables
LOC: 0 0 0 0 0 0 0 0 Interruption de la minuterie locale
SPU: 0 0 0 0 0 0 0 0 Interruptions parasites
PMI: 0 0 0 0 0 0 0 0 Interruptions de surveillance des performances
IWI: 0 0 0 0 0 0 0 0 Interruptions de travail IRQ
RES: 3607120 3551629 3422476 3802992 3482146 3468144 5374762 3236015 Interruptions de rééchelonnement
CAL: 770084 489287 952799 544546 919884 343765 863201 373596 Interruptions d'appel de fonction
TLB: 0 0 0 0 0 0 0 0 0 Abattages TLB
TRM: 0 0 0 0 0 0 0 0 Interruptions d'événements thermiques
THR: 0 0 0 0 0 0 0 0 0 Interruptions seuil APIC
MCE: 0 0 0 0 0 0 0 0 Exceptions de vérification de la machine
MCP: 0 0 0 0 0 0 0 0 Sondages de vérification de la machine
ERR: 0
MIS: 0
Alexander Gladysh
la source
Question bonus: existe-t-il un moyen de réduire le nombre d'interruptions eth1?
Alexander Gladysh

Réponses:

10

Regardez dans le /proc/irq/283répertoire. Il existe un smp_affinity_listfichier qui indique quels processeurs recevront l'interruption 283. Pour vous, ce fichier contient probablement "0" (et smp_affinitycontient probablement "1").

Vous pouvez écrire la plage CPU dans le smp_affinity_listfichier:

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

Ou vous pouvez écrire un masque de bits, où chaque bit correspond à un CPU, pour smp_affinity:

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

Cependant, irqbalance est connu pour avoir sa propre idée de l'affinité que doit avoir chaque interruption, et il peut annuler vos mises à jour. Il est donc préférable de désinstaller complètement irqbalance. Ou au moins, arrêtez-le et désactivez-le lors du redémarrage.

Si même sans déséquilibre, vous devenez étrange smp_affinitypour l'interruption 283 après un redémarrage, vous devrez mettre à jour manuellement l'affinité CPU dans l'un de vos scripts de démarrage.

chutz
la source
irqbalanceest déjà en cours d'exécution. Peut-être qu'il n'est pas configuré correctement? Comment vérifier ça?
Alexander Gladysh
Peut-être que vous devriez simplement désactiver l'irqbalance, redémarrer, voir si cela aide. Les interruptions sont assez bien équilibrées par défaut.
chutz
FYI: /proc/irq/283/smp_affinitya 01en elle maintenant (personne n'a changé ce truc sur cette machine au meilleur de ma connaissance - donc ce doit être le système par défaut).
Alexander Gladysh
Désolé, j'ai mis à jour ma réponse. irqbalance est probablement le coupable. Débarrassez-vous-en. Je ne sais pas ce que le défaut est censé être, mais par expérience, je l'ai vu par défaut sur "TOUS les CPU".
chutz
La désactivation irqbalance(via ENABLED=0in /etc/default/irqbalance) n'aide pas. Après le redémarrage irqbalanceest stop/waiting, mais /proc/irq/283/smp_affinityest toujours 01.
Alexander Gladysh
2

Si vous avez le bon modèle de carte réseau Intel, vous pouvez améliorer considérablement les performances.

Pour citer le premier paragraphe:

Les processeurs multicœurs et les adaptateurs Ethernet les plus récents (y compris les 82575, 82576, 82598 et 82599) permettent d'optimiser les flux de transfert TCP en affectant des flux d'exécution aux cœurs individuels. Par défaut, Linux attribue automatiquement des interruptions aux cœurs de processeur. Il existe actuellement deux méthodes pour affecter automatiquement les interruptions, un équilibreur IRQ du noyau et le démon d'équilibre IRQ dans l'espace utilisateur. Les deux offrent des compromis qui peuvent réduire l'utilisation du processeur mais ne maximisent pas les taux de transfert IP. Un débit optimal peut être obtenu en épinglant manuellement les files d'attente de l'adaptateur Ethernet à des cœurs de processeur spécifiques.

Pour le transfert IP, une paire de files d'attente de transmission / réception doit utiliser le même cœur de processeur et réduire la synchronisation du cache entre différents cœurs. Cela peut être effectué en affectant des interruptions d'émission et de réception à des cœurs spécifiques. À partir du noyau Linux 2.6.27, plusieurs files d'attente peuvent être utilisées sur les 82575, 82576, 82598 et 82599. De plus, plusieurs files d'attente de transmission ont été activées dans les interruptions signalées de messagerie étendue (MSI-X). MSI-X prend en charge un plus grand nombre d'interruptions pouvant être utilisées, ce qui permet un contrôle plus fin et un ciblage des interruptions sur des CPU spécifiques.

Voir: Affectation d'interruptions aux cœurs de processeur à l'aide d'un contrôleur Ethernet Intel® 82575/82576 ou 82598/82599

Mat
la source
2

En fait, il est recommandé, en particulier lorsqu'il s'agit de processus répétitifs sur une courte durée, que toutes les interruptions générées par une file d'attente de périphériques soient gérées par le même processeur, au lieu de l'équilibrage IRQ et donc vous verrez de meilleures performances si un seul processeur gère l'interruption eth1 *** exception prévue ci-dessous

La source, liée ci-dessus, provient du Symposium Linux et je vous recommande de lire les quelques paragraphes sur SMP IRQ Affinity car cela vous convaincra plus efficacement que ce billet.

Pourquoi?

Rappelez-vous que chaque processeur a son propre cache en plus de pouvoir accéder à la mémoire principale, consultez ce diagramme . Lorsqu'une interruption est déclenchée, un cœur de processeur devra récupérer les instructions pour gérer l'interruption de la mémoire principale, ce qui prend beaucoup plus de temps que si les instructions se trouvaient dans le cache. Une fois qu'un processeur a exécuté une tâche, il aura ces instructions dans le cache. Supposons maintenant que le même cœur de processeur gère la même interruption presque tout le temps, la fonction de gestionnaire d'interruption quittera probablement le cache du cœur de processeur, ce qui augmentera les performances du noyau.

Alternativement, lorsque l'IRQ est équilibré, il peut affecter l'interruption à gérer en permanence par différents CPU, alors le nouveau noyau de CPU n'aura probablement pas la fonction de gestionnaire d'interruption dans le cache, et il faudra beaucoup de temps pour obtenir le gestionnaire approprié du principal Mémoire.

Exception : si vous utilisez rarement l'interruption eth1, ce qui signifie que suffisamment de temps s'écoule pour que le cache soit écrasé par d'autres tâches, ce qui signifie que des données arrivent par intermittence sur cette interface avec de longues périodes entre les deux ... alors vous ne verrez probablement pas ces avantages car ils le sont lorsque vous utilisez un processus à haute fréquence.

Conclusion

Si votre interruption se produit très fréquemment, il suffit de lier cette interruption pour qu'elle soit gérée par un processeur spécifique uniquement. Cette configuration vit à

 /proc/'IRQ number'/smp_affinity

ou

/proc/irq/'IRQ number'/smp_affinity

Voir le dernier paragraphe dans la section Affinité SMP IRQ de la source liée ci-dessus, il contient des instructions.

Alternativement

Vous pouvez modifier la fréquence à laquelle l'indicateur d'interruption est déclenché en augmentant la taille MTU (trames jumbo) si le réseau le permet ou modifier pour que l'indicateur soit levé après la réception d'une plus grande quantité de paquets au lieu de chaque paquet OU modifiez la expirer, augmentez donc l'interruption après un certain temps. Attention à l'option heure car votre taille de tampon peut être pleine avant la fin du temps. Cela peut être fait en utilisant l' ethtool qui est décrit dans la source liée.

cette réponse approche de la longueur à laquelle les gens ne la liront pas, donc je n'entrerai pas dans les détails, mais selon votre situation, il existe de nombreuses solutions ... vérifiez la source :)

frère-bilo
la source