Commit 12281c8d authored by Jani Nikula's avatar Jani Nikula

video: fb_defio: preserve user fb_ops

Modifying fb_ops directly to override fb_mmap with fb_deferred_io_mmap
and then resetting it to NULL afterwards causes problems all over the
place. First, it prevents making the fbops member of struct fb_info a
const pointer, which means we can't make struct fb_ops const
anywhere. Second, a few places have to go out of their way to restore
the original fb_mmap pointer that gets reset to NULL.

Since the only user of the fbops->fb_mmap hook is fb_mmap() in fbmem.c,
call fb_deferred_io_mmap() directly when deferred IO is enabled, and
avoid modifying fb_ops altogether.

Simply use info->fbdefio to determine whether deferred IO should be used
or not. This should be accurate enough for all use cases, although
perhaps not pedantically correct.

v2: Simplify considerably by calling fb_deferred_io_mmap() directly
    (Daniel, Ville)

Cc: Jaya Kumar <jayalk@intworks.biz>
Cc: linux-fbdev@vger.kernel.org
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Acked-by: default avatarNoralf Trønnes <noralf@tronnes.org>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/022c82429da15d6450ff9ac1a897322ec3124db4.1575022735.git.jani.nikula@intel.com
parent dc190678
...@@ -171,7 +171,6 @@ int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma) ...@@ -171,7 +171,6 @@ int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
vma->vm_private_data = info; vma->vm_private_data = info;
return 0; return 0;
} }
EXPORT_SYMBOL(fb_deferred_io_mmap);
/* workqueue callback */ /* workqueue callback */
static void fb_deferred_io_work(struct work_struct *work) static void fb_deferred_io_work(struct work_struct *work)
...@@ -206,7 +205,6 @@ void fb_deferred_io_init(struct fb_info *info) ...@@ -206,7 +205,6 @@ void fb_deferred_io_init(struct fb_info *info)
BUG_ON(!fbdefio); BUG_ON(!fbdefio);
mutex_init(&fbdefio->lock); mutex_init(&fbdefio->lock);
info->fbops->fb_mmap = fb_deferred_io_mmap;
INIT_DELAYED_WORK(&info->deferred_work, fb_deferred_io_work); INIT_DELAYED_WORK(&info->deferred_work, fb_deferred_io_work);
INIT_LIST_HEAD(&fbdefio->pagelist); INIT_LIST_HEAD(&fbdefio->pagelist);
if (fbdefio->delay == 0) /* set a default of 1 s */ if (fbdefio->delay == 0) /* set a default of 1 s */
...@@ -237,7 +235,6 @@ void fb_deferred_io_cleanup(struct fb_info *info) ...@@ -237,7 +235,6 @@ void fb_deferred_io_cleanup(struct fb_info *info)
page->mapping = NULL; page->mapping = NULL;
} }
info->fbops->fb_mmap = NULL;
mutex_destroy(&fbdefio->lock); mutex_destroy(&fbdefio->lock);
} }
EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);
...@@ -1332,16 +1332,23 @@ static int ...@@ -1332,16 +1332,23 @@ static int
fb_mmap(struct file *file, struct vm_area_struct * vma) fb_mmap(struct file *file, struct vm_area_struct * vma)
{ {
struct fb_info *info = file_fb_info(file); struct fb_info *info = file_fb_info(file);
struct fb_ops *fb; int (*fb_mmap_fn)(struct fb_info *info, struct vm_area_struct *vma);
unsigned long mmio_pgoff; unsigned long mmio_pgoff;
unsigned long start; unsigned long start;
u32 len; u32 len;
if (!info) if (!info)
return -ENODEV; return -ENODEV;
fb = info->fbops;
mutex_lock(&info->mm_lock); mutex_lock(&info->mm_lock);
if (fb->fb_mmap) {
fb_mmap_fn = info->fbops->fb_mmap;
#if IS_ENABLED(CONFIG_FB_DEFERRED_IO)
if (info->fbdefio)
fb_mmap_fn = fb_deferred_io_mmap;
#endif
if (fb_mmap_fn) {
int res; int res;
/* /*
...@@ -1349,7 +1356,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) ...@@ -1349,7 +1356,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
* SME protection is removed ahead of the call * SME protection is removed ahead of the call
*/ */
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
res = fb->fb_mmap(info, vma); res = fb_mmap_fn(info, vma);
mutex_unlock(&info->mm_lock); mutex_unlock(&info->mm_lock);
return res; return res;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment