[SOS] Gestion de la mémoire, physique, paginée, virtuelle...

David Decotigny david.decotigny at free.fr
Sam 15 Avr 15:04:19 CEST 2006


Bonjour,

Bombela wrote:
> Mais tout d'abord, laissez moi vous décrire cette gestion comme je l'ai
> comprise actuellement.

[ ... ]

Il n'y a rien à redire à ce résumé. Tous les éléments importants sont là
et corrects ! Ca fait plaisir ;)

> De plus, je crois que c'est ce gestionnaire qui doit gérer l'allocation
> de plus petit objet
> (allocateur slab etc...).

En gros oui. Plus precisement : il y a un gestionnaire de regions
virtuelles (des intervalles de X pages virtuelles contigues) qui permet
a l'allocateur SLAB de fonctionner. Cet allocateur SLAB permet d'allouer
des objets de petite taille (< 1 page) dans les regions virtuelles. Les
deux sous-systemes (gestionnaire de mem virtuelle / SLAB) sont
interdependants dans SOS, d'où probablement ton hesitation. Dans une
possible 2eme iteration de SOS, je pense qu'on supprimera cette
inter-dependance pour simplifier les explications et la comprehension.

> Ce gestionnaire doit :
>  * Permettre une relation entre le gestionnaire de mémoire paginée
>        et le gestionnaire de mémoire physique.
>  * Gérer le callback de page fault de la mémoire paginée pour gérer le
> swap, mappage de fichier
>       ou erreur de programmation.

Dans les faits on n'utilise pas le demand-paging dans le noyau. On ne
l'utilise que dans le premier article sur la VMM pour montrer ce qu'est
le demand-paging. Mais par la suite on ne l'utilise plus dans le noyau,
il intervient seulement en cas de page fault en espace user. Donc la
gestion du callback de page fault par ce gestionnaire VMM se reduit en
pratique a la signalisation d'une erreur de programmation. Dans une
possible 2eme iteration de SOS, je ne sais pas si on gardera cette
possibilite de demand-paging dans le noyau.

> Mais ! Comment faire pour allouer des pages physique alignée pour le dma
> par exemple ?
> Les périphérique PCI ? La mémoire vidéo (Si on change de framebuffer par
> défaut)
> De plus, on ne peut pas allouer n'importe quel endroit de la ram !
> Dans le cas du DMA, c'est en dessous des 16 mo...

Tu mets le doigt sur un aspect delicat de SOS : veut-on faire simple ou
"qui marche a tous les coups" ?

Dans l'article sur la mem physique, on a signalé comment ça marchait
dans Linux (vrai allocateur d'intervalles confondu avec l'alloc
d'intervalles virtuels car identity mapping + notion de zones classées
par priorité). Eh bien dans SOS on s'est posé la question de savoir si
il fallait suivre une demarche similaire, à savoir avoir un allocateur
de memoire physique capable de gerer des intervalles de memoire
physique, et eventuellement les regrouper dans des zones (ISA DMA, ...).
Dans le cadre de SOS, la question qui s'est posée était donc la suivante
: est-ce que ca ne va pas porter a confusion d'avoir 2 mecanismes
quasiment identiques (un allocateur d'intervalles pour la RAM, un autre
pour la VMM) ?... Par exemple, sous Linux cette confusion n'existe pas :
la VMM noyau est un identity mapping de la RAM < 1GB. Donc dans SOS on
se serait retrouves avec un OS "Simple" plus délicat à expliquer (risque
de confusion) qu'un "vrai" OS qui marche et fait le café... Un comble !
C'est en gros pourquoi on a choisi de se passer d'un allocateur de
memoire physique digne de ce nom.

Cependant, avec le recul, cette solution ne me satisfait qu'a moitié.
Donc un "vrai" allocateur de memoire physique est dans notre TODO,
probable que ce soit mis en oeuvre dans une prochaine iteration de SOS.
En attendant, dans l'iteration de SOS en cours, on n'a pas besoin d'un
tel allocateur. En effet, le seul peripherique "externe" que nous
utilisons (une carte PCI reseau RTL8029) est attaqué par le bus I/O en
PIO, pas par son mapping sur le bus de memoire physique, encore moins
par acces DMA.

Pour une utilisation de SOS grandeur nature, soit il faudra revoir
l'allocateur de mem physique (alloc intervalles + eventuellement notion
de zones avec priorites d'allocation). Soit on se restreindra seulement
au support de certains peripheriques PCI "evolués" : de plus en plus de
peripheriques PCI permettent en effet le DMA en mode "scatter-gather",
ce qui signifie qu'ils sont capables d'eclater le DMA sur plusieurs
pages non contigües ; pour ces periph, plus besoin donc de se soucier de
pages contiguës en RAM ! Ce n'est pas le cas de la RTL8029, d'où le
choix de l'acces en PIO. Ou alors, pour les plus fous, il faudra
regarder du cote d'un portage sur amd64 pour l'utilisation du MMIO (si
adapté ...) qui, semble-t'il, rend ce scatter-gather possible meme pour
les peripheriques PCI qui ne le supportent pas (a confirmer par ceux qui
connaissent).

> 
> Pour le cas ou la ram physique est déjà utiliser, le gestionnaire de
> mémoire virtuelle peut s'en occuper.
> En effet, il peut allouer des pages physique ailleur dans la mémoire,
> recopier dedans la page à libérer,
> et "déplacer" la page de mémoire paginée dessus. SOS le fait très bien
> dans un exemple.

Tout à fait. D'ailleurs nous avons présenté une démonstration "amusante"
de ce petit jeu dans le premier article sur la VMM. On deplaçait la page
de code noyau en cours d'exécution sur une autre page physique.

> Mais une question : Comment le gestionnaire de mémoire virtuelle fait
> pour allouer
> des pages physique "ailleur" ? On doit donc ajouter une méthode dans
> notre gestionnaire de mémoire
> physique, qui permet de définir une adresse minimum d'allocation...
> (Dite moi si je me trompe)

Non, il n'y a pas de probleme a ce niveau là. La fonction
sos_physmem_ref_physpage_at() fait le boulot.

Le problème est plutôt que le déplacement de données en mémoire physique
dont il vient d'être question, n'est valable que pour les donées
appartenant au noyau ! Il est hors de question de déplacer n'importe
quelle page physique utilisée en mode user ! En effet, imaginons qu'une
page physique "Phys" soit partagée par deux processus P1 et P2. Au
niveau du noyau, je sais que "Phys" est référencée 2 fois, mais je ne
sais pas dans quels espaces d'adressages (pas de "reverse-mapping" dans
SOS, cf plus bas!). Si je voulais déplacer les données de "Phys" vers
une autre page physique, il faudrait que je retrouve quels processus la
mappent, à quelles adresses virtuelles, que je modifie les tables de
traduction de ces processus... c'est beaucoup trop loooooooourd !

Par contre, il est 2 cas simples où je peux déplacer des données
librement en mémoire physique : ces données ne sont utilisées que par le
noyau (on en a fait la démonstration !), ou ces données ne sont mappées
que par un processus user qu'on connaît.

Bref, tout cela pour dire que le déplacement en mémoire physique est
possible et pratique dans certains cas. Mais pas adapté au cas général.
C'est pousquoi, pour le cas général, on a deux solutions : 1/ *prévenir*
en privilégiant les allocations de mémoire physique dans des zones qui
sont neutres vis à vis du matériel (ie adresses au delà du 16MB du DMA
ISA par exemple), ceci nécessite un allocateur par intervalles + un
classement par zones d'allocation clasées par priorité ; 2/ *guérir*
avec les outils adaptés pour être capable de déplacer les pages
physiques dans tous les cas, ceci nécessite un allocateur par
intervalles + un mécanisme de reverse-mapping (cf plus bas).

> Bien, maintenant que l'allocation physique d'une zone mémoire n'est plus
> un problème, comment allouer
> des pages physiques alignée ???

Jimagine que tu veux parler de pages physiques "contiguës" plutot que
"alignées" ? Cf supra : dans l'itération de SOS en cours ce n'est pas
possible car pas nécessaire pour nos besoins.

> Ah puis autre chose... J'ai lut qu'il faut gérer une correspondance
> adresse physique - linéaire (virtuelle).
> Donc, gérer l'inverse de la MMU.
> Mais pour quel raison ? J'ai pas d'idée en tête.

C'est ce qu'on appelle le "reverse-mapping". Ca permet de savoir quelles
tables de traduction doivent être mises à jour quand on fait des choses
avec la memoire physique. Je vois deux cas dans lesquels ça peut servir.

Le premier cas a ete presente plus haut : on veut deplacer les données
d'une page physique vers une autre, il faudra donc modifier les tables
de traduction de tous les processus qui mappent ces données. Le
reverse-mapping permettra de savoir exactement quelles tables sont à
modifier et comment. Pas de reverse mapping dans SOS, en revanche il y
en a un dans KOS.

Le deuxieme cas (plus classique) concerne le page-out (p.ex swap) : on
veut virer une page de memoire physique sur le disque, il faut donc
savoir quelles tables de traduction sont a modifier pour leur indiquer
que la page est maintenant sur disque. Dans ce cas, le reverse-mapping
est interessant (en gros : gain en efficacité) mais pas necessaire. Par
exemple, dans Linux 2.6 le reverse mapping permet d'accelerer le
page-out. Il n'y en avait pas dans les versions precedentes du noyau, le
page-out restait quand meme possible, mais etait moins efficace (si on
va jusqu'au page-out dans SOS, on utilisera cette technique qui sera
donc detaillée).

Le probleme est que le reverse-mapping necessite d'allouer des donnees
supplementaires en... memoire, donc "gaspille" de l'espace noyau.

> Mon premier (et pas le dernier ;) ) message sur la liste SOS !

Désolé pour le retard. Quelques problèmes d'emploi du temps et de
motivation sont à l'origine de ce retard a l'allumage...

Bonne journée,

-- 
http://david.decotigny.free.fr/


Plus d'informations sur la liste de diffusion Sos