Skip to content

Commit 7f5cc4a

Browse files
author
Thomas Zimmermann
committed
drm/fb-helper: Schedule deferred-I/O worker after writing to framebuffer
Schedule the deferred-I/O worker instead of the damage worker after writing to the fbdev framebuffer. The deferred-I/O worker then performs the dirty-fb update. The fbdev emulation will initialize deferred I/O for all drivers that require damage updates. It is therefore a valid assumption that the deferred-I/O worker is present. It would be possible to perform the damage handling directly from within the write operation. But doing this could increase the overhead of the write or interfere with a concurrently scheduled deferred-I/O worker. Instead, scheduling the deferred-I/O worker with its regular delay of 50 ms removes load off the write operation and allows the deferred-I/O worker to handle multiple write operations that arrived during the delay time window. v3: * remove unused variable (lkp) v2: * keep drm_fb_helper_damage() (Daniel) * use fb_deferred_io_schedule_flush() (Daniel) * clarify comments (Daniel) Signed-off-by: Thomas Zimmermann <[email protected]> Reviewed-by: Daniel Vetter <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 5fc586a commit 7f5cc4a

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

drivers/gpu/drm/drm_fb_helper.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,9 +599,16 @@ static void drm_fb_helper_add_damage_clip(struct drm_fb_helper *helper, u32 x, u
599599
static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y,
600600
u32 width, u32 height)
601601
{
602+
struct fb_info *info = helper->info;
603+
602604
drm_fb_helper_add_damage_clip(helper, x, y, width, height);
603605

604-
schedule_work(&helper->damage_work);
606+
/*
607+
* The current fbdev emulation only flushes buffers if a damage
608+
* update is necessary. And we can assume that deferred I/O has
609+
* been enabled as damage updates require deferred I/O for mmap.
610+
*/
611+
fb_deferred_io_schedule_flush(info);
605612
}
606613

607614
/*

drivers/video/fbdev/core/fb_defio.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,19 @@ void fb_deferred_io_cleanup(struct fb_info *info)
332332
mutex_destroy(&fbdefio->lock);
333333
}
334334
EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);
335+
336+
void fb_deferred_io_schedule_flush(struct fb_info *info)
337+
{
338+
struct fb_deferred_io *fbdefio = info->fbdefio;
339+
340+
if (WARN_ON_ONCE(!fbdefio))
341+
return; /* bug in driver logic */
342+
343+
/*
344+
* There's no requirement from callers to schedule the
345+
* flush immediately. Rather schedule the worker with a
346+
* delay and let a few more writes pile up.
347+
*/
348+
schedule_delayed_work(&info->deferred_work, fbdefio->delay);
349+
}
350+
EXPORT_SYMBOL_GPL(fb_deferred_io_schedule_flush);

include/linux/fb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ extern void fb_deferred_io_open(struct fb_info *info,
663663
struct inode *inode,
664664
struct file *file);
665665
extern void fb_deferred_io_cleanup(struct fb_info *info);
666+
extern void fb_deferred_io_schedule_flush(struct fb_info *info);
666667
extern int fb_deferred_io_fsync(struct file *file, loff_t start,
667668
loff_t end, int datasync);
668669

0 commit comments

Comments
 (0)