J'ai un noyau 2.6.35 PREEMPT fonctionnant sur un processeur ARMv7 à vitesse modérée. Environ une fois toutes les 100 à 125 secondes, quelque chose fait que le noyau ne parvient pas à traiter certains pilotes liés à l'audio suffisamment rapidement pour éviter les sous-exécutions. Le hold-up est généralement compris entre 15 et 30 ms, mais peut être beaucoup plus long. Il n'est pas clair si le blocage est entièrement dans le noyau ou peut être lié à la planification d'un processus utilisateur fonctionnant avec une priorité en temps réel (SCHED_RR, 2).
Je suppose qu'il y a (au moins un) pilote qui ne joue pas bien avec préemption.
Une sortie strace du processus utilisateur illustre un aspect du comportement normal et anormal, bien que je ne sois pas certain comment interpréter les différents rapports de temps?
Cas normal:
0,000518 sondage ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3415) = 1 0.010202 sondage ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3404) = 1 0,000585 sondage ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3404) = 1 0,000302 sondage ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3404) = 1 0.010706 sondage ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3393) = 1 0,000480 sondage ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3392) = 1
Aucun blocage ne se produit sur l'interrogation pour la sortie sur fd6 et, lorsque seul fd10 est interrogé pour l'entrée, un bloc d'environ 10 ms se produit. Cela se reflète à la fois dans le rapport de la durée de l'appel système et de l'intervalle entre les appels système (ils sont cohérents).
Cas d'échec (exemple extrême):
0,000305 sondage ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3543) = 1 0.010730 sondage ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3533) = 1 0,000475 sondage ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3532) = 1 0,000329 sondage ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3532) = 1 0,953349 sondage ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT | POLLERR}], 2, 2578) = 1
Notez dans ce cas que, même si l'avant-dernier appel est enregistré comme prenant 10 ms (normal), il reste 953 ms avant le dernier appel.
Quels outils puis-je utiliser pour retrouver le coupable?
Réponses:
perf
peut vous être utile. Il fait partie des utilitaires du noyau linux.Par exemple:
Il affichera tous les temps et paramètres d'entrée / sortie de syscall (comme strace), fournira le nom du binaire appelant le syscall et échantillonnera la pile d'appels de chaque CPU à une certaine fréquence (y compris les symboles du noyau). Vous pouvez donc réellement voir quel code a été exécuté lors de l'appel système. Dans un système multiprocesseur, vous devez faire attention à l'identifiant du processeur (par exemple [001]).
la source
Peut-être
atop
peut éclairer votre problème.Il peut afficher les processus qui se sont déjà terminés et il peut afficher l'utilisation du processeur , de la mémoire , du disque et du réseau .
Vous pouvez l'exécuter de manière interactive, le laisser écrire dans un fichier texte ou l'exécuter comme
sar
dans un intervalle prédéfini, créant un fichier d'historique binaire que vous pourrez parcourir ensuite.Je l'utilise pour trouver des porcs de toutes sortes difficiles à trouver :-)
la source