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

Configure Feed

Select the types of activity you want to include in your feed.

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 <tzimmermann@suse.de>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20221115115819.23088-6-tzimmermann@suse.de

+25 -1
+8 -1
drivers/gpu/drm/drm_fb_helper.c
··· 599 599 static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y, 600 600 u32 width, u32 height) 601 601 { 602 + struct fb_info *info = helper->info; 603 + 602 604 drm_fb_helper_add_damage_clip(helper, x, y, width, height); 603 605 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); 605 612 } 606 613 607 614 /*
+16
drivers/video/fbdev/core/fb_defio.c
··· 332 332 mutex_destroy(&fbdefio->lock); 333 333 } 334 334 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);
+1
include/linux/fb.h
··· 663 663 struct inode *inode, 664 664 struct file *file); 665 665 extern void fb_deferred_io_cleanup(struct fb_info *info); 666 + extern void fb_deferred_io_schedule_flush(struct fb_info *info); 666 667 extern int fb_deferred_io_fsync(struct file *file, loff_t start, 667 668 loff_t end, int datasync); 668 669