Question

J'ai consulté Google et trouvé la plupart des personnes 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 que vous souhaitez ne peut pas être trouvé.
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 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’attribution est prioritaire et   ne dort pas. C'est le drapeau à   utiliser dans les gestionnaires d'interruptions, en bas   moitiés et d'autres situations où vous   ne peux pas dormir.

     

GFP_KERNEL   Ceci est une allocation normale et peut bloquer. C'est le drapeau à utiliser   code de contexte de processus lorsque vous pouvez dormir en toute sécurité.

Était-ce utile?

La solution

Vous ne devez vous préoccuper de l’utilisation de la mémoire physiquement contiguë que si un dispositif DMA doit accéder à la mémoire tampon sur un bus à adresse physique (tel que PCI). Le problème est que beaucoup d'appels système n'ont aucun moyen de savoir si leur tampon sera éventuellement transmis à un périphérique DMA: une fois que vous avez transféré le tampon à un autre sous-système du noyau, vous ne pouvez vraiment pas savoir où il va aller. Même si le noyau n’utilise pas la mémoire 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 n'est jamais remappé, mais s'il n'est pas appelé avec GFP_ATOMIC, kmalloc peut bloquer.

kmalloc est limité dans la taille de la mémoire tampon qu'il peut fournir: 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.

  

*) C'était le cas pour les 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 de 4 Mo! (J'ai écrit un assez article détaillé à ce sujet .) & # 8212; 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.

Autres conseils

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 les problèmes qu’elle pose.

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 vous trouvez dans un gestionnaire d’interruptions, comme vous l’avez suggéré.

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 nécessaire 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 physiquement non contigus (pages) 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, (taille de la mémoire tampon / taille de la page) sera ajouté au nombre de mappages ajoutés à la table des pages.

Ceci ajoute également une pression sur 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 entraîner des palper .

Le kmalloc () & amp; Les fonctions vmalloc () constituent une interface simple permettant d’obtenir la mémoire du noyau sous forme de fragments d’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 de la mémoire qui est virtuellement contiguë et pas nécessairement physiquement contiguë.

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

De Google "Je me sens chanceux" sur vmalloc :

kmalloc est la méthode préférée, tant que vous n’avez pas besoin de zones très étendues. Le problème, c'est que si vous voulez utiliser DMA depuis / vers un périphérique matériel, vous devez utiliser kmalloc, et vous aurez probablement besoin d'une plus grande quantité. La solution consiste à allouer de la mémoire dès que possible, avant la mémoire se fragmente.

Sur un système 32 bits, kmalloc () renvoie l’adresse logique du noyau (c’est une adresse virtuelle), qui a le mappage direct (en réalité avec décalage constant) sur l’adresse physique. Ce mappage direct garantit que nous obtenons un bloc physique de RAM contigu. Convient pour DMA où nous ne donnons que le pointeur initial et attendons ensuite un mappage physique contigu 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ù cela nous est égal que la mémoire allouée à notre processus est continue, même dans la RAM physique.

L’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 "Mémoire faible". (dans le premier gigaoctet de mémoire physique) et sont mappés directement aux adresses physiques (utilisez la macro __pa pour la convertir). Cette propriété implique que la mémoire allouée en km est une mémoire continue.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top