Skip to content

Commit 5905585

Browse files
committed
fbdev: Put mmap for deferred I/O into drivers
The fbdev mmap function fb_mmap() unconditionally overrides the driver's implementation if deferred I/O has been activated. This makes it hard to implement mmap with anything but a vmalloc()'ed software buffer. That is specifically a problem for DRM, where video memory is maintained by a memory manager. Leave the mmap handling to drivers and expect them to call the helper for deferred I/O by thmeselves. v4: * unlock mm_lock in fb_mmap() error path (Dan) v3: * fix warning if fb_mmap is missing (kernel test robot) v2: * print a helpful error message if the defio setup is incorrect (Javier) Signed-off-by: Thomas Zimmermann <[email protected]> Reviewed-by: Javier Martinez Canillas <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 594e9c0 commit 5905585

File tree

15 files changed

+37
-11
lines changed

15 files changed

+37
-11
lines changed

drivers/gpu/drm/drm_fb_helper.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2118,7 +2118,9 @@ static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
21182118
{
21192119
struct drm_fb_helper *fb_helper = info->par;
21202120

2121-
if (fb_helper->dev->driver->gem_prime_mmap)
2121+
if (drm_fbdev_use_shadow_fb(fb_helper))
2122+
return fb_deferred_io_mmap(info, vma);
2123+
else if (fb_helper->dev->driver->gem_prime_mmap)
21222124
return fb_helper->dev->driver->gem_prime_mmap(fb_helper->buffer->gem, vma);
21232125
else
21242126
return -ENODEV;

drivers/gpu/drm/vmwgfx/vmwgfx_fb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,7 @@ static const struct fb_ops vmw_fb_ops = {
619619
.fb_imageblit = vmw_fb_imageblit,
620620
.fb_pan_display = vmw_fb_pan_display,
621621
.fb_blank = vmw_fb_blank,
622+
.fb_mmap = fb_deferred_io_mmap,
622623
};
623624

624625
int vmw_fb_init(struct vmw_private *vmw_priv)

drivers/hid/hid-picolcd_fb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ static const struct fb_ops picolcdfb_ops = {
428428
.fb_imageblit = picolcd_fb_imageblit,
429429
.fb_check_var = picolcd_fb_check_var,
430430
.fb_set_par = picolcd_set_par,
431+
.fb_mmap = fb_deferred_io_mmap,
431432
};
432433

433434

drivers/staging/fbtft/fbtft-core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
652652
fbops->fb_imageblit = fbtft_fb_imageblit;
653653
fbops->fb_setcolreg = fbtft_fb_setcolreg;
654654
fbops->fb_blank = fbtft_fb_blank;
655+
fbops->fb_mmap = fb_deferred_io_mmap;
655656

656657
fbdefio->delay = HZ / fps;
657658
fbdefio->sort_pagelist = true;

drivers/video/fbdev/broadsheetfb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,7 @@ static const struct fb_ops broadsheetfb_ops = {
10551055
.fb_fillrect = broadsheetfb_fillrect,
10561056
.fb_copyarea = broadsheetfb_copyarea,
10571057
.fb_imageblit = broadsheetfb_imageblit,
1058+
.fb_mmap = fb_deferred_io_mmap,
10581059
};
10591060

10601061
static struct fb_deferred_io broadsheetfb_defio = {

drivers/video/fbdev/core/fb_defio.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
181181
vma->vm_private_data = info;
182182
return 0;
183183
}
184+
EXPORT_SYMBOL_GPL(fb_deferred_io_mmap);
184185

185186
/* workqueue callback */
186187
static void fb_deferred_io_work(struct work_struct *work)

drivers/video/fbdev/core/fbmem.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,7 +1334,6 @@ static int
13341334
fb_mmap(struct file *file, struct vm_area_struct * vma)
13351335
{
13361336
struct fb_info *info = file_fb_info(file);
1337-
int (*fb_mmap_fn)(struct fb_info *info, struct vm_area_struct *vma);
13381337
unsigned long mmio_pgoff;
13391338
unsigned long start;
13401339
u32 len;
@@ -1343,24 +1342,27 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
13431342
return -ENODEV;
13441343
mutex_lock(&info->mm_lock);
13451344

1346-
fb_mmap_fn = info->fbops->fb_mmap;
1347-
1348-
#if IS_ENABLED(CONFIG_FB_DEFERRED_IO)
1349-
if (info->fbdefio)
1350-
fb_mmap_fn = fb_deferred_io_mmap;
1351-
#endif
1352-
1353-
if (fb_mmap_fn) {
1345+
if (info->fbops->fb_mmap) {
13541346
int res;
13551347

13561348
/*
13571349
* The framebuffer needs to be accessed decrypted, be sure
13581350
* SME protection is removed ahead of the call
13591351
*/
13601352
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
1361-
res = fb_mmap_fn(info, vma);
1353+
res = info->fbops->fb_mmap(info, vma);
13621354
mutex_unlock(&info->mm_lock);
13631355
return res;
1356+
#if IS_ENABLED(CONFIG_FB_DEFERRED_IO)
1357+
} else if (info->fbdefio) {
1358+
/*
1359+
* FB deferred I/O wants you to handle mmap in your drivers. At a
1360+
* minimum, point struct fb_ops.fb_mmap to fb_deferred_io_mmap().
1361+
*/
1362+
dev_warn_once(info->dev, "fbdev mmap not set up for deferred I/O.\n");
1363+
mutex_unlock(&info->mm_lock);
1364+
return -ENODEV;
1365+
#endif
13641366
}
13651367

13661368
/*

drivers/video/fbdev/hecubafb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ static const struct fb_ops hecubafb_ops = {
204204
.fb_fillrect = hecubafb_fillrect,
205205
.fb_copyarea = hecubafb_copyarea,
206206
.fb_imageblit = hecubafb_imageblit,
207+
.fb_mmap = fb_deferred_io_mmap,
207208
};
208209

209210
static struct fb_deferred_io hecubafb_defio = {

drivers/video/fbdev/hyperv_fb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,7 @@ static const struct fb_ops hvfb_ops = {
909909
.fb_copyarea = hvfb_cfb_copyarea,
910910
.fb_imageblit = hvfb_cfb_imageblit,
911911
.fb_blank = hvfb_blank,
912+
.fb_mmap = fb_deferred_io_mmap,
912913
};
913914

914915

drivers/video/fbdev/metronomefb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ static const struct fb_ops metronomefb_ops = {
564564
.fb_fillrect = metronomefb_fillrect,
565565
.fb_copyarea = metronomefb_copyarea,
566566
.fb_imageblit = metronomefb_imageblit,
567+
.fb_mmap = fb_deferred_io_mmap,
567568
};
568569

569570
static struct fb_deferred_io metronomefb_defio = {

0 commit comments

Comments
 (0)