gpt4 book ai didi

linux-kernel - 如何通过 get_page() 为 mmap 手动引用 'free' 页?

转载 作者:行者123 更新时间:2023-12-04 18:09:34 25 4
gpt4 key购买 nike

我将多个物理上不连续的内存缓冲区映射到单个线性用户空间地址。我使用 vm_insert_page() 和 get_page()。我需要在所有分配的页面上使用 get_page() 因为只有给定缓冲区的第一页的引用计数 > 0 并且 vm_insert_page() 需要引用计数 > 0。
据说(根据网上的一些帖子)如果不再需要,我必须通过调用 get_page() 来“释放”我增加引用计数的页面。但是,我不太确定如何“释放”页面。我是否需要跟踪 get_page() 返回的每个页面结构,然后在取消映射期间调用相应的 API 以释放页面?看起来操作系统不会自动为我做这件事。也就是说,在用户进程存在后,页面上的引用计数保持不变,并在用户空间的下一个 mmap 上再次增加。

我的伪代码是这样的:
使用对 pci_alloc_consistent() 的调用分配多个 phys 非连续内存缓冲区
对于上面分配的所有缓冲区中的所有 4K block
使用 virt_to_page(phys_chunk_addr) 创建一个页面结构
//这是必需的,因为只有 phys 缓冲区的第一页
//将有 vm_insert_page() 需要的引用计数 > 0!
通过调用 get_page() 增加页面引用计数
使用 vm_insert_page() 将页面放入 vma

感谢您的任何建议/指示。
担。

最佳答案

DMA 一致性内存可能需要特定于体系结构的缓存标志,因此您不能简单地将其映射到用户空间。
pci_alloc_consistent已弃用。
要映射单个连续内存块,请使用 dma_alloc_coherentdma_mmap_coherent .

如果你不太关心便携性,你可以避免使用 dma_alloc_coherent完全使用单个页面代替:

  • alloc_page 分配一堆页面(对于 PCI,您通常需要 GFP_DMA32 );
  • 使用 dma_map_page 获取每个页面的 DMA 地址;
  • 使用 vm_insert_page 将它们映射到用户空间.

  • 请注意,这不是一致的 DMA 映射,而是流式 DMA 映射。
    在 x86 上,这无关紧要,但在许多其他架构上,您必须调用 dma_sync_ * 在适当的时候发挥作用。

    有关内核中的此示例,请参阅 drivers/firewire/core-iso.c , core-cdev.c .

    如果需要将多个物理上连续的大缓冲区映射到一个几乎连续的区域,则不能使用 dma_mmap_coherent ,所以你必须以艰难的方式做到这一点:
  • 调用 dma_alloc_coherent根据您的需要经常使用;
  • 在您的 mmap实现,只需设置 vm_area_struct->vm_ops ;
  • vm_operations_struct.fault , 调用 virt_to_page , 调用 get_page ,并设置 vm_fault->page到页面。

  • 示例见 sound/core/pcm_native.c .

    关于linux-kernel - 如何通过 get_page() 为 mmap 手动引用 'free' 页?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17746331/

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