[Kos-dev] VMM : zero, kmem, kstack, lien avec FS

Christophe kos-dev@enix.org
Sat, 4 Aug 2001 00:34:37 +0200


----- Original Message -----
From: Thomas Petazzoni <thomas.petazzoni@ifrance.com>
To: <kos-dev@enix.org>
Sent: Thursday, October 11, 2001 6:00 PM
Subject: [Kos-dev] VMM : zero, kmem, kstack, lien avec FS


> - zero
> Ce driver sert pour le mapping des zones allouees sur le tas par les
> threads utilisateurs (via un equivalent a l'appel systeme sbrk). La
> fonction raw_read se contentera d'envoyer des zeros, tnadis que la
> fonction raw_write ne fera rien. La politique en cas de page fault est :
> "Je verifie que je suis bien dans le tas de la zone utilisateur du
> processus courant. Si oui => allocation d'une page, sinon envoi d'un
> signal type SIGSEGV au thread (team ?) concerne. Reste a definir si
> c'est la team ou le thread qui doit recevoir le signal.

Pas très clair... pour résumer, tu définis ce "zéro" comme étant une façon
analogue d'allouer de la "bss" sauf qu'il s'agit d'un "heap" pour le
processus en cours ? on peut donc y lire et y écrire, sauf que si la page
n'était pas présente lors d'un accès lecture/écriture, on alloue une page
physique remplie de zéros (bref, comme pour le "bss" de linux). Je comprends
moins l'intérêt de "raw_write" qui ne fait rien, en effet, comment
comptes-tu gérer la mémoire virtuelle pour le tas, i.e, permettre au noyau
de "swapper" les pages les moins utilisées si ce n'est pas "raw_write" qui
en prend charge ? c'est là un détail que tu devrais m'éclairer.

Pour ma part, un "team" n'est pas une tâche mais une collection de tâches
("threads") ayant les mêmes ressources et le même espace virtuel. De fait,
c'est bien le "thread" qui doit recevoir l'exception "user" indiquant un "
BAD MEMORY ACCESS " (à savoir, ton SIGSEGV), car lui seul en est le vrai
responsable du défaut de page qui n'a pu être résoulu. Les autres "threads"
n'ont pas de raison d'être punis.

D'ailleurs, imaginez un jeu marant où "on" créé des "threads" génétiquement
modifiables avec une sélection fondée sur l'élimination des "threads" de par
des accès interdits en mémoire. Ce serait impossible de le réaliser si la
punition s'appliquait à tous les "threads" du "team".

> - kmem
> Kmem sert a gerer la zone noyau, actuellement comprise entre 512M et
> 768M. Deux possibilites s'offrent a nous :
> - lors d'une allocation via kvalloc (donc via kmalloc ou
> kslab_cache_alloc), des pages physiques sont automatiquement allouees et
> mappees la ou il faut. Le handler de page fault de ce driver devra donc
> toujours arreter le systeme (ou alors peut etre arret du thread noyau
> incrimine, a determiner precisement).
> - lors d'une allocation via kvalloc, les pages physiques ne sont PAS
> automatiquement allouees et mappees. Le Handler de page fault se charge
> de verifier grace aux listes de ranges de kvalloc si la page merite
> d'etre mappee. Si oui c'est fait, sinon arret du systeme (ou la aussi
> arret du thread noyau incrimine).
> La deuxieme possibilite correspond plus a la logique UNIX (enfin je
> crois) en terme d'allocation memoire : on retarde le plus possible. Mais
> peut etre que pour les donnees du noyau, ceci n'est pas vraiment
> valable. Qu'en pensez-vous ?
> Sinon le raw_read se chargera simplement de remplir la page allouee de
> zeros. Le raw_write ne fera rien non plus ici.

Les deux sont possibles, simplement en rajoutant un paramètre d'allocation à
la fonction kvalloc pour sélectionner le comportement à suivre :
- la mémoire à allouer est petite et sûre d'être utilisée très rapidement :
allocation immédiate.
- la mémoire à allouer est très grande et seule une petite partie est
finalement utilisée (choisie aléatoirement) : allocation "lazy" pour mieux
coller à l'utilisation réelle.

> - kstack
> Kstack sert a gerer les piles des differents threads (qu'ils soient
> noyau ou utilisateur) au niveau noyau (piles utilisees tout le temps par
> les threads noyaux, et durant les appels systemes ou IRQ poru les
> threads utilisateurs). Tout page fault dans la region virtuelle des
> piles doit etre severement suivi d'un arret total du systeme : ceci ne
> doit pas arriver.
> Les fonctions raw_read et raw_write n'auront pas besoin d'etre
> implementees, elles n'ont aucune raison d'etre appelles : les pages pour
> les piles seront allouees et mappees directement lors de la creation du
> thread. Bref c'est un driver tres simple mais important.
> Le double fault sera gere par un mecanisme exterieur, et se contentera
> d'afficher des messages de debug pour comprendre pourquoi tel ou tel
> thread a utilise trop de piles. Comme nos experimentations l'ont montre,
> il n'est pas possible d'agrandir dynamiquement la pile.

Quelles expérimentations ? j'aimerais bien les connaître, les "preuves" qui
infirment la possibilité d'agrandir dynamiquement la pile. J'ai autant de
méfiance vis-à-vis de cette affirmation que j'en ai eu quand on me soutenait
qu'il était impossible de faire du mode réel avec du code 32-bit par défaut.
Cependant, je dois reconnaître que la gestion des piles dynamiques
compliquent leurs manipulations à tous les niveaux et donc je comprendrais
que l'on ne veuille pas s'hasarder dans cette aventure. Moi-même n'étant pas
certain que cette gestion dynamique nous soit utile. En revanche, il nous
faut en effet garder ce double fault pour nous prévenir d'un plantage
général et pas seulement pour le déboguage.

amicalement,

Hlide