fbdev: Use pageref offset for deferred-I/O writeback
authorThomas Zimmermann <tzimmermann@suse.de>
Fri, 29 Apr 2022 10:08:34 +0000 (12:08 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Tue, 3 May 2022 14:04:22 +0000 (16:04 +0200)
Use pageref->offset instead of page->index for deferred-I/O writeback
where appropriate. Distinguishes between file-mapping offset and video-
memory offset. While at it, also remove unnecessary references to
struct page.

Fbdev's deferred-I/O code uses the two related page->index and
pageref->offset. The former is the page offset in the mapped file,
the latter is the byte offset in the video memory (or fbdev screen
buffer). It's the same value for fbdev drivers, but for DRM the values
can be different. Because GEM buffer objects are mapped at an offset
in the DRM device file, page->index has this offset added to it as well.
We currently don't hit this case in DRM, because all affected mappings
of GEM memory are performed with an internal, intermediate shadow buffer.

The value of page->index is required by page_mkclean(), which we
call to reset the mappings during the writeback phase of the deferred
I/O. The value of pageref->offset is for conveniently getting an offset
into video memory in fb helpers.

v4:
* fix commit message (Javier)

Suggested-by: Javier Martinez Canillas <javierm@redhat.com>
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-6-tzimmermann@suse.de
drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
drivers/staging/fbtft/fbtft-core.c
drivers/video/fbdev/broadsheetfb.c
drivers/video/fbdev/hyperv_fb.c
drivers/video/fbdev/metronomefb.c
drivers/video/fbdev/sh_mobile_lcdcfb.c
drivers/video/fbdev/smscufx.c
drivers/video/fbdev/udlfb.c
drivers/video/fbdev/xen-fbfront.c

index 9a3dc5c4eec85a5ca27ca43203779a2fa21ba143..0ba9739f406dd3ab5cb5ed09528b6174868a44c9 100644 (file)
@@ -327,8 +327,7 @@ static void vmw_deferred_io(struct fb_info *info, struct list_head *pagereflist)
        min = ULONG_MAX;
        max = 0;
        list_for_each_entry(pageref, pagereflist, list) {
-               struct page *page = pageref->page;
-               start = page->index << PAGE_SHIFT;
+               start = pageref->offset;
                end = start + PAGE_SIZE - 1;
                min = min(min, start);
                max = max(max, end);
index 8774bffe94ccc1179c8837bb975f3b7a64099a31..60b2278d8b160ef9ba768857428cc649e0d9b577 100644 (file)
@@ -327,7 +327,6 @@ static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagereflis
        struct fbtft_par *par = info->par;
        unsigned int dirty_lines_start, dirty_lines_end;
        struct fb_deferred_io_pageref *pageref;
-       unsigned long index;
        unsigned int y_low = 0, y_high = 0;
        int count = 0;
 
@@ -341,14 +340,12 @@ static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagereflis
 
        /* Mark display lines as dirty */
        list_for_each_entry(pageref, pagereflist, list) {
-               struct page *page = pageref->page;
                count++;
-               index = page->index << PAGE_SHIFT;
-               y_low = index / info->fix.line_length;
-               y_high = (index + PAGE_SIZE - 1) / info->fix.line_length;
+               y_low = pageref->offset / info->fix.line_length;
+               y_high = (pageref->offset + PAGE_SIZE - 1) / info->fix.line_length;
                dev_dbg(info->device,
                        "page->index=%lu y_low=%d y_high=%d\n",
-                       page->index, y_low, y_high);
+                       pageref->page->index, y_low, y_high);
                if (y_high > info->var.yres - 1)
                        y_high = info->var.yres - 1;
                if (y_low < dirty_lines_start)
index 883a3ac03189e05cfac8287f876fca8b71bd868f..55e62dd96f9bef0ee3f6ff7915517feac9a6e6cf 100644 (file)
@@ -932,7 +932,7 @@ static void broadsheetfb_dpy_update(struct broadsheetfb_par *par)
 static void broadsheetfb_dpy_deferred_io(struct fb_info *info, struct list_head *pagereflist)
 {
        u16 y1 = 0, h = 0;
-       int prev_index = -1;
+       unsigned long prev_offset = ULONG_MAX;
        struct fb_deferred_io_pageref *pageref;
        int h_inc;
        u16 yres = info->var.yres;
@@ -943,22 +943,21 @@ static void broadsheetfb_dpy_deferred_io(struct fb_info *info, struct list_head
 
        /* walk the written page list and swizzle the data */
        list_for_each_entry(pageref, pagereflist, list) {
-               struct page *cur = pageref->page;
-               if (prev_index < 0) {
+               if (prev_offset == ULONG_MAX) {
                        /* just starting so assign first page */
-                       y1 = (cur->index << PAGE_SHIFT) / xres;
+                       y1 = pageref->offset / xres;
                        h = h_inc;
-               } else if ((prev_index + 1) == cur->index) {
+               } else if ((prev_offset + PAGE_SIZE) == pageref->offset) {
                        /* this page is consecutive so increase our height */
                        h += h_inc;
                } else {
                        /* page not consecutive, issue previous update first */
                        broadsheetfb_dpy_update_pages(info->par, y1, y1 + h);
                        /* start over with our non consecutive page */
-                       y1 = (cur->index << PAGE_SHIFT) / xres;
+                       y1 = pageref->offset / xres;
                        h = h_inc;
                }
-               prev_index = cur->index;
+               prev_offset = pageref->offset;
        }
 
        /* if we still have any pages to update we do so now */
index 550cf099007021863db8cd51b98213f337b9b5e5..8359a513b600f1ab02b536994df6fb4992d081d0 100644 (file)
@@ -437,8 +437,7 @@ static void synthvid_deferred_io(struct fb_info *p, struct list_head *pagereflis
         * value to yres.
         */
        list_for_each_entry(pageref, pagereflist, list) {
-               struct page *page = pageref->page;
-               start = page->index << PAGE_SHIFT;
+               start = pageref->offset;
                end = start + PAGE_SIZE - 1;
                y1 = start / p->fix.line_length;
                y2 = end / p->fix.line_length;
index f581c73d39dfbb2372d28facfc422db655f33071..9fd4bb85d7356464156dab08faeebb4da2999911 100644 (file)
@@ -473,11 +473,10 @@ static void metronomefb_dpy_deferred_io(struct fb_info *info, struct list_head *
 
        /* walk the written page list and swizzle the data */
        list_for_each_entry(pageref, pagereflist, list) {
-               struct page *cur = pageref->page;
-               cksum = metronomefb_dpy_update_page(par,
-                                       (cur->index << PAGE_SHIFT));
-               par->metromem_img_csum -= par->csum_table[cur->index];
-               par->csum_table[cur->index] = cksum;
+               unsigned long pgoffset = pageref->offset >> PAGE_SHIFT;
+               cksum = metronomefb_dpy_update_page(par, pageref->offset);
+               par->metromem_img_csum -= par->csum_table[pgoffset];
+               par->csum_table[pgoffset] = cksum;
                par->metromem_img_csum += cksum;
        }
 
index 2b060eca4360a19c556c058e90a1d1436a5af696..6d00893d41f4ca2de2fc8be8391b0c6e56f46f78 100644 (file)
@@ -445,8 +445,7 @@ static int sh_mobile_lcdc_sginit(struct fb_info *info, struct list_head *pageref
        sg_init_table(ch->sglist, nr_pages_max);
 
        list_for_each_entry(pageref, pagereflist, list) {
-               struct page *page = pageref->page;
-               sg_set_page(&ch->sglist[nr_pages++], page, PAGE_SIZE, 0);
+               sg_set_page(&ch->sglist[nr_pages++], pageref->page, PAGE_SIZE, 0);
        }
 
        return nr_pages;
index 7f00605bc0d18e0d3da3da916dc736257ecd4835..d7aa5511c3617a07fe9e003ef4e5b539d58d2548 100644 (file)
@@ -970,10 +970,9 @@ static void ufx_dpy_deferred_io(struct fb_info *info, struct list_head *pagerefl
        list_for_each_entry(pageref, pagereflist, list) {
                /* create a rectangle of full screen width that encloses the
                 * entire dirty framebuffer page */
-               struct page *cur = pageref->page;
                const int x = 0;
                const int width = dev->info->var.xres;
-               const int y = (cur->index << PAGE_SHIFT) / (width * 2);
+               const int y = pageref->offset / (width * 2);
                int height = (PAGE_SIZE / (width * 2)) + 1;
                height = min(height, (int)(dev->info->var.yres - y));
 
index 66eefd317431e155274ef5f8d9f48b37cdb28d31..c863244ef12cb8dde40d9f4e61eee03430c45da5 100644 (file)
@@ -810,11 +810,9 @@ static void dlfb_dpy_deferred_io(struct fb_info *info, struct list_head *pageref
 
        /* walk the written page list and render each to device */
        list_for_each_entry(pageref, pagereflist, list) {
-               struct page *cur = pageref->page;
-
                if (dlfb_render_hline(dlfb, &urb, (char *) info->fix.smem_start,
-                                 &cmd, cur->index << PAGE_SHIFT,
-                                 PAGE_SIZE, &bytes_identical, &bytes_sent))
+                                     &cmd, pageref->offset, PAGE_SIZE,
+                                     &bytes_identical, &bytes_sent))
                        goto error;
                bytes_rendered += PAGE_SIZE;
        }
index bc8244b9ce0311ad7388d2fe7945a06196bea5b6..3bed357a98703e30db607325deab3e5c6cb1e411 100644 (file)
@@ -191,8 +191,7 @@ static void xenfb_deferred_io(struct fb_info *fb_info, struct list_head *pageref
        miny = INT_MAX;
        maxy = 0;
        list_for_each_entry(pageref, pagereflist, list) {
-               struct page *page = pageref->page;
-               beg = page->index << PAGE_SHIFT;
+               beg = pageref->offset;
                end = beg + PAGE_SIZE - 1;
                y1 = beg / fb_info->fix.line_length;
                y2 = end / fb_info->fix.line_length;