On Linux machine, trying to write driver and trying to map some kernel memory to application for performance gains. Checking driver implementation for mmap online, finding different varieties of implementation. As per man pages, mmap - creates new mapping in virtual address space of calling process.
1) Who allocates physical address space during mmap calling? kernel or device driver?
seen following varieties of driver mmap implementation.
a) driver creates contiguous physical kernel memory and maps it with process address space.
static int driver_mmap(struct file *filp, struct vm_area_struct *vma) { unsigned long size = vma->vm_end - vma->vm_start; pos = kmalloc(size); //allocate contiguous physical memory. while (size > 0) { unsigned long pfn; pfn = virt_to_phys((void *) pos) >> PAGE_SHIFT; // Get Page frame number if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED)) // creates mapping return -EAGAIN; start += PAGE_SIZE; pos += PAGE_SIZE; size -= PAGE_SIZE; } } b) driver creates virtual kernel memory and maps it with process address space.
static struct vm_operations_struct dr_vm_ops = { .open = dr_vma_open, .close = dr_vma_close, }; static int driver_mmap(struct file *filp, struct vm_area_struct *vma) { unsigned long size = vma->vm_end - vma->vm_start; void *kp = vmalloc(size); unsigned long up; for (up = vma->vm_start; up < vma->vm_end; up += PAGE_SIZE) { struct page *page = vmalloc_to_page(kp); //Finding physical page from virtual address err = vm_insert_page(vma, up, page); //How is it different from remap_pfn_range? if (err) break; kp += PAGE_SIZE; } vma->vm_ops = &dr_vm_ops; ps_vma_open(vma); } c) not sure who allocates memory in this case.
static int driver_mmap(struct file *filp, struct vm_area_struct *vma) { if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot)) // creates mapping return -EAGAIN; } 2) If kernel allocates memory for mmap, is n't memory wasted in a&b cases?
3) remap_pfn_range is to map multiple pages where as vm_insert_page is just for single page mapping. is it the only difference b/w these two APIs?
Thank You,
Gopinath.