diff --git a/content/packet_drop.mdown b/content/packet_drop.mdown index be7f4c9..ec0aa19 100644 --- a/content/packet_drop.mdown +++ b/content/packet_drop.mdown @@ -47,11 +47,11 @@ $ ethtool -S eth3 | grep rx_discard rx_discards: 1411 ``` -Au passage, on constate que les cartes réseau de ces machines ont 8 files de traitement des paquets. `ethtool -l` nous indique que l'ont pourrait passer à 30 files, combinée, c'est à dire qu'il faut toujours un nombre pair et que deux files sont liées, l'une pour la réception (RX) et l'autre pour la trasmission (TX). +Au passage, on constate que les cartes réseau de ces machines ont 8 files de traitement des paquets. `ethtool -l` nous indique que l'ont pourrait passer à 30 files, combinées, c'est à dire qu'il faut toujours un nombre pair et que deux files sont liées, l'une pour la réception (RX) et l'autre pour la trasmission (TX). ## rx buffer -Après quelques recherches, en particulier à l'aide de cet article, [Monitoring and Tuning the Linux Networking Stack: Receiving Data](https://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-linux-networking-stack-receiving-data/), il a été constaté que la taille du ring buffer du driver réseau était configurée à une valeur assez basse défaut : +Après quelques recherches, en particulier à l'aide de cet article, [Monitoring and Tuning the Linux Networking Stack: Receiving Data](https://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-linux-networking-stack-receiving-data/), il a été constaté que la taille du ring buffer du driver réseau était configurée à une valeur assez basse par défaut : ```console $ ethtool -g eth3 @@ -68,12 +68,12 @@ RX Jumbo: 0 TX: 4078 ``` -Mon anaylse est que les CPU de ces machines, servant au CI, sont soumis à des pics de charge, assez long lors des builds que le noyau n'a pas le temps de dépiler tous les paquets réseau arrivant dans le ring buffer entre la carte et le noyau. Ainsi, les anciens paquets non traités sont droppés. +Mon analyse est que les CPU de ces machines, servant au CI, sont soumis à des pics de charge, assez longs lors des builds et que le noyau n'a pas le temps de dépiler tous les paquets réseau arrivant dans le ring buffer entre la carte et le noyau. Ainsi, les anciens paquets non traités sont droppés. ## /proc/net/softnet_stat -Un autre extrait de l'article traitant cette fois de la gestion des interruption réseau. Le traitement se fait à l'aide de la couche NAPI, qui est une optimisation du traitement des interruptions réseau, pour ne pas générer une interruption par paquet réseau, comme c'était le cas à l'origine, et ainsi pouvoir traiter de fortes charges réseau, sans monopiloser le CPU. +Un autre extrait de l'article traitant cette fois de la gestion des interruptions réseau. Le traitement se fait à l'aide de la couche NAPI, qui est une optimisation du traitement des interruptions réseau, pour ne pas générer une interruption par paquet réseau, comme c'était le cas à l'origine, et ainsi pouvoir traiter de fortes charges réseau, sans monopoliser le CPU. Ce mécanisme désactive les interruptions matérielles et ce sont les interruptions logicielles qui sont en charge de venir traiter régulièrement le contenu du buffer de la carte réseau. Toujours dans une optique de ne pas monopoliser le CPU à ce traitement, ce processus a une limite de temps allouée à chaque passage, nommée `budget`. @@ -101,11 +101,11 @@ $ cat /proc/net/softnet_stat Un extrait de la doc pour lire ça : (TL;DR, la deuxième indique les paquets droppés par manque de place et la troisième colonne indique le nombre de dépassements de budget) -Each line of /proc/net/softnet_stat corresponds to a struct softnet_data structure, of which there is 1 per CPU. -The values are separated by a single space and are displayed in hexadecimal -The first value, sd->processed, is the number of network frames processed. This can be more than the total number of network frames received if you are using ethernet bonding. There are cases where the ethernet bonding driver will trigger network data to be re-processed, which would increment the sd->processed count more than once for the same packet. -The second value, sd->dropped, is the number of network frames dropped because there was no room on the processing queue. More on this later. -The third value, sd->time_squeeze, is (as we saw) the number of times the net_rx_action loop terminated because the budget was consumed or the time limit was reached, but more work could have been. Increasing the budget as explained earlier can help reduce this. +> Each line of /proc/net/softnet_stat corresponds to a struct softnet_data structure, of which there is 1 per CPU. +> The values are separated by a single space and are displayed in hexadecimal +> The first value, sd->processed, is the number of network frames processed. This can be more than the total number of network frames received if you are using ethernet bonding. There are cases where the ethernet bonding driver will trigger network data to be re-processed, which would increment the sd->processed count more than once for the same packet. +> The second value, sd->dropped, is the number of network frames dropped because there was no room on the processing queue. More on this later. +> The third value, sd->time_squeeze, is (as we saw) the number of times the net_rx_action loop terminated because the budget was consumed or the time limit was reached, but more work could have been. Increasing the budget as explained earlier can help reduce this. Finalement, et contrairement à ce que je pensais au début, dans l'exemple collecté, ça ne serait peut-être pas tant la place dans le buffer qui manquerait, mais le temps pour le traiter. @@ -113,18 +113,18 @@ Finalement, et contrairement à ce que je pensais au début, dans l'exemple coll ## Actions envisagées -- allouer plus de `budget` pour traiter le contenu de ce buffer - action à chaud : `sysctl -w net.core.netdev_budget=600` (l'unité étant le paquet traité, le temps étant plafonné à 2 jiffies, la valeur par défaut est 300) -- augmenter la taille du ring buffer, à 1024 voir au max à 4096 - /!\ fait un down/up sur la carte réseau donc drop toutes les connexions en cours - `ethtool -G ethX rx 1024` +- allouer plus de `budget` pour traiter le contenu de ce buffer - action à chaud : `sysctl -w net.core.netdev_budget=600` (l'unité étant le paquet traité, le temps étant plafonné à 2 jiffies, il y a un effet de seuil dans l'augmentation de la valeur. Par défaut le budget est de 300) +- augmenter la taille du ring buffer, à 1024 voir au max à 4096 - ⚠️ fait un down/up sur la carte réseau donc drop toutes les connexions en cours ⚠️ - `ethtool -G ethX rx 1024` ## Next steps Si cela ne suffit pas, d'autres pistes peuvent être explorées : -- irqbalance et le fait de répartir les gestionnaires d'interruptions sur tous plusieurs coeurs et de ne surtout pas en avoir plusieurs sur le même coeur. Le budget étant assigné à un coeur, si plusieurs gestionnaires d'interruptions sont assignés au même coeur, ils partageront le même budget. +- irqbalance et le fait de répartir les gestionnaires d'interruptions sur tous plusieurs cœurs et de ne surtout pas en avoir plusieurs sur le même coeur. Le budget étant assigné à un coeur, si plusieurs gestionnaires d'interruptions sont assignés au même coeur, ils partageront le même budget. A noter qu'un équilibrage automatique est réalisé sur les systèmes "modernes", nos centos 7 ont un process irqbalance qui tourne. Je ne m'attends donc pas de progrès de ce côté là, mais je n'ai pas creusé. -## ressources documentaires +## Quelques ressources documentaires - L'article expliquant comment les données réseau sont reçues par le noyau : [Monitoring and Tuning the Linux Networking Stack: Receiving Data](https://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-linux-networking-stack-receiving-data/) - Le site de [NAPI](https://wiki.linuxfoundation.org/networking/napi)