[英]Map multiple kernel buffer into contiguous userspace buffer?
我使用dma_alloc_coherent
分配了多個內核可訪問緩沖區,每個緩沖區大小為 4MiB。 目標是將這些緩沖區映射到連續的用戶空間虛擬內存中。 問題是remap_pfn_range
似乎不工作,因為用戶空間內存有時工作,有時不工作,或者有時復制緩沖區的頁面映射。
// in probe() function
dma_alloc_coherent(&pcie->dev, BUF_SIZE, &bus_addr0, GFP_KERNEL);
dma_alloc_coherent(&pcie->dev, BUF_SIZE, &bus_addr1, GFP_KERNEL);
// ...
// in mmap() function
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
pfn = dma_to_phys(&pcie->dev, &bus_addr0) >> PAGE_SHIFT;
remap_pfn_range(pfn, vma->vm_start + 0, pfn, BUF_SIZE, vma->vm_page_prot);
pfn = dma_to_phys(&pcie->dev, &bus_addr1) >> PAGE_SHIFT;
remap_pfn_range(pfn, vma->vm_start + BUF_SIZE, pfn, BUF_SIZE, vma->vm_page_prot);
我不太確定將多個內核緩沖區映射到連續用戶空間內存的最佳方法,但我覺得我做錯了。 提前致謝。
我不知道為什么沒有更好的接口將多個緩沖區連續映射到用戶空間。 理論上,您可以多次調用remap_pfn_range()
,但在某些平台(例如 ARM)上基本上不可能為dma_alloc_coherent()
分配的內存獲取正確的 pfn。
我想出了一個解決這個問題的方法,它可能不被認為是“好”的,但在我的多個平台(x86_64 和各種 ARM)上的使用中似乎工作得很好。 解決方法是在多次調用dma_mmap_coherent()
時臨時修改struct vm_area_struct
中的起始地址和結束地址,每個緩沖區一次。 只要您將 VMA 開始和結束地址重置為其原始值,一切似乎都可以正常工作(請參閱我之前的免責聲明)。
這是一個例子:
static int mmap(struct file *file, struct vm_area_struct *vma)
{
. . .
int rc;
unsigned long vm_start_orig = vma->vm_start;
unsigned long vm_end_orig = vma->vm_end;
for (int idx = 0; idx < buffer_list_size; idx++) {
buffer_entry = &buffer_list[idx];
/* Temporarily modify VMA start and end addresses */
if (idx > 0) {
vma->vm_start = vma->vm_end;
}
vma->vm_end = vma->vm_start + buffer_entry->size;
rc = dma_mmap_coherent(dev, vma,
buffer_entry->virt_address,
buffer_entry->phys_addr,
buffer_entry->size);
if (rc != 0) {
pr_err("dma_mmap_coherent: %d (IDX = %d)\n", rc, idx);
return -EAGAIN;
}
}
/* Restore VMA addresses */
vma->vm_start = vm_start_orig;
vma->vm_end = vm_end_orig;
return rc;
}
不幸的是,目前唯一支持 mmap()ing DMA 一致性內存的方法是宏dma_mmap_coherent()
或函數dma_mmap_attrs()
(由dma_mmap_coherent()
調用)。 不幸的是,這不支持將單個 VMA 拆分為多個單獨分配的 DMA 相干內存塊。
(我希望有一種支持的方法可以將 VMA 的 mmap() 拆分為多個 DMA 相干內存分配,因為它會影響我幫助維護的內核子系統中的緩沖區分配。我不得不更改它以將緩沖區分配為一個單一的 DMA 一致性內存塊,而不是許多頁面大小的塊。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.