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

fbdev: Refactor implementation of page_mkwrite

Refactor the page-write handler for deferred I/O. Drivers use the
function to let fbdev track written pages of mmap'ed framebuffer
memory.

v3:
* keep locking within track-pages function for readability (Sam)
v2:
* don't export the helper until we have an external caller

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220429100834.18898-4-tzimmermann@suse.de

+38 -15
+38 -15
drivers/video/fbdev/core/fb_defio.c
··· 143 143 } 144 144 EXPORT_SYMBOL_GPL(fb_deferred_io_fsync); 145 145 146 - /* vm_ops->page_mkwrite handler */ 147 - static vm_fault_t fb_deferred_io_mkwrite(struct vm_fault *vmf) 146 + /* 147 + * Adds a page to the dirty list. Call this from struct 148 + * vm_operations_struct.page_mkwrite. 149 + */ 150 + static vm_fault_t fb_deferred_io_track_page(struct fb_info *info, unsigned long offset, 151 + struct page *page) 148 152 { 149 - struct page *page = vmf->page; 150 - struct fb_info *info = vmf->vma->vm_private_data; 151 153 struct fb_deferred_io *fbdefio = info->fbdefio; 152 154 struct fb_deferred_io_pageref *pageref; 153 - unsigned long offset; 154 155 vm_fault_t ret; 155 - 156 - offset = (vmf->address - vmf->vma->vm_start); 157 - 158 - /* this is a callback we get when userspace first tries to 159 - write to the page. we schedule a workqueue. that workqueue 160 - will eventually mkclean the touched pages and execute the 161 - deferred framebuffer IO. then if userspace touches a page 162 - again, we repeat the same scheme */ 163 - 164 - file_update_time(vmf->vma->vm_file); 165 156 166 157 /* protect against the workqueue changing the page list */ 167 158 mutex_lock(&fbdefio->lock); ··· 186 195 err_mutex_unlock: 187 196 mutex_unlock(&fbdefio->lock); 188 197 return ret; 198 + } 199 + 200 + /* 201 + * fb_deferred_io_page_mkwrite - Mark a page as written for deferred I/O 202 + * @fb_info: The fbdev info structure 203 + * @vmf: The VM fault 204 + * 205 + * This is a callback we get when userspace first tries to 206 + * write to the page. We schedule a workqueue. That workqueue 207 + * will eventually mkclean the touched pages and execute the 208 + * deferred framebuffer IO. Then if userspace touches a page 209 + * again, we repeat the same scheme. 210 + * 211 + * Returns: 212 + * VM_FAULT_LOCKED on success, or a VM_FAULT error otherwise. 213 + */ 214 + static vm_fault_t fb_deferred_io_page_mkwrite(struct fb_info *info, struct vm_fault *vmf) 215 + { 216 + unsigned long offset = vmf->address - vmf->vma->vm_start; 217 + struct page *page = vmf->page; 218 + 219 + file_update_time(vmf->vma->vm_file); 220 + 221 + return fb_deferred_io_track_page(info, offset, page); 222 + } 223 + 224 + /* vm_ops->page_mkwrite handler */ 225 + static vm_fault_t fb_deferred_io_mkwrite(struct vm_fault *vmf) 226 + { 227 + struct fb_info *info = vmf->vma->vm_private_data; 228 + 229 + return fb_deferred_io_page_mkwrite(info, vmf); 189 230 } 190 231 191 232 static const struct vm_operations_struct fb_deferred_io_vm_ops = {