Commit 757a2713 authored by Thomas Zimmermann's avatar Thomas Zimmermann

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: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarJavier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240419083331.7761-3-tzimmermann@suse.de
parent 73ef0aec
......@@ -36,21 +36,44 @@ 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_get(struct fb_info *info,
static struct fb_deferred_io_pageref *fb_deferred_io_pageref_lookup(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;
struct fb_deferred_io_pageref *pageref;
if (WARN_ON_ONCE(pgoff >= info->npagerefs))
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;
struct fb_deferred_io_pageref *pageref, *cur;
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
* writing to the same page through a new PTE. This new access
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment