I am trying to understand mmap operation in a driver. I know why we are doing mmap. I am confused with the following 2 implementations of mmap:
int my_mmap(struct file *filp, struct vm_area_struct *vma)
{
vma->vm_ops = &mmap_vm_ops;
vma->vm_flags |= VM_RESERVED;
/* assign the file private data to the vm private data */
vma->vm_private_data = filp->private_data;
mmap_open(vma);
return 0;
}
and
static int simple_remap_mmap(struct file *filp, struct vm_area_struct *vma)
{
if (remap_pfn_range(vma, vma->vm_start, vm->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
vma->vm_ops = &simple_remap_vm_ops;
simple_vma_open(vma);
return 0;
}
The first example is a simple implementation that does not modify page tables..but the 2nd does.
So what is the rationale in the 2nd approach. 1st example also works properly.
The second example simply maps all the requested pages.
The first examples does not immediately map any page.
When the user-space application tries to access one of those pages, a page fault happens, and the page fault handler (.fault
) in mmap_vm_ops
must then actually map that page.
This makes sense if you estimate that most of the pages will not actually be accessed, and if the actual mapping takes too much time or memory.