Caching 直接将数据存储到用户内存时刷新缓存

Caching 直接将数据存储到用户内存时刷新缓存,caching,linux-device-driver,virtual-memory,Caching,Linux Device Driver,Virtual Memory,我已经编写了一个驱动程序,其目的是允许用户空间程序固定页面并获取页面的物理地址 具体地说,我通过调用内核模块中的get\u user\u pages\u fast来实现这一点 此模块的源代码可在此处找到,以供参考: 使用/dev/mem(是的,我的内核允许不安全的/dev/mem访问),我已经确认物理地址是正确的 但是,我有一些外部硬件(精确地说,是FPGA中的AXI DMA)不工作,看起来可能是缓存一致性问题。在上面链接代码的第329-337行,我这样做了:(在这段代码中,cm.usr_buf

我已经编写了一个驱动程序,其目的是允许用户空间程序固定页面并获取页面的物理地址

具体地说,我通过调用内核模块中的
get\u user\u pages\u fast
来实现这一点

此模块的源代码可在此处找到,以供参考:

使用
/dev/mem
(是的,我的内核允许不安全的
/dev/mem
访问),我已经确认物理地址是正确的

但是,我有一些外部硬件(精确地说,是FPGA中的AXI DMA)不工作,看起来可能是缓存一致性问题。在上面链接代码的第329-337行,我这样做了:(在这段代码中,cm.usr_buf是一个用户虚拟地址)

这似乎没有帮助。我还尝试了更通用的
flush\u cache\u mm
功能


是否有正确的方法刷新用户页缓存?

我尝试了不同的API刷新缓存。劳伦特·平查德(Laurent Pinchard)做了一个名为“”的演讲,他在演讲中解释说不应该使用
中的函数。相反,在锁定用户内存时,可以使用诸如
dma\u map\u sg
dma\u unmap\u sg
之类的方法。我快速查看了内核源代码,这些函数最终会调用特定于每个体系结构的汇编例程,这些例程可能负责禁用某些内存区域中的缓存

此外,如果您尝试在dma传输之间访问内存,则可使用用于cpu的
dma\u sync\u sg\u和用于设备的
dma\u sync\u sg\u来强制缓存刷新

我重写了我的内核驱动程序来使用这些函数,它可以正常工作

//Find the VMA containing the user's buffer
struct vm_area_struct *vma = find_vma(current->mm, (unsigned long)cmd.usr_buf);
if (!vma) {
    printk(KERN_ALERT "pinner: unrecognized user virtual address\n");
    return -EINVAL;
}
flush_cache_range(vma, (unsigned long) cmd.usr_buf, (unsigned long) cmd.usr_buf + cmd.usr_buf_sz);