Commit d208d875 authored by Simon Ser's avatar Simon Ser
Browse files

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/20170509153654.23464-1-robdclark@gmail.com/
[2]: https://lore.kernel.org/dri-devel/20211006151921.312714-1-contact@emersion.fr/
[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: default avatarSimon Ser <contact@emersion.fr>
Reviewed-by: default avatarDaniel Stone <daniels@collabora.com>
Acked-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Dennis Filder <d.filder@web.de>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Rob Clark <robdclark@gmail.com>
Cc: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20231020101926.145327-2-contact@emersion.fr
parent 0226ba39
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -222,6 +222,8 @@ int drm_mode_addfb2_ioctl(struct drm_device *dev,
			  void *data, struct drm_file *file_priv);
int drm_mode_rmfb_ioctl(struct drm_device *dev,
			void *data, struct drm_file *file_priv);
int drm_mode_closefb_ioctl(struct drm_device *dev,
			   void *data, struct drm_file *file_priv);
int drm_mode_getfb(struct drm_device *dev,
		   void *data, struct drm_file *file_priv);
int drm_mode_getfb2_ioctl(struct drm_device *dev,
+22 −0
Original line number Diff line number Diff line
@@ -480,6 +480,28 @@ int drm_mode_rmfb_ioctl(struct drm_device *dev,
	return drm_mode_rmfb(dev, *fb_id, file_priv);
}

int drm_mode_closefb_ioctl(struct drm_device *dev,
			   void *data, struct drm_file *file_priv)
{
	struct drm_mode_closefb *r = data;
	struct drm_framebuffer *fb;
	int ret;

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return -EOPNOTSUPP;

	if (r->pad)
		return -EINVAL;

	fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
	if (!fb)
		return -ENOENT;

	ret = drm_mode_closefb(fb, file_priv);
	drm_framebuffer_put(fb);
	return ret;
}

/**
 * drm_mode_getfb - get FB info
 * @dev: drm device for the ioctl
+1 −0
Original line number Diff line number Diff line
@@ -675,6 +675,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb_ioctl, 0),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2_ioctl, 0),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb_ioctl, 0),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CLOSEFB, drm_mode_closefb_ioctl, 0),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, 0),
+20 −0
Original line number Diff line number Diff line
@@ -1218,6 +1218,26 @@ extern "C" {

#define DRM_IOCTL_SYNCOBJ_EVENTFD	DRM_IOWR(0xCF, struct drm_syncobj_eventfd)

/**
 * DRM_IOCTL_MODE_CLOSEFB - Close a framebuffer.
 *
 * This closes a framebuffer previously added via ADDFB/ADDFB2. The IOCTL
 * argument is a framebuffer object ID.
 *
 * This IOCTL is similar to &DRM_IOCTL_MODE_RMFB, except it doesn't disable
 * planes and CRTCs. As long as the framebuffer is used by a plane, it's kept
 * alive. When the plane no longer uses the framebuffer (because the
 * framebuffer is replaced with another one, or the plane is disabled), the
 * framebuffer is cleaned up.
 *
 * This is useful to implement flicker-free transitions between two processes.
 *
 * Depending on the threat model, user-space may want to ensure that the
 * framebuffer doesn't expose any sensitive user information: closed
 * framebuffers attached to a plane can be read back by the next DRM master.
 */
#define DRM_IOCTL_MODE_CLOSEFB		DRM_IOWR(0xD0, struct drm_mode_closefb)

/*
 * Device specific ioctls should only be in their respective headers
 * The device specific ioctl range is from 0x40 to 0x9f.
+10 −0
Original line number Diff line number Diff line
@@ -1323,6 +1323,16 @@ struct drm_mode_rect {
	__s32 y2;
};

/**
 * struct drm_mode_closefb
 * @fb_id: Framebuffer ID.
 * @pad: Must be zero.
 */
struct drm_mode_closefb {
	__u32 fb_id;
	__u32 pad;
};

#if defined(__cplusplus)
}
#endif