121 votes

Quelle est la différence entre vmalloc et kmalloc ?

J'ai fait des recherches sur Internet et j'ai constaté que la plupart des gens préconisent l'utilisation de kmalloc car vous avez la garantie d'obtenir des blocs physiques contigus de mémoire. Cependant, il semble également que kmalloc peut échouer si un contigu physique Le bloc que vous voulez est introuvable.
Quels sont les avantages d'avoir un bloc de mémoire contigu ? Plus précisément, pourquoi aurais-je besoin d'un bloc de mémoire contigu ? physique bloc de mémoire dans un appel système ? Y a-t-il une raison pour laquelle je ne pourrais pas simplement utiliser vmalloc ?
Enfin, si je devais allouer de la mémoire pendant le traitement d'un appel système, devrais-je spécifier GFP_ATOMIC ? Un appel système est-il exécuté dans un contexte atomique ?

GFP_ATOMIC
L'allocation est hautement prioritaire et n'est pas en sommeil. C'est le drapeau à utiliser dans les gestionnaires d'interruptions, les moitié et d'autres situations où vous où vous ne pouvez pas dormir.

GFP_KERNEL Il s'agit d'une allocation normale qui pourrait être bloquée. C'est le drapeau à utiliser dans le code de contexte de processus quand il est sûr de dormir.

0 votes

6 votes

Cet article affirme des absurdités comme : "Généralement, une architecture 32 bits a une taille de page de 4KB et une architecture 64 bits a une taille de page de 8KB". Je ne l'ai pas lu entièrement, mais je ne le qualifierais pas de "bon", ni même d'en croire un mot.

1 votes

Note (semi-relationnelle) : vmalloc est plus rapide avec le noyau 5.2 (Q2 2019)

102voto

DGentry Points 10759

Vous ne devez vous soucier de l'utilisation d'une mémoire physiquement contiguë que si le tampon est accessible par un dispositif DMA sur un bus à adressage physique (comme PCI). Le problème est que de nombreux appels système n'ont aucun moyen de savoir si leur tampon sera finalement transmis à un périphérique DMA : une fois que vous avez transmis le tampon à un autre sous-système du noyau, vous ne pouvez pas vraiment savoir où il va aller. Même si le noyau n'utilise pas la mémoire tampon pour le DMA aujourd'hui, un développement futur pourrait le faire.

vmalloc est souvent plus lent que kmalloc, car il peut avoir à remapper l'espace tampon dans une plage virtuellement contiguë. kmalloc ne remappe jamais, bien que s'il n'est pas appelé avec GFP_ATOMIC kmalloc peut bloquer.

kmalloc est limité dans la taille du tampon qu'il peut fournir : 128 KBytes *) . Si vous avez besoin d'un tampon vraiment grand, vous devez utiliser vmalloc ou un autre mécanisme comme la réservation de mémoire élevée au démarrage.

*) C'était vrai pour les noyaux précédents. Sur les noyaux récents (je l'ai testé sur 2.6.33.2), la taille maximale d'un seul kmalloc peut atteindre 4 Mo ! (J'ai écrit un post détaillé sur ce sujet .) - kaiwan

Pour un appel système, vous n'avez pas besoin de passer GFP_ATOMIC à kmalloc(), vous pouvez utiliser GFP_KERNEL. Vous n'êtes pas un gestionnaire d'interruption : le code de l'application entre dans le contexte du noyau au moyen d'un trap, ce n'est pas une interruption.

1 votes

Je pensais que les appels système étaient lancés en déclenchant int $0x80 ? (c'est à dire une interruption) ?

3 votes

Int $0x80 est une interruption logicielle, également appelée "trap". Ce que l'on entend par gestionnaire d'interruptions est une interruption matérielle, par exemple lorsque l'utilisateur appuie sur une touche ou déplace les touches.

0 votes

Les appels système sont destinés aux transitions entre l'espace utilisateur et l'espace noyau... kmalloc est utilisé dans le contexte du noyau uniquement....

18voto

Mike Heinz Points 1081

Réponse courte : télécharger Pilotes de périphériques Linux et lisez le chapitre sur la gestion de la mémoire.

Sérieusement, il y a beaucoup de questions subtiles liées à la gestion de la mémoire du noyau que vous devez comprendre - je passe beaucoup de mon temps à déboguer des problèmes avec elle.

vmalloc() est très rarement utilisé, car le noyau utilise rarement la mémoire virtuelle. kmalloc() est ce qui est typiquement utilisé, mais vous devez connaître les conséquences des différents drapeaux et vous avez besoin d'une stratégie pour gérer ce qui se passe en cas d'échec - particulièrement si vous êtes dans un gestionnaire d'interruption, comme vous l'avez suggéré.

3 votes

"parce que le noyau utilise rarement la mémoire virtuelle", pourquoi cela ?

0 votes

Parce que vous ne voulez généralement pas que le noyau se bloque pendant qu'il attend que le noyau échange de la mémoire dans ou hors du stockage disque...

3 votes

Non, la mémoire du noyau allouée avec vmalloc est jamais swapped. Seule la mémoire de l'espace utilisateur peut être échangée. L'espace d'adressage du noyau n'est pas échangeable, et vmalloc alloue dans l'espace d'adressage du noyau.

15voto

codetwiddler Points 210

Linux Kernel Development de Robert Love (chapitre 12, page 244 dans la 3e édition) répond très clairement à cette question.

Oui, une mémoire physiquement contiguë n'est pas nécessaire dans la plupart des cas. La principale raison pour laquelle kmalloc est plus utilisé que vmalloc dans le noyau est la performance. Le livre explique que lorsque de gros morceaux de mémoire sont alloués à l'aide de vmalloc, le noyau doit mapper les morceaux (pages) physiquement non contigus en une seule région de mémoire virtuelle contiguë. Comme la mémoire est virtuellement contiguë et physiquement non contiguë, plusieurs mappages d'adresses virtuelles à physiques devront être ajoutés à la table des pages. Et dans le pire des cas, il y aura (taille du tampon/taille de la page) nombre de mappings ajoutés à la table des pages.

Cela ajoute également une pression sur le TLB (les entrées du cache stockant les mappages récents des adresses virtuelles et physiques) lors de l'accès à ce tampon. Cela peut conduire à coups de poing .

4voto

Dark Shikari Points 6178

Quels sont les avantages d'avoir un bloc de mémoire contigu ? Plus précisément, pourquoi aurais-je besoin d'un bloc de mémoire physique contigu dans un appel système ? Y a-t-il une raison pour laquelle je ne pourrais pas simplement utiliser vmalloc ?

De "I'm Feeling Lucky" de Google sur vmalloc :

kmalloc est la méthode préférée, tant que vous n'avez pas besoin de très grandes zones. Le problème est que si vous voulez faire du DMA depuis/vers un périphérique matériel, vous devrez utiliser kmalloc, et vous aurez probablement besoin de plus gros morceaux. La solution est d'allouer la mémoire le plus tôt possible, avant que que la mémoire ne soit fragmentée.

0 votes

Tu vois, j'ai lu ça, et ça n'a aucun sens pour moi. Je comprends l'utilisation de kmalloc pour grand mais pour les petites allocations, pourquoi ne pas utiliser vmalloc pour éviter de fragmenter la mémoire physique ?

0 votes

Parce que vous devriez faire confiance au noyau pour faire ce qui est le mieux ; s'il pense que l'allocation d'un seul morceau est mieux, il le fera. vmalloc est seulement pour quand vous devez absolument doit ont un morceau contigu.

0 votes

Je suppose que cela a du sens, mais cela semble contre-intuitif. kmalloc semble devoir être utilisé lorsque les performances sont un souci majeur (c'est-à-dire que je ne peux pas être assailli par les entrées-sorties sur le disque). Par ailleurs, qu'en est-il de GFP_ATOMIC ?

1voto

user3287223 Points 21

Un bon article sur vmalloc et kmalloc

http://learnlinuxconcepts.blogspot.in/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X