fbdev: defio: Move pageref array to struct fb_deferred_io_state

The pageref array stores all pageref structures for a device's defio
helpers. Move it into struct fb_deferred_io_state to not expose it to
drivers.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Helge Deller <deller@gmx.de>
This commit is contained in:
Thomas Zimmermann 2026-02-24 09:25:57 +01:00 committed by Helge Deller
parent 648bfb62da
commit 02fe86e5fc
2 changed files with 27 additions and 30 deletions

View File

@ -41,28 +41,46 @@ struct fb_deferred_io_state {
/* fields protected by lock */
struct fb_info *info;
struct list_head pagereflist; /* list of pagerefs for touched pages */
unsigned long npagerefs;
struct fb_deferred_io_pageref *pagerefs;
};
static struct fb_deferred_io_state *fb_deferred_io_state_alloc(void)
static struct fb_deferred_io_state *fb_deferred_io_state_alloc(unsigned long len)
{
struct fb_deferred_io_state *fbdefio_state;
struct fb_deferred_io_pageref *pagerefs;
unsigned long npagerefs;
fbdefio_state = kzalloc_obj(*fbdefio_state);
if (!fbdefio_state)
return NULL;
npagerefs = DIV_ROUND_UP(len, PAGE_SIZE);
/* alloc a page ref for each page of the display memory */
pagerefs = kvzalloc_objs(*pagerefs, npagerefs);
if (!pagerefs)
goto err_kfree;
fbdefio_state->npagerefs = npagerefs;
fbdefio_state->pagerefs = pagerefs;
kref_init(&fbdefio_state->ref);
mutex_init(&fbdefio_state->lock);
INIT_LIST_HEAD(&fbdefio_state->pagereflist);
return fbdefio_state;
err_kfree:
kfree(fbdefio_state);
return NULL;
}
static void fb_deferred_io_state_release(struct fb_deferred_io_state *fbdefio_state)
{
WARN_ON(!list_empty(&fbdefio_state->pagereflist));
mutex_destroy(&fbdefio_state->lock);
kvfree(fbdefio_state->pagerefs);
kfree(fbdefio_state);
}
@ -125,18 +143,19 @@ static struct page *fb_deferred_io_get_page(struct fb_info *info, unsigned long
return page;
}
static struct fb_deferred_io_pageref *fb_deferred_io_pageref_lookup(struct fb_info *info,
unsigned long offset,
struct page *page)
static struct fb_deferred_io_pageref *
fb_deferred_io_pageref_lookup(struct fb_deferred_io_state *fbdefio_state, unsigned long offset,
struct page *page)
{
struct fb_info *info = fbdefio_state->info;
unsigned long pgoff = offset >> PAGE_SHIFT;
struct fb_deferred_io_pageref *pageref;
if (fb_WARN_ON_ONCE(info, pgoff >= info->npagerefs))
if (fb_WARN_ON_ONCE(info, pgoff >= fbdefio_state->npagerefs))
return NULL; /* incorrect allocation size */
/* 1:1 mapping between pageref and page offset */
pageref = &info->pagerefs[pgoff];
pageref = &fbdefio_state->pagerefs[pgoff];
if (pageref->page)
goto out;
@ -160,7 +179,7 @@ static struct fb_deferred_io_pageref *fb_deferred_io_pageref_get(struct fb_info
struct list_head *pos = &fbdefio_state->pagereflist;
struct fb_deferred_io_pageref *pageref, *cur;
pageref = fb_deferred_io_pageref_lookup(info, offset, page);
pageref = fb_deferred_io_pageref_lookup(fbdefio_state, offset, page);
if (!pageref)
return NULL;
@ -397,16 +416,13 @@ int fb_deferred_io_init(struct fb_info *info)
{
struct fb_deferred_io *fbdefio = info->fbdefio;
struct fb_deferred_io_state *fbdefio_state;
struct fb_deferred_io_pageref *pagerefs;
unsigned long npagerefs;
int ret;
BUG_ON(!fbdefio);
if (WARN_ON(!info->fix.smem_len))
return -EINVAL;
fbdefio_state = fb_deferred_io_state_alloc();
fbdefio_state = fb_deferred_io_state_alloc(info->fix.smem_len);
if (!fbdefio_state)
return -ENOMEM;
fbdefio_state->info = info;
@ -415,24 +431,9 @@ int fb_deferred_io_init(struct fb_info *info)
if (fbdefio->delay == 0) /* set a default of 1 s */
fbdefio->delay = HZ;
npagerefs = DIV_ROUND_UP(info->fix.smem_len, PAGE_SIZE);
/* alloc a page ref for each page of the display memory */
pagerefs = kvzalloc_objs(*pagerefs, npagerefs);
if (!pagerefs) {
ret = -ENOMEM;
goto err;
}
info->npagerefs = npagerefs;
info->pagerefs = pagerefs;
info->fbdefio_state = fbdefio_state;
return 0;
err:
fb_deferred_io_state_release(fbdefio_state);
return ret;
}
EXPORT_SYMBOL_GPL(fb_deferred_io_init);
@ -475,7 +476,5 @@ void fb_deferred_io_cleanup(struct fb_info *info)
mutex_unlock(&fbdefio_state->lock);
fb_deferred_io_state_put(fbdefio_state);
kvfree(info->pagerefs);
}
EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);

View File

@ -482,8 +482,6 @@ struct fb_info {
#ifdef CONFIG_FB_DEFERRED_IO
struct delayed_work deferred_work;
unsigned long npagerefs;
struct fb_deferred_io_pageref *pagerefs;
struct fb_deferred_io *fbdefio;
struct fb_deferred_io_state *fbdefio_state;
#endif