mmap共享不及时更新问题

MIPS平台

设备驱动中mmap实现如下:

static int shm_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
{
struct tee_shm *shm = dmabuf->priv;
size_t size = vma->vm_end - vma->vm_start;

vma->vm_flags |= VM_IO | VM_SHARED; 
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 
return remap_pfn_range(vma, vma->vm_start, shm->paddr >> PAGE_SHIFT,
       size, vma->vm_page_prot);
}

如果不加下划线两行代码,当应用进程,向共享的虚拟空间写入数据时,数据不会及时更新到物理内存中。

因为应用进程中的虚拟空间和物理内存间还有cache。

但是相同的代码在ARM平台没有问题,X86据说也没问题(未验证)、PPC据说平台也有问题(未验证)。

下面分析来自网上:

Mapping of physical memory in UIO needs pgprot_noncached() to ensure
that IO memory is not cached. Without pgprot_noncached(), it (accidentally)

works on x86 and arm, but fails on PPC.

 

你把用户态的设成了no cache,直接读物理内存。
        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
内核直接用的dcache,肯定又一段延迟才会写到物理内存。
这样用户态自然读的延迟了。

如果 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);把这个去掉的话。用户态和内核态都用cache,虽然可能有cache aliasing的问题(用户态cache line和内核cache line都指向的同一块物理内存),但是一般体系都会自动解决这个alasing的,比如armv7就是自动处理vipt dcache aliasing的。

 

PPC的这个问题我也遇到过,硬件DMA跟上层共享数据的话不会自动刷新cache,当时我是在访问之前,使用flush_cache_range刷新了cache

 

ppc是pipt的cache,所以不会出现cache alias的问题
LZ之前代码中有pgprot_noncached,于是kernel就是写的data cache,而app却是直接读的内存,所以数据不一致

而LZ后面又去掉了pgprot_noncached,于是kernel和app都是读写的data cache,而ppc又是pipt的cache,所以app和kernel都是读写的同一个cache line,因此没有问题了

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值