gpt4 book ai didi

c - "Magic ring buffer"在Linux内核空间的实现?

转载 作者:太空宇宙 更新时间:2023-11-04 04:24:20 24 4
gpt4 key购买 nike

我知道 "magic ring buffer"该技巧涉及在进程的地址空间中镜像底层缓冲区,以允许使用单个 memcpy() 对数据 block 进行排队,而无需担心回绕。

我想在 Linux 内核模块中完成同样的事情。假设我有一个使用 dma_alloc_coherent() 创建的缓冲区,它的虚拟地址是 V 并且它的长度是 N。如何创建映射,使其虚拟地址 [V+N,V+2N) 映射到与 [V,V+N) 相同的底层页面?

Note: this is in 32-bit ARM Linux.

最佳答案

drivers/firewire/ohci.c将异步接收环形缓冲区的某些页面映射两次,以便更轻松地访问环绕的接收数据包:

    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);
...

据我所知,相干 DMA 内存没有类似的 API。如果您知道您的架构如何处理此问题,您也许能够重新映射 dma_alloc_coherent() 返回的页面。

请注意,如果您使用多个虚拟地址修改同一个物理地址,某些架构的缓存可能会出现问题;即使您设法映射它,您也必须检查在您的特定架构中是否可以缓存连贯的 DMA 内存。

关于c - "Magic ring buffer"在Linux内核空间的实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43243726/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com