Pourquoi les numéros d'appel système Linux en x86 et x86_64 sont-ils différents?

35

Je sais que l'interface d'appel système est implémentée à un niveau bas et dépend donc de l'architecture / de la plateforme, pas du code "générique".

Cependant, je ne vois pas clairement pourquoi les appels système dans les noyaux Linux 32 bits x86 ont des numéros qui ne sont pas conservés de la même façon dans l'architecture similaire Linux 64 bits x86_64? Quelle est la motivation / raison derrière cette décision?

Ma première hypothèse était qu'une raison en arrière-plan consistait à laisser les applications 32 bits exécutables sur un système x86_64, de sorte que, via un décalage raisonnable vers le numéro d'appel du système, le système sache que l'espace utilisateur est de 32 ou 64 bits. respectivement. Ceci est cependant pas le cas. Au moins, il me semble que read () étant le numéro d'appel système 0 dans x86_64 ne peut pas être aligné sur cette idée.

Une autre hypothèse est que la modification des numéros d'appel système pourrait avoir un arrière-plan de sécurité / renforcement, ce que je n'ai pas pu confirmer moi-même.

Ignorant les défis de la mise en œuvre des parties de code dépendantes de l'architecture, je me demande encore comment changer les numéros d'appel système , quand il ne semble pas nécessaire (car même un registre 16 bits stockerait beaucoup plus que les ~ 346 numéros actuels pour représenter tous appels), aiderait à réaliser quoi que ce soit, mis à part rompre la compatibilité (bien que l’utilisation des appels système via une bibliothèque, libc, l’atténue).

humanitéet paix
la source
3
Je pense que vous posez la mauvaise question. La bonne question est pourquoi les garder les mêmes: Réponse compatibilité. Donc, si x86 et x86_64 sont incompatibles, aucune force ne les empêche de changer. Désormais, toutes les forces des 20 dernières années qui souhaitaient un changement domineront (nous aurons une chance de les changer). [Notez qu'il ne s'agit que d'une opinion et non de l'esprit des concepteurs du nouveau système.]
ctrl-alt-delor

Réponses:

34

En ce qui concerne le raisonnement derrière la numérotation spécifique, qui ne correspond à aucune autre architecture [à l'exception de "x32" qui ne fait en réalité que partie de l'architecture x86_64]: Au tout début du support x86_64 dans le noyau Linux, il n'y en avait pas contraintes de compatibilité ascendante graves, tous les appels système ont été renumérotés pour l’optimiser au niveau d’utilisation de la cacheline .

Je ne sais pas assez sur le développement du noyau de connaître la base spécifique pour ces choix, mais apparemment , il y a un certain logique derrière le choix de tout renumérotation avec ces chiffres particuliers plutôt que de simplement copier la liste à partir d' une architecture existante et supprimer ceux non utilisés. Il semble que l'ordre puisse être basé sur la fréquence à laquelle ils sont appelés (par exemple, lecture / écriture / ouverture / fermeture sont au premier plan). Exit et fork peuvent sembler "fondamentaux", mais ils ne sont appelés qu'une seule fois par processus.

Il se peut également que quelque chose soit en cours pour conserver les appels système couramment utilisés ensemble dans la même ligne de cache (ces valeurs ne sont que des entiers, mais il existe dans le noyau une table avec des pointeurs de fonction pour chacun, de sorte que chaque groupe de 8 appels système occupe une ligne de cache de 64 octets pour cette table)

Au hasard832
la source
1
fork may seem "fundamental", but [...] called only once per process.Quoi? Si j'ai bien compris, vous pouvez vous attendre à appeler la sortie une fois, mais vous pouvez vous rapprocher du parent et de l'enfant d'un fork()appel
Cat
5
@cat si vous considérez forkque le processus enfant est comptabilisé (c.-à-d. visualisez-le comme l'appel de création du processus), plutôt que le processus parent, l'instruction de Random832 est correcte.
icarus
4
@cat OK, vous pouvez appeler fork () deux ou trois fois, peut-être un peu plus. Mais vous pouvez appeler read () des millions, voire des milliards de fois.
Michael Hampton
1
Oui, c'est ce que je voulais dire. Le nombre d'appels fork et le nombre de processus au cours de la durée de vie du système vont être identiques, ignorant des détails tels que init, clone [pouvant créer des processus ou des threads], etc.
Random832
15

Voir la réponse à la question "Pourquoi les numéros d’appel système sont-ils différents dans amd64 linux?" débordement de pile.

En résumé: pour des raisons de compatibilité, la liste des appels système est stable et ne peut que s'allonger. Lorsque l’architecture x86 64 est apparue, l’ABI (argument passant, valeur renvoyée) était différente, les développeurs du noyau ont donc profité de l’occasion pour apporter des modifications tant attendues.

xhienne
la source
Cool, je suppose que c'était correct.
ctrl-alt-delor
2
Cette autre réponse à laquelle vous associez est spéculative: elle dit "les gars de Linux qui ont probablement décidé ..." (italiques ajoutés). Je pense que cela aiderait si votre réponse ici donnait une indication du fait que cela est apparemment basé sur des spéculations plutôt que sur des preuves. Incidemment, un commentaire plus récent posté sous la réponse liée indique que la vraie raison n'est pas le nettoyage générique de cruft (comme le spécule cette réponse), mais concerne spécifiquement "l'utilisation de la cacheline", comme expliqué dans l'autre réponse ici .
DW
-3

En bref, parce que quelqu'un pensait que "des N+1manières de le faire gratuitement incompatibles sont meilleures que des Nmanières". Pour les arcs historiques, les numéros d'appels système étaient généralement choisis pour correspondre à un unix propriétaire hérité. Mais pour x86_64, les développeurs du noyau étaient libres de choisir la numérotation de leur choix. Plutôt que de faire le simple choix et de réutiliser une numérotation existante, ils ont choisi d’inventer une nouvelle norme. Ensuite, ils l'ont fait à nouveau pour aarch64 et pour un groupe d'autres. C'est un motif souvent répété dans le développement du noyau Linux.

R ..
la source
3
Le changement n'était pas gratuit. Il y a de bonnes raisons techniques. S'il n'y avait pas eu d'exigences de compatibilité ascendante, des modifications similaires auraient également été appliquées aux architectures existantes.
Jörg W Mittag
La différence de numérotation est 100% gratuite. Il n'y a aucun avantage technique à une numérotation particulière.
R ..
2
Comme cette autre réponse l' explique, les appels système sont groupés de manière à ce que les appels système couramment utilisés partagent la même cacheline dans la table syscall. Et les numéros d' appels système sont choisis de manière à constituer de simples index dans cette table. Théoriquement, nous pourrions utiliser une couche d'indirection pour découpler la position d'un appel système dans la table d'appels système du nombre d'appels système, mais cela absorberait peut-être une partie des gains de performance obtenus en plaçant des appels système à chaud dans la même cacheline.
Jörg W Mittag Le
@ JörgWMittag: Et c'est évidemment une optimisation prématurée et non une amélioration mesurable. Il suffit de regarder combien de cycles les appels système prennent et combien de lignes de cache ils expulsent. Enregistrer au mieux une ligne de cache de la commande de la table ne fera aucune différence.
R ..
2
@R .. "J'ai choisi la numérotation en fonction des informations de profilage du noyau tpcc avec le SGBD populaire et la sortie strace de certaines applications de réseau et de bureau." Cela ressemble certainement à des mesures. Cependant, l'auteur n'a pas fourni de chiffres ni expliqué adéquatement la méthodologie.
user45891