Last active
April 24, 2020 12:42
-
-
Save juniorprincewang/eabbb879e9b8acde8afb8717de5ac67f to your computer and use it in GitHub Desktop.
vm_insert_page
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| int _mmap(struct file *f, struct vm_area_struct *vma) { | |
| unsigned long pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | |
| unsigned long addr; | |
| struct page *page; | |
| int i,rc=-ENODEV; | |
| // TODO need any semaphore for vma manipulation? | |
| printk(KERN_DEBUG "vma->vm_end %lu vm_start %lu len %lu pages %lu vm_pgoff %lu\n", | |
| vma->vm_end, vma->vm_start, vma->vm_end - vma->vm_start, pages, vma->vm_pgoff); | |
| /* allocate and insert pages to fill the vma. */ | |
| for(i=0; i < pages; i++) { | |
| page = alloc_page(GFP_KERNEL); // TODO IO RESERVE? | |
| if (!page) { | |
| // TODO free previous pages | |
| printk(KERN_DEBUG "alloc_page failed\n"); | |
| goto done; | |
| } | |
| addr = vma->vm_start+i*PAGE_SIZE; | |
| if (vm_insert_page(vma,addr,page) < 0) { | |
| // TODO free previous pages | |
| printk(KERN_DEBUG "vm_insert_page failed\n"); | |
| goto done; | |
| } | |
| printk(KERN_DEBUG "inserted page %d at %p\n",i,(void*)addr); | |
| // TODO __free_page now, should be ok, since vm_insert_page incremented its | |
| // refcount. that way, upon munmap, refcount hits zer0, pages get freed | |
| __free_page(page); | |
| } | |
| printk(KERN_DEBUG "completed inserting %lu pages\n", pages); | |
| rc = 0; | |
| done: | |
| return rc; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pos = usbvision->frame[i].data; | |
| while (size > 0) { | |
| if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { | |
| PDEBUG(DBG_MMAP, "mmap: vm_insert_page failed"); | |
| return -EAGAIN; | |
| } | |
| start += PAGE_SIZE; | |
| pos += PAGE_SIZE; | |
| size -= PAGE_SIZE; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment