J'écris un pilote de noyau où j'ai besoin de vérifier quel thread est en cours d'exécution à un certain point sur un autre c? Ur. Mon pilote exécute un thread noyau par noyau et j'ai besoin de synchroniser de temps en temps certains threads pour effectuer certaines tâches. Ce que je peux observer à partir des journaux de débogage est que parfois un thread attend trop d'autres threads. J'ai fait un patch où je stocke le __preempt_count
sur d'autres cœurs pour vérifier si n'importe quel softirq/hardirq ou préemption désactivé retarde mon fil. J'ai également utilisé la fonction FTRACE pour vérifier les options irqsoff et preemptirqsoff pour la durée maximale des interruptions IRQ et la préemption désactivée. Jusqu'à présent, j'étais capable de repérer les threads kerneloops qui désactivent les interruptions jusqu'à 20msec, ce que je trouve trop long. A fait un systemctl disable kerneloops
et s'est débarrassé de ce problème.Accéder au pointeur "current_task" d'une autre unité centrale dans un système Linux basé sur SMP
Maintenant, je semble traiter de certaines fenêtres désactivées de préemption. Pour l'analyse future de ce pilote, j'ai besoin d'un moyen de déterminer quels threads sont en cours d'exécution à un moment donné sur d'autres cœurs. J'essaye d'employer FTRACE principalement avec des événements pour l'entrée/sortie d'IRQ, j'utilise également trace_printk
pour pousser quelque log de débogage dans le tampon de ftrace pour avoir tout dans un journal, etc.
Cependant, une chose que je voudrais comme à faire est d'accéder à la structure current_task
des autres cœurs (le current
ptr) et d'imprimer le champ comm
qui donne le nom de la tâche (ou la valeur pid). Mais j'ai du mal à faire ça.
Pour __preempt_count
Je n'avais pas question:
int *p = per_cpu_ptr(&__preempt_count,cpu);
pr_info("Preempt count of cpu%u is 0x%08x\n",cpu,*p);
Jusqu'à présent, j'eu aucun problème avec la déclaration ou l'accès par des variables cpu, mais pour une raison quelconque, le pointeur current_task
déclenche une erreur de page lorsque vous essayez d'y accéder.
char buf[10];
struct task_struct *task = per_cpu_ptr(current_task,cpu);
snprintf(buf,8,"%s",task->comm);
pr_info("Task name: %s",buf);
Le code ci-dessus déclenche toujours une erreur de page, NULL ptr bla bla. Je ne pouvais pas trouver la raison jusqu'à maintenant. J'ai essayé d'imprimer la valeur du pointeur pour task
, j'ai eu la même erreur de page. Est-ce parce que l'adresse n'est pas accessible par d'autres cœurs? Dans l'espace du noyau ne devrait pas être le cas afaik. Je n'avais pas non plus de problème avec les variables de base et j'ai beaucoup joué avec ça.
Conclusion: quelle serait la bonne approche pour accéder aux current_task
des autres cœurs et imprimer les champs comm/pid?
Merci beaucoup,
Daniel