Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fb: defio nopage

Convert fb defio from nopage to fault.
Switch from OOM to SIGBUS if the resource is not available.

Signed-off-by: Nick Piggin <npiggin@suse.de>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Jaya Kumar <jayakumar.lkml@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Nick Piggin and committed by
Linus Torvalds
529e55b6 8c85fd89

+11 -12
+3 -3
Documentation/fb/deferred_io.txt
··· 7 7 works: 8 8 9 9 - userspace app like Xfbdev mmaps framebuffer 10 - - deferred IO and driver sets up nopage and page_mkwrite handlers 10 + - deferred IO and driver sets up fault and page_mkwrite handlers 11 11 - userspace app tries to write to mmaped vaddress 12 - - we get pagefault and reach nopage handler 13 - - nopage handler finds and returns physical page 12 + - we get pagefault and reach fault handler 13 + - fault handler finds and returns physical page 14 14 - we get page_mkwrite where we add this page to a list 15 15 - schedule a workqueue task to be run after a delay 16 16 - app continues writing to that page with no additional cost. this is
+8 -9
drivers/video/fb_defio.c
··· 25 25 #include <linux/pagemap.h> 26 26 27 27 /* this is to find and return the vmalloc-ed fb pages */ 28 - static struct page* fb_deferred_io_nopage(struct vm_area_struct *vma, 29 - unsigned long vaddr, int *type) 28 + static int fb_deferred_io_fault(struct vm_area_struct *vma, 29 + struct vm_fault *vmf) 30 30 { 31 31 unsigned long offset; 32 32 struct page *page; ··· 34 34 /* info->screen_base is in System RAM */ 35 35 void *screen_base = (void __force *) info->screen_base; 36 36 37 - offset = (vaddr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); 37 + offset = vmf->pgoff << PAGE_SHIFT; 38 38 if (offset >= info->fix.smem_len) 39 - return NOPAGE_SIGBUS; 39 + return VM_FAULT_SIGBUS; 40 40 41 41 page = vmalloc_to_page(screen_base + offset); 42 42 if (!page) 43 - return NOPAGE_OOM; 43 + return VM_FAULT_SIGBUS; 44 44 45 45 get_page(page); 46 - if (type) 47 - *type = VM_FAULT_MINOR; 48 - return page; 46 + vmf->page = page; 47 + return 0; 49 48 } 50 49 51 50 int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync) ··· 83 84 } 84 85 85 86 static struct vm_operations_struct fb_deferred_io_vm_ops = { 86 - .nopage = fb_deferred_io_nopage, 87 + .fault = fb_deferred_io_fault, 87 88 .page_mkwrite = fb_deferred_io_mkwrite, 88 89 }; 89 90