Skip to content

Commit

Permalink
drm: extract closefb logic in separate function
Browse files Browse the repository at this point in the history
drm_mode_rmfb performs two operations: drop the FB from the
file_priv->fbs list, and make sure the FB is no longer used on a
plane.

In the next commit an IOCTL which only does so former will be
introduced, so let's split it into a separate function.

No functional change, only refactoring.

v2: no change

Signed-off-by: Simon Ser <contact@emersion.fr>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Dennis Filder <d.filder@web.de>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Rob Clark <robdclark@gmail.com>
Cc: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231020101926.145327-1-contact@emersion.fr
  • Loading branch information
Simon Ser committed Oct 27, 2023
1 parent 80683bf commit 0226ba3
Showing 1 changed file with 31 additions and 22 deletions.
53 changes: 31 additions & 22 deletions drivers/gpu/drm/drm_framebuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,31 @@ static void drm_mode_rmfb_work_fn(struct work_struct *w)
}
}

static int drm_mode_closefb(struct drm_framebuffer *fb,
struct drm_file *file_priv)
{
struct drm_framebuffer *fbl;
bool found = false;

mutex_lock(&file_priv->fbs_lock);
list_for_each_entry(fbl, &file_priv->fbs, filp_head)
if (fb == fbl)
found = true;

if (!found) {
mutex_unlock(&file_priv->fbs_lock);
return -ENOENT;
}

list_del_init(&fb->filp_head);
mutex_unlock(&file_priv->fbs_lock);

/* Drop the reference that was stored in the fbs list */
drm_framebuffer_put(fb);

return 0;
}

/**
* drm_mode_rmfb - remove an FB from the configuration
* @dev: drm device
Expand All @@ -410,9 +435,8 @@ static void drm_mode_rmfb_work_fn(struct work_struct *w)
int drm_mode_rmfb(struct drm_device *dev, u32 fb_id,
struct drm_file *file_priv)
{
struct drm_framebuffer *fb = NULL;
struct drm_framebuffer *fbl = NULL;
int found = 0;
struct drm_framebuffer *fb;
int ret;

if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EOPNOTSUPP;
Expand All @@ -421,24 +445,13 @@ int drm_mode_rmfb(struct drm_device *dev, u32 fb_id,
if (!fb)
return -ENOENT;

mutex_lock(&file_priv->fbs_lock);
list_for_each_entry(fbl, &file_priv->fbs, filp_head)
if (fb == fbl)
found = 1;
if (!found) {
mutex_unlock(&file_priv->fbs_lock);
goto fail_unref;
ret = drm_mode_closefb(fb, file_priv);
if (ret != 0) {
drm_framebuffer_put(fb);
return ret;
}

list_del_init(&fb->filp_head);
mutex_unlock(&file_priv->fbs_lock);

/* drop the reference we picked up in framebuffer lookup */
drm_framebuffer_put(fb);

/*
* we now own the reference that was stored in the fbs list
*
* drm_framebuffer_remove may fail with -EINTR on pending signals,
* so run this in a separate stack as there's no way to correctly
* handle this after the fb is already removed from the lookup table.
Expand All @@ -457,10 +470,6 @@ int drm_mode_rmfb(struct drm_device *dev, u32 fb_id,
drm_framebuffer_put(fb);

return 0;

fail_unref:
drm_framebuffer_put(fb);
return -ENOENT;
}

int drm_mode_rmfb_ioctl(struct drm_device *dev,
Expand Down

0 comments on commit 0226ba3

Please sign in to comment.