web-dev-qa-db-fra.com

Quelle est la différence entre vmalloc et kmalloc?

J'ai consulté Google et trouvé la plupart des gens qui préconisent l'utilisation de kmalloc, car vous êtes assuré d'obtenir des blocs de mémoire physiques contigus. Cependant, il semble également que kmalloc puisse échouer si un bloc physique contigu ne vous permet pas de trouver.
Quels sont les avantages d’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?
Enfin, si je devais allouer de la mémoire lors du 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 prioritaire et ne dort pas. C'est le drapeau à utiliser dans les gestionnaires d'interruptions, les moitiés inférieures et autres situations dans lesquelles vous ne pouvez pas dormir.

GFP_KERNEL Ceci est une allocation normale et peut bloquer. Il s'agit de l'indicateur à utiliser dans le code de contexte de processus lorsqu'il est possible de dormir en toute sécurité.

105
FreeMemory

Vous ne devez vous préoccuper que de l’utilisation de la mémoire physiquement contiguë si le tampon est accessible par un périphérique DMA sur un bus à adresse physique (comme le PCI). Le problème est que de nombreux appels système ne disposent savoir si leur mémoire tampon finira par être transmise à un périphérique DMA: une fois que vous transmettez la mémoire tampon à un autre sous-système du noyau, vous ne pouvez vraiment pas savoir où elle va aller. Même si le noyau ne l'utilise pas le tampon pour DMA aujourd'hui, un développement futur pourrait le faire.

vmalloc est souvent plus lent que kmalloc, car il peut être nécessaire de remapper l'espace tampon dans une plage pratiquement contiguë. kmalloc ne remappe jamais, mais s'il n'est pas appelé avec GFP_ATOMIC, kmalloc peut bloquer.

la taille de la mémoire tampon fournie par kmalloc est limitée: 128 Ko*). Si vous avez besoin d'un très gros tampon, vous devez utiliser vmalloc ou un autre mécanisme comme réserver de la mémoire vive au démarrage.

*)  Cela était vrai des noyaux précédents. Sur les noyaux récents (j'ai testé cela sur 2.6.33.2), la taille maximale d'un seul kmalloc est jusqu'à 4 Mo! (J'ai écrit un assez article détaillé à 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'une interruption, ce n'est pas une interruption.

85
DGentry

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

Sérieusement, vous devez comprendre beaucoup de problèmes subtils liés à la gestion de la mémoire du noyau - je passe beaucoup de temps à résoudre 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 généralement utilisé, mais vous devez savoir quelles sont les conséquences des différents drapeaux et vous avez besoin d’une stratégie pour faire face à ce qui se passe en cas d’échec - en particulier si vous êtes dans un gestionnaire d’interruptions, comme vous l’avez suggéré.

16
Mike Heinz

Le développement du noyau Linux de Robert Love (Chapitre 12, page 244 dans la 3e édition) répond très clairement à cette question.

Oui, la mémoire physiquement contiguë n'est pas requise dans de nombreux cas. Les performances sont principalement à l'origine de l'utilisation de kmalloc par rapport à vmalloc. 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 dans une seule région de mémoire virtuelle contiguë. Étant donné que la mémoire est pratiquement contiguë et physiquement non contiguë, plusieurs mappages d'adresse virtuelle à physique devront être ajoutés à la table des pages. Et dans le pire des cas, il y aura (taille du tampon/taille de la page) le nombre de mappages ajoutés à la table des pages.

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

12
codetwiddler

Les fonctions kmalloc() & vmalloc() constituent une interface simple permettant d'obtenir la mémoire du noyau sous forme de fragments de la taille en octets.

  1. La fonction kmalloc() garantit que les pages sont physiquement contiguës (et pratiquement contiguës).

  2. La fonction vmalloc() fonctionne de la même manière que kmalloc(), sauf qu'elle alloue une mémoire virtuellement contiguë et non nécessairement physiquement contiguë.

10
Yogeesh H T

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? Existe-t-il une raison pour laquelle je ne pourrais pas utiliser vmalloc?

De "Je me sens chanceux" de Google sur vmalloc:

kmalloc est le moyen privilégié, tant que vous n’avez pas besoin de très grandes zones. Le problème, si vous voulez faire DMA de/vers un périphérique matériel, vous ' Vous aurez besoin d’utiliser kmalloc, et vous aurez probablement besoin d’un plus gros morceau. La solution consiste à allouer de la mémoire dès que possible, avant que la mémoire ne soit fragmentée.

5
Dark Shikari

Sur un système 32 bits, kmalloc () renvoie l'adresse logique du noyau (une adresse virtuelle cependant), qui possède le mappage direct (en réalité avec un décalage constant) en adresse physique. Ce mappage direct garantit que nous obtenons un bloc physique de mémoire vive contigu. Convient pour DMA où nous ne donnons que le pointeur initial et attendons un mappage physique contigu par la suite pour notre opération.

vmalloc () renvoie l'adresse virtuelle du noyau qui, à son tour, pourrait ne pas avoir de mappage contigu sur la RAM physique. Utile pour l'allocation de mémoire importante et dans les cas où nous ne nous soucions pas du fait que la mémoire allouée à notre processus est continue, même dans la RAM physique.

2
a.saurabh

Une des autres différences est que kmalloc renverra une adresse logique (sinon, vous spécifiez GPF_HIGHMEM). Les adresses logiques sont placées dans la mémoire faible (dans le premier gigaoctet de mémoire physique) et sont mappées directement aux adresses physiques (utilisez la macro __pa pour la convertir). Cette propriété implique que la mémoire allouée est une mémoire continue.

D'autre part, Vmalloc est capable de retourner des adresses virtuelles à partir de "haute mémoire". Ces adresses ne peuvent pas être converties en adresses physiques de manière directe (vous devez utiliser la fonction virt_to_page).

1
Jezz