Skip to content

Commit d208d87

Browse files
committed
drm: introduce CLOSEFB IOCTL
This new IOCTL allows callers to close a framebuffer without disabling planes or CRTCs. This takes inspiration from Rob Clark's unref_fb IOCTL [1] and DRM_MODE_FB_PERSIST [2]. User-space patch for wlroots available at [3]. IGT test available at [4]. v2: add an extra pad field just in case we want to extend this IOCTL in the future (Pekka, Sima). [1]: https://lore.kernel.org/dri-devel/[email protected]/ [2]: https://lore.kernel.org/dri-devel/[email protected]/ [3]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4394 [4]: https://lists.freedesktop.org/archives/igt-dev/2023-October/063294.html Signed-off-by: Simon Ser <[email protected]> Reviewed-by: Daniel Stone <[email protected]> Acked-by: Pekka Paalanen <[email protected]> Cc: Hans de Goede <[email protected]> Cc: Dennis Filder <[email protected]> Cc: Daniel Vetter <[email protected]> Cc: Rob Clark <[email protected]> Cc: Sean Paul <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 0226ba3 commit d208d87

File tree

5 files changed

+55
-0
lines changed

5 files changed

+55
-0
lines changed

drivers/gpu/drm/drm_crtc_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ int drm_mode_addfb2_ioctl(struct drm_device *dev,
222222
void *data, struct drm_file *file_priv);
223223
int drm_mode_rmfb_ioctl(struct drm_device *dev,
224224
void *data, struct drm_file *file_priv);
225+
int drm_mode_closefb_ioctl(struct drm_device *dev,
226+
void *data, struct drm_file *file_priv);
225227
int drm_mode_getfb(struct drm_device *dev,
226228
void *data, struct drm_file *file_priv);
227229
int drm_mode_getfb2_ioctl(struct drm_device *dev,

drivers/gpu/drm/drm_framebuffer.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,28 @@ int drm_mode_rmfb_ioctl(struct drm_device *dev,
480480
return drm_mode_rmfb(dev, *fb_id, file_priv);
481481
}
482482

483+
int drm_mode_closefb_ioctl(struct drm_device *dev,
484+
void *data, struct drm_file *file_priv)
485+
{
486+
struct drm_mode_closefb *r = data;
487+
struct drm_framebuffer *fb;
488+
int ret;
489+
490+
if (!drm_core_check_feature(dev, DRIVER_MODESET))
491+
return -EOPNOTSUPP;
492+
493+
if (r->pad)
494+
return -EINVAL;
495+
496+
fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
497+
if (!fb)
498+
return -ENOENT;
499+
500+
ret = drm_mode_closefb(fb, file_priv);
501+
drm_framebuffer_put(fb);
502+
return ret;
503+
}
504+
483505
/**
484506
* drm_mode_getfb - get FB info
485507
* @dev: drm device for the ioctl

drivers/gpu/drm/drm_ioctl.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
675675
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb_ioctl, 0),
676676
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2_ioctl, 0),
677677
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb_ioctl, 0),
678+
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CLOSEFB, drm_mode_closefb_ioctl, 0),
678679
DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER),
679680
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER),
680681
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, 0),

include/uapi/drm/drm.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,26 @@ extern "C" {
12181218

12191219
#define DRM_IOCTL_SYNCOBJ_EVENTFD DRM_IOWR(0xCF, struct drm_syncobj_eventfd)
12201220

1221+
/**
1222+
* DRM_IOCTL_MODE_CLOSEFB - Close a framebuffer.
1223+
*
1224+
* This closes a framebuffer previously added via ADDFB/ADDFB2. The IOCTL
1225+
* argument is a framebuffer object ID.
1226+
*
1227+
* This IOCTL is similar to &DRM_IOCTL_MODE_RMFB, except it doesn't disable
1228+
* planes and CRTCs. As long as the framebuffer is used by a plane, it's kept
1229+
* alive. When the plane no longer uses the framebuffer (because the
1230+
* framebuffer is replaced with another one, or the plane is disabled), the
1231+
* framebuffer is cleaned up.
1232+
*
1233+
* This is useful to implement flicker-free transitions between two processes.
1234+
*
1235+
* Depending on the threat model, user-space may want to ensure that the
1236+
* framebuffer doesn't expose any sensitive user information: closed
1237+
* framebuffers attached to a plane can be read back by the next DRM master.
1238+
*/
1239+
#define DRM_IOCTL_MODE_CLOSEFB DRM_IOWR(0xD0, struct drm_mode_closefb)
1240+
12211241
/*
12221242
* Device specific ioctls should only be in their respective headers
12231243
* The device specific ioctl range is from 0x40 to 0x9f.

include/uapi/drm/drm_mode.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,16 @@ struct drm_mode_rect {
13231323
__s32 y2;
13241324
};
13251325

1326+
/**
1327+
* struct drm_mode_closefb
1328+
* @fb_id: Framebuffer ID.
1329+
* @pad: Must be zero.
1330+
*/
1331+
struct drm_mode_closefb {
1332+
__u32 fb_id;
1333+
__u32 pad;
1334+
};
1335+
13261336
#if defined(__cplusplus)
13271337
}
13281338
#endif

0 commit comments

Comments
 (0)