Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maitrise de la VMM #173

Open
NicolasFloquet opened this issue Dec 2, 2013 · 11 comments
Open

Maitrise de la VMM #173

NicolasFloquet opened this issue Dec 2, 2013 · 11 comments

Comments

@NicolasFloquet
Copy link
Member

Il faut admettre qu'on ne maitrise pas vraiment l'aspect VMM/Pagination dans TacOS.
Tant que ça sera le cas, on ne pourra pas envisager d'avoir de la SHM, un mmap ou des MMIO. On doit reprendre la main sur cette partie du code.
Cela passera je pense par les étapes suivantes:

  • Commenter / Document le code actuel pour mieux le comprendre
  • Refactorer le code. Pour le moment, c'est un mélange de fonctions utilitaires et d'autres choses, c'est pas très clair.

L'idée serait à la fin d'avoir une idée précise du layout de la mémoire physique et virtuelle.

@NicolasFloquet
Copy link
Member Author

A noter que pour la plupart des drivers utilisant des DMA ou le bus PCI, il est souvent question d'accès à des adresses physiques connues. Pour cette raison, avoir des interfaces simples pour mapper des adresses physiques dans l'adressage virtuel du kernel est très prioritaire.

@MaximeCheramy
Copy link
Member

Je te trouve un peu dur, si on a perdu la maîtrise, c'est surtout parce que ça a été fait au début du projet et qu'on a eu le temps d'oublier comment ça marchait. L'aspect VMM ainsi que la partie malloc, a été réalisée par NoWiS et la partie pagination par moi-même.

Niveau doc, on ne part pas de rien : https://github.com/TacOS-team/tacos/wiki/VMM et https://github.com/TacOS-team/tacos/wiki/Pagination

Je n'ai bien sûr rien contre la proposition : commenter/documenter le code ne fera pas de mal, c'est une partie assez complexe et ultra importante. Aucun problème pour le refactoring, si tu juges que certaines parties pourraient être mieux faites, vas-y.

@NicolasFloquet
Copy link
Member Author

Oui bon j'exagère un peu, ceci dit je pense quand même qu'il nous manque un peu de maitrise pour pouvoir faire des choses simples comme mapper de la mémoire commune entre deux process (pourtant y'a pas de réelle difficulté en théorie)

@MaximeCheramy
Copy link
Member

Je faisais un peu joujou ce matin :

  • J'ai tenté de modifier le First Fit pour trouver un slab avec assez de place en Next Fit. Je n'ai pas noté de gain, j'ai reverté mon code puisque ça rajoutait un peu de complexité.
  • Je vois qu'on fait une insertion triée des slabs par ordre de mémoire. J'aimerais savoir si et pourquoi c'est utile. J'ai tenté de remplacer le add par un push_back et ça n'a pas provoqué de régression apparente.

@NoWiS- Est-ce que tu peux nous éclairer ?

@NicolasFloquet
Copy link
Member Author

Note: quand il s'agit de gestion de mémoire, je me méfie toujours de l'absense de regression apparente...

@MaximeCheramy
Copy link
Member

Note: j'ai aussi reverté en attendant une réponse claire.

@NicolasFloquet
Copy link
Member Author

Vu que c'est un sujet qui ne devrait pas faire changer les interfaces mais seulement la façon dont sa fonctionne, je suggère une branche refactoring vmm

@NoWiS-
Copy link
Member

NoWiS- commented Dec 10, 2013

Alors, j'ai re-regarder un peu le code.
Dans l'idée, je voulais éviter la fragmentation, mais ça n'a jamais vraiment été fini. L'intuition c'était, lorsque malloc n'a plus besoin d'une page, il demande la désallocation de la page (via unallocate_page) mais dans l'état malloc ne le fait jamais (le syscall n'existe même pas).
De plus, j'étais pas sur que ça soit pas très pertinent du côté vmm (surement plus du côté malloc).

Je ne pense pas qu'en l'état passer à un push_back ne devrait pas amener de régression.

Comme je l'avais déjà dis, je pense que le plus simple serait probablement de repartir de zéro. En ayant plus en tête ces histoire d'extension pour de la mémoire partagé, fichier etc...

@NicolasFloquet
Copy link
Member Author

Repartir à 0? mais ça avait l'air tellement bien fait!

MaximeCheramy added a commit that referenced this issue Dec 19, 2014
Plus de 10 fois plus rapide au bout d'un moment. #173
@MaximeCheramy
Copy link
Member

Je songe à travailler un peu sur cette partie. J'aimerais débloquer tout ce qui est mmap, on doit pouvoir gagner énormément en perf.

@MaximeCheramy
Copy link
Member

Je me suis plongé dedans, et lorsque je pense avoir compris, je tombe toujours sur un truc qui fait que je me pose d'autres questions, etc... Alors quelques remarques :

  • Dans le kernel, on a kmalloc qui s'occupe de refiler des morceaux de la taille demandée en cherchant dans sa mémoire, et s'il a besoin de plus de place il fait appel à vmm pour qu'il lui refile de la place. vmm lui fait comme kmalloc mais avec des ensembles consécutifs de page. Dit comme ça, on pourrait peut être se demander si kmalloc et vmm ne pourraient pas faire qu'un. Probablement mais c'est pas plus mal pour diverses raisons.
  • On parle de slabs dans la vmm, donc j'ai voulu me renseigner et je ne comprenais pas pourquoi ça correspondait pas aux slabs tels qu'on les retrouve dans Linux par exemple. Définition wikipedia :

Slab allocation is a memory management mechanism intended for the efficient memory allocation of kernel objects. It eliminates fragmentation caused by allocations and deallocations. The technique is used to retain allocated memory that contains a data object of a certain type for reuse upon subsequent allocations of objects of the same type. It is analogous to an object pool, but only applies to memory, not other resources.

De ce que j'ai pu en comprendre, l'idée c'est de ne pas avoir un seul allocateur (kmalloc) mais tout un ensemble d'allocateurs spécialisés dans des morceaux de taille identique. Voir cat /proc/slabinfo sous Linux pour avoir la liste des allocateurs. Le fonctionnement d'un allocateur est trivial : il prend un "slab", le découpe en morceaux de taille identique et distribue ou libère les morceaux à la demande. Il n'y a plus de problème de fragmentation car tous les morceaux ont la même taille ! Et le traitement est plus rapide car il n'y a plus besoin de maintenir des listes chainées des éléments libres.

Bref, à garder dans un coin de la tête car il y a probablement moyen d'accélérer les perfs du système avec des allocateurs spécialisés.

  • Au niveau du mapping mémoire, kmalloc utilise l'objet "kvm" (kernel virtual memory) qui représente un heap partant de la fin du kernel et qui remonte. Sans limite haute donc potentiellement on peut au bout d'un moment essayer de mapper 2 adresses physiques sur la même adresse virtuelle. Les process utilisent un objet vm qui map à partir de 1Gio (virtuel). Le programme et la stack sont mappés au début de ces 1Gio, le malloc utilisera des adresses situées au dessus.
  • Je suis encore un peu dans le flou en ce qui concerne les reconfigurations du MMU. Je ne sais pas si on fait n'importe quoi ou si c'est juste moi qui ne comprend pas. Au début on a une pagination du kernel en identity mapping qui est chargée. Lors de la création d'un nouveau process, on crée une nouvelle table pour la pagination (kprocess.c:334) et on y recopie le début du kernel. Première remarque : et tout ce qui a été kmalloc'é, c'est pas recopié donc ? Ça me surprend mais c'est vrai qu'on est encore très stateless en dehors de ce qui est explicitement stocké dans les objets process donc ça pourrait quand même marcher. Faudrait enquêter sur ça. Et de manière générale, toutes les pages allouées plus tard pour kmalloc ne le sont que pour un process en particulier ? Est-ce qu'on ne devrait pas charger la pagination du kernel à chaque syscall ? Et les tables de pagination des process n'ont finalement besoin du kernel que pour acceder aux méthodes des syscall.

Initialement j'avais pour objectif de coder mmap : suffit de réserver une région dans l'adressage virtuel et y associer un fichier ou rien si on veut juste des 0. Lors d'une tentative d'accès à une adresse de cette région, on parcours les régions pour identifier la bonne et on recopie dans la mémoire physique les données qui vont bien. Dans la théorie c'est simple, mais il faut s'emboiter avec l'existant... D'où les questions de tables pas forcément à jour ce qui peut poser des problèmes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants