2017-04-06 4 views
1

Je connais l'astuce "magic ring buffer" qui implique la mise en miroir du tampon sous-jacent dans l'espace adresse du processus pour permettre à des blocs de données d'être mis en file d'attente avec un seul memcpy() sans se soucier de l'encapsulation.Implémentation du "Magic Ring Buffer" dans l'espace noyau Linux?

Je voudrais accomplir la même chose mais dans un module de noyau Linux. Supposons que j'ai un tampon créé avec dma_alloc_coherent(), son adresse virtuelle est V et sa longueur est N. Comment créer le mappage de manière à ce que ses adresses virtuelles [V+N,V+2N) correspondent aux mêmes pages sous-jacentes que [V,V+N)?

Remarque: il s'agit de Linux ARM 32 bits.

+2

[kfifo.c] (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/libkfifo.c) et [kfifo.h] (https: //git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/kfifo.h) sont une version qui supporte les éléments de taille constante sans aucune aide MMU. Ils sont plus communs dans le noyau. –

+0

Merci! Je pense que cela fonctionnera pour mon application, et je ne pense pas que le tampon en miroir sera nécessaire. –

Répondre

0

drivers/firewire/ohci.c cartes de certaines pages du Asynchronous Tampon de réception anneau double pour permettre un accès plus facile aux paquets reçus qui enveloppent:

for (i = 0; i < AR_BUFFERS; i++) { 
      ctx->pages[i] = alloc_page(GFP_KERNEL | GFP_DMA32); 
      ... 
      dma_addr = dma_map_page(ohci->card.device, ctx->pages[i], 
            0, PAGE_SIZE, DMA_FROM_DEVICE); 
      ... 
    } 
    for (i = 0; i < AR_BUFFERS; i++) 
      pages[i]    = ctx->pages[i]; 
    for (i = 0; i < AR_WRAPAROUND_PAGES; i++) 
      pages[AR_BUFFERS + i] = ctx->pages[i]; 
    ctx->buffer = vmap(pages, ARRAY_SIZE(pages), VM_MAP, PAGE_KERNEL); 
    ... 

Pour autant que je peux voir, il n'y a pas d'API similaire pour DMA cohérente Mémoire. Vous pourriez être en mesure de remapper les pages retournées par dma_alloc_coherent() si vous savez comment votre architecture gère cela.

Veuillez noter que certaines architectures peuvent avoir des problèmes avec leurs caches si vous utilisez plusieurs adresses virtuelles pour modifier la même adresse physique; même si vous parvenez à le mapper, vous devez vérifier si la mémoire DMA cohérente est disponible dans votre arche spécifique.