Aujourd'hui, je vais parler des voyants rouges et verts clignotants et de la manière dont ils nous ont menés dans le cadre d'une longue enquête sur les performances qui s'est terminée profondément dans les pilotes PCI Express du noyau Linux.

(En outre, si vous ne l'avez pas déjà vu, consultez la deuxième partie de la série de blogs Road to All-Flash, par les gens qui ont construit la plate-forme dont je discute dans ce post.)

La ballade des lumières clignotantes.

Il y a environ un an, je travaillais sur notre nouveau Plateforme tout flash NVMe et un problème étrange est apparu.

En cas de défaillance d'un disque SSD, nous ne pouvions pas allumer le petit voyant rouge du lecteur pour indiquer celui qui devait être remplacé. En effet, un lecteur NVMe est connecté (plus ou moins) directement au processeur via PCI-Express, par opposition aux lecteurs SATA ou SAS, qui se connectent à un contrôleur distinct qui sait comment procéder, par exemple, allumer et éteindre les lumières.

Cela peut sembler anodin, mais un retour visuel dans le centre de données est important pour les administrateurs de stockage qui doivent remplacer le disque défectueux (et non le mauvais). Dans le meilleur des cas, le lecteur est tellement à plat que le voyant est éteint. Dans le pire des cas, l’administrateur de stockage est confronté à une mission périlleuse: un choix impossible. («Coupez le fil rouge!» «Quel fil rouge? Il y a vingt-quatre fils et ils sont tous verts!)

Heureusement, ce problème a une solution qui s'appelle Intel Volume Management Device (VMD). VMD est une fonctionnalité du complexe racine de certains processeurs Xeon pouvant agir en tant que délégué pour les événements NVMe et les acheminer vers des pilotes logiciels. En plus de savoir comment allumer et éteindre les lumières, il prend également en charge un branchement à chaud plus fiable - gagnant gagnant!

Eh bien, pas tout à fait.

Les gars du PC de jeu avaient raison. LED do impact sur les performances.

Lorsque nous avons activé l'utilisation de VMD, les choses ont ralenti. UNE lot Ralentissez. Nos tests de débit ont montré une régression de 50 ou supérieure, voire supérieure - un des workloads les plus touchés a atteint des vitesses proches de 15 Go / s, mais a maintenant du mal à atteindre 6 Go / s.

Au début, nous craignions que quelque chose dans le fonctionnement de VMD ne limite fondamentalement le débit que nous pourrions obtenir des disques SSD. VMD agit en quelque sorte comme un intermédiaire et l'un de ses effets consiste à créer un aliasing de plusieurs périphériques de stockage derrière un ensemble limité et partagé de vecteurs d'interruption. Sans VMD, chaque disque a ses propres vecteurs d’interruption qu’il n’a pas à partager. Nous soupçonnions que la controverse sur ces ressources d'interruption était ce qui nous ralentissait.

En fin de compte, nous étions presque droite.

Pendant que nous explorions nous-mêmes les données de performance, nous avons également contacté des spécialistes d'Intel pour nous aider à résoudre le problème. Leur aide s’est révélée précieuse pour identifier le véritable coupable de ce mystère.

Les moyennes peuvent être trompeuses et d'autres faits évidents

L'une des premières choses que nous avons examinées a été la latence moyenne des demandes d'E / S pour les disques dans les deux configurations - VMD off et VMD on. À notre grande surprise, la latence moyenne n’était pas très différente. C'était nettement plus élevé avec VMD, mais seulement un peu. Des graphiques comme celui-ci (à partir de données capturées lors d'un test d'écriture) étaient typiques:

Des microsecondes 10-15 supplémentaires par demande ne sont pas géniales, mais elles ne suffisent pas pour expliquer les% de pertes de débit de 50-60, même si nous étions totalement liés à la latence.

Pendant ce temps, les ingénieurs d’Intel scrutaient le code de leur pilote. Ils avaient connaissance de quelques problèmes mineurs et en avaient déjà corrigé les versions ultérieures du noyau par rapport à celle que nous utilisions. Ils nous ont donc fourni des correctifs, nous avons construit un module de noyau personnalisé et nous nous sommes lancés dans la course - mais ces corrections n'améliorent que légèrement les performances.

Ils ont découvert un autre problème: le pilote VMD ne prenait pas correctement en compte l'affinité CPU souhaitée des périphériques lors de l'affectation de vecteurs d'interruption. Le correctif pour résoudre ce problème a également ajouté une option de pilote, max_vec, qui régit le nombre maximal de vecteurs d'interruption que VMD tentera d'allouer pour chaque périphérique connecté. La valeur par défaut était auparavant 4.

Un autre patch, une autre série de reconstitutions du pilote et une autre série de tests - et, à notre grande satisfaction, les performances étaient considérablement meilleures. Mais il y avait aussi quelque chose de particulier. Lorsque nous avons essayé différentes valeurs pour max_vec, nous avons constaté que les performances diminuaient à mesure que la valeur augmentait:

Tester le débit contre max_vec
max_vec écrire lire
2 8,080 Mo / s 15,460 Mo / s
4 5,540 Mo / s 13,670 Mo / s
8 4,540 Mo / s 13,430 Mo / s

C'était inattendu. Finalement, nous avons décidé de revoir les données. Clairement, il nous manquait quelque chose. J'ai commencé à parcourir les données iostat à partir d'une multitude de tests de performance et j'ai rapidement découvert la pièce manquante: le les lecteurs n'étaient pas un peu plus lent. Exactement une le lecteur était beaucoup Ralentissez:

Lorsque j'ai montré ce complot à un ingénieur Intel, il a vécu l'un de ces moments «euréka». Après tout, le problème ne résidait pas dans VMD: il s'agissait d'un pilote pour un périphérique PCIe complètement séparé, un module de gestion intégré dans un commutateur Microsemi PCIe.

Rappelez-vous comment un VMD agit comme une sorte d’intermédiaire et gère ses périphériques connectés via un ensemble partagé de vecteurs d’interruption. Lorsque le VMD reçoit une interruption sur l'un de ces vecteurs, il ne sait pas nécessairement quel périphérique est la cible réelle. Donc, il doit effectivement invoquer les gestionnaires d'interruptions pour tout les appareils partageant ce vecteur. Si l'un de ces gestionnaires d'interruptions était plus lent que les autres, le reste serait simplement obligé d'attendre.

C'est exactement ce qui se passait. L’augmentation de max_vec au-delà de 2 a considérablement aggravé les choses, c’est que l’attribution de plus de vecteurs d’interruption à chaque périphérique augmentait la probabilité qu’un (ou plus!) SSD finisse par partager un vecteur avec le commutateur Microsemi. De plus, comme une seule opération d'écriture dans le système de fichiers de Qumulo sera codée en effacement sur plusieurs unités de stockage pour la protection des données, si un seul disque impliqué dans une écriture est lent, l'écriture entière sera lente.

Voici une version condensée du gestionnaire d’interruptions fautif, trouvée dans drivers / pci / switch / switchtec.c dans la source du noyau Linux:

static irqreturn_t switchtec_event_isr (int irq, void * dev)
{
struct switchtec_dev * stdev = dev;
u32 reg;
/ *… * /

reg = ioread32 (& stdev- & gt; mmio_part_cfg- & gt; mrpc_comp_hdr);
if (reg & SWITCHTEC_EVENT_OCCURRED) {
/ *… * /
iowrite32 (reg, & amp; stdev- & gt; mmio_part_cfg- & gt; mrpc_comp_hdr);
}

/ *… * /
}

Consultez ces appels vers ioread32 et iowrite32, en ciblant une adresse d'E / S mappée en mémoire sur le commutateur lui-même. Dans le cadre de la gestion d’une interruption, ce pilote effectue des E / S réelles sur le bus PCIe (!).

S'il devait y avoir un seul commandement d'écrire des pilotes de périphérique, un concurrent sérieux serait: «Vous ne ferez pas plus de travail que ce qui est absolument nécessaire dans un gestionnaire d'interruptions». Peut-être qu'attendre des E / S n'est pas une grosse affaire pour ce périphérique , mais cela devient un gros problème quand il finit par partager un vecteur d'interruption avec quelque chose d'extrêmement sensible au temps de latence!

Heureusement, la solution à ce problème était simple: ne chargez pas le module du noyau Switchtec. Nous n’avions besoin de aucune de ses fonctionnalités, et sans ce gestionnaire d’interruptions lent dans le mixage, nous étions de retour à la normale - avec une nos lumières clignotantes et colorées.

La morale de l'histoire

Les valeurs aberrantes peuvent être extrêmement importantes.

C'est une de ces choses que presque tout le monde "sait", mais c'est une chose facile à oublier, surtout lorsque vous poursuivez une hypothèse. Les moyennes sont utiles, après tout, car un seul chiffre peut vous en dire long sur un phénomène. Mais ne tirez pas trop de conclusions de la moyenne si vous ne comprenez pas la distribution sous-jacente!

Partager avec votre réseau