#define _PAGE_BIT_PCD 4 /* page cache disabled *
#define _PAGE_PCD (_AT(pteval_t, 1) << _PAGE_BIT_PCD)
不知道为什么fb_mmap要调用fb_pgprotect(file, vma, off);将page的cache关掉呢,向该page写入数据访问速度奇慢无比,尤其对几十M的大数据量操作时,更是难以忍受,将其去掉之后,速度那是缸缸的!
/* This is an IO map - tell maydump to skip this VMA */
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
unsigned long off)
{
if (boot_cpu_data.x86 > 3)
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
}
后来在
http://blog.163.com/shenbin62349962/blog/static/5800864020083169180610/找到了原因:因为lcd的framebuffer如果是直接位于LCD面板上的话,那么当然需要配置为IO空间,进而也就不应该有cpu缓存,在fbmem.c的fb_mmap中,如果lcd驱动程序没有提供fb->fb_mmap方法,那么于fbmem.c默认使用lcd内部的硬件ram,所以加入了_PAGE_PCD位,禁止缓存该区间内的所有页,
引用设备内存不应当被处理器缓存PS:
从drivers/video/vfb.c获得的信息是,VM_RESERVED必须设置.
vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
PS:
drivers/video/bfin-t350mcqb-fb.c
static int bfin_bf54x_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct bfin_bf54xfb_info *fbi = info->par;
if (fbi->lq043_mmap)
return -1;
spin_lock(&fbi->lock);
fbi->lq043_mmap = 1;
spin_unlock(&fbi->lock);
vma->vm_start = (unsigned long)(fbi->fb_buffer);
vma->vm_end = vma->vm_start + info->fix.smem_len;
/* For those who don't understand how mmap works, go read
* Documentation/nommu-mmap.txt.
* For those that do, you will know that the VM_MAYSHARE flag
* must be set in the vma->vm_flags structure on noMMU
* Other flags can be set, and are documented in
* include/linux/mm.h
*/
vma->vm_flags |= VM_MAYSHARE | VM_SHARED; // 这个是我们需要的.[luther.gliethttp] return 0;
}
PS:
来自include/asm-generic/cacheflush.h文件的信息
/* * The cache doesn't need to be flushed when TLB entries change when * the cache is mapped to physical memory, not virtual memory */从这里来看,如果mmap或者自己用do_mmap_pgoff()自定义一块kmalloc到的内核内存到user空间,那么当user空间拷贝完数据之后,如果执行了ioctl或者user空间进程被调度,将导致调度程序,切换时执行flush操作,所以用户空间直接写入的到kmalloc内核空间的数据,也就被flush到DDR上,因此数据不会发生非一致性问题,所以像flush_dcache_page(pages[i]);等回写函数也就不用单独去调用了..mmap = gliethttp_card_mmap,
static int gliethttp_card_mmap(struct file *file, struct vm_area_struct * vma)
{
vma->vm_pgoff = page_to_pfn(virt_to_page(file->private_data)) << PAGE_SHIFT;
/*
// This is an IO map - tell maydump to skip this VMA
vma->vm_flags |= VM_IO | VM_RESERVED;
if (boot_cpu_data.x86 > 3) {
log_printf("boot_cpu_data.x86\n");
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; // fb_mmap==>fb_pgprotect
}*/
vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
return 0;
}
static long gliethttp_do_mmap(struct file *file, void *phy, size_t len)
{
int error = -EBADF;
struct mm_struct *mm = current->mm;
unsigned long prot = PROT_READ | PROT_WRITE;
unsigned long flags = MAP_SHARED;
file->private_data = phy;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
down_write(&mm->mmap_sem);
error = do_mmap_pgoff(file, 0, len, prot, flags, 0);
up_write(&mm->mmap_sem);
return error;
}
阅读(4796) | 评论(1) | 转发(0) |