Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 529e55b6 authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds
Browse files

fb: defio nopage



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

Signed-off-by: default avatarNick 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 8c85fd89
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -7,10 +7,10 @@ IO. The following example may be a useful explanation of how one such setup
works:

- userspace app like Xfbdev mmaps framebuffer
- deferred IO and driver sets up nopage and page_mkwrite handlers
- deferred IO and driver sets up fault and page_mkwrite handlers
- userspace app tries to write to mmaped vaddress
- we get pagefault and reach nopage handler
- nopage handler finds and returns physical page
- we get pagefault and reach fault handler
- fault handler finds and returns physical page
- we get page_mkwrite where we add this page to a list
- schedule a workqueue task to be run after a delay
- app continues writing to that page with no additional cost. this is
+8 −9
Original line number Diff line number Diff line
@@ -25,8 +25,8 @@
#include <linux/pagemap.h>

/* this is to find and return the vmalloc-ed fb pages */
static struct page* fb_deferred_io_nopage(struct vm_area_struct *vma,
					unsigned long vaddr, int *type)
static int fb_deferred_io_fault(struct vm_area_struct *vma,
				struct vm_fault *vmf)
{
	unsigned long offset;
	struct page *page;
@@ -34,18 +34,17 @@ static struct page* fb_deferred_io_nopage(struct vm_area_struct *vma,
	/* info->screen_base is in System RAM */
	void *screen_base = (void __force *) info->screen_base;

	offset = (vaddr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT);
	offset = vmf->pgoff << PAGE_SHIFT;
	if (offset >= info->fix.smem_len)
		return NOPAGE_SIGBUS;
		return VM_FAULT_SIGBUS;

	page = vmalloc_to_page(screen_base + offset);
	if (!page)
		return NOPAGE_OOM;
		return VM_FAULT_SIGBUS;

	get_page(page);
	if (type)
		*type = VM_FAULT_MINOR;
	return page;
	vmf->page = page;
	return 0;
}

int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync)
@@ -84,7 +83,7 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma,
}

static struct vm_operations_struct fb_deferred_io_vm_ops = {
	.nopage   	= fb_deferred_io_nopage,
	.fault		= fb_deferred_io_fault,
	.page_mkwrite	= fb_deferred_io_mkwrite,
};