Localiser le porc du noyau CPU occasionnel

11

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?

awy
la source
2
Points bonus pour la question intéressante. Je ne sais pas comment y répondre, mais j'ai une question sur la façon de le suivre jusqu'à l'utilisation du processeur (par opposition aux pics dans iowait, par exemple)?
Bratchley
1
La première supposition est de savoir si vous utilisez JFFS2 ou YAFFS sur un grand flash NAND, surtout si vous enregistrez. Désactivez tout ce qui écrit sur flash et voyez si cela aide. À quoi ressemble votre table de processus? Vous pouvez utiliser ftrace en dernier recours si vous disposez d'une chaîne d'outils pour construire le noyau.
Jonathan Ben-Avraham
sar -bu pourrait le faire .. linux.die.net/man/1/sar
Grizly
Il y a du flash en cours d'utilisation; une carte SD avec un système de fichiers ext4 monté. Et y écrire est en effet une source possible de ces problèmes (mais pourquoi, exactement?) Mais probablement pas le seul.
awy

Réponses:

1

perfpeut vous être utile. Il fait partie des utilitaires du noyau linux.

Par exemple:

perf record -R -a -g fp -e cycles -e syscalls:sys_enter_poll -e syscalls:sys_exit_poll
#Just ctrl+c if you are done, and view ith
perf script 

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]).

Zulan
la source
Je vais chercher à construire des performances pour la plate-forme - merci pour l'astuce.
awy
0

Peut-être atoppeut é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 sardans 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 :-)

trapicki
la source