summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2024-04-19 10:28:55 +0200
committerThomas Zimmermann <tzimmermann@suse.de>2024-05-02 11:33:12 +0200
commit757a2713761fa90bb8f57cba231a3e7259944463 (patch)
tree2fdb376f07bb77194c900ad079df9c77e14e114c
parent73ef0aecba78aa9ebd309b10b6cd17d94e632892 (diff)
fbdev/deferred-io: Move pageref setup into separate helper
Set up struct fb_deferred_io_pageref in the new helper function fb_deferred_io_pageref_lookup(), which runs when the pageref is first taken. Remove the setup code from the rest of the code. At first, the code allocates the memory of all pageref structs. The setup of the various fields happens when the pageref is required. v2: - fix typo in commit message (Javier) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240419083331.7761-3-tzimmermann@suse.de
-rw-r--r--drivers/video/fbdev/core/fb_defio.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c
index 806ecd32219b..dc3b4dc4d507 100644
--- a/drivers/video/fbdev/core/fb_defio.c
+++ b/drivers/video/fbdev/core/fb_defio.c
@@ -36,20 +36,43 @@ static struct page *fb_deferred_io_page(struct fb_info *info, unsigned long offs
return page;
}
+static struct fb_deferred_io_pageref *fb_deferred_io_pageref_lookup(struct fb_info *info,
+ unsigned long offset,
+ struct page *page)
+{
+ unsigned long pgoff = offset >> PAGE_SHIFT;
+ struct fb_deferred_io_pageref *pageref;
+
+ if (fb_WARN_ON_ONCE(info, pgoff >= info->npagerefs))
+ return NULL; /* incorrect allocation size */
+
+ /* 1:1 mapping between pageref and page offset */
+ pageref = &info->pagerefs[pgoff];
+
+ if (pageref->page)
+ goto out;
+
+ pageref->page = page;
+ pageref->offset = pgoff << PAGE_SHIFT;
+ INIT_LIST_HEAD(&pageref->list);
+
+out:
+ if (fb_WARN_ON_ONCE(info, pageref->page != page))
+ return NULL; /* inconsistent state */
+ return pageref;
+}
+
static struct fb_deferred_io_pageref *fb_deferred_io_pageref_get(struct fb_info *info,
unsigned long offset,
struct page *page)
{
struct fb_deferred_io *fbdefio = info->fbdefio;
struct list_head *pos = &fbdefio->pagereflist;
- unsigned long pgoff = offset >> PAGE_SHIFT;
struct fb_deferred_io_pageref *pageref, *cur;
- if (WARN_ON_ONCE(pgoff >= info->npagerefs))
- return NULL; /* incorrect allocation size */
-
- /* 1:1 mapping between pageref and page offset */
- pageref = &info->pagerefs[pgoff];
+ pageref = fb_deferred_io_pageref_lookup(info, offset, page);
+ if (!pageref)
+ return NULL;
/*
* This check is to catch the case where a new process could start
@@ -60,9 +83,6 @@ static struct fb_deferred_io_pageref *fb_deferred_io_pageref_get(struct fb_info
if (!list_empty(&pageref->list))
goto pageref_already_added;
- pageref->page = page;
- pageref->offset = pgoff << PAGE_SHIFT;
-
if (unlikely(fbdefio->sort_pagereflist)) {
/*
* We loop through the list of pagerefs before adding in
@@ -264,7 +284,7 @@ int fb_deferred_io_init(struct fb_info *info)
{
struct fb_deferred_io *fbdefio = info->fbdefio;
struct fb_deferred_io_pageref *pagerefs;
- unsigned long npagerefs, i;
+ unsigned long npagerefs;
int ret;
BUG_ON(!fbdefio);
@@ -286,8 +306,6 @@ int fb_deferred_io_init(struct fb_info *info)
ret = -ENOMEM;
goto err;
}
- for (i = 0; i < npagerefs; ++i)
- INIT_LIST_HEAD(&pagerefs[i].list);
info->npagerefs = npagerefs;
info->pagerefs = pagerefs;