Commit 62884cd3 authored by Keith Packard's avatar Keith Packard Committed by Dave Airlie

drm: Add four ioctls for managing drm mode object leases [v7]

drm_mode_create_lease

	Creates a lease for a list of drm mode objects, returning an
	fd for the new drm_master and a 64-bit identifier for the lessee

drm_mode_list_lesees

	List the identifiers of the lessees for a master file

drm_mode_get_lease

	List the leased objects for a master file

drm_mode_revoke_lease

	Erase the set of objects managed by a lease.

This should suffice to at least create and query leases.

Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>:

 * query ioctls only query the master associated with
   the provided file.

 * 'mask_lease' value has been removed

 * change ioctl has been removed.

Changes for v3 suggested in part by Dave Airlie <airlied@gmail.com>

 * Add revoke ioctl.

Changes for v4 suggested by Dave Airlie <airlied@gmail.com>

 * Expand on the comment about the magic use of &drm_lease_idr_object
 * Pad lease ioctl structures to align on 64-bit boundaries

Changes for v5 suggested by Dave Airlie <airlied@gmail.com>

 * Check for non-negative object_id in create_lease to avoid debug
   output from the kernel.

Changes for v6 provided by Dave Airlie <airlied@gmail.com>

 * For non-universal planes add primary/cursor planes to lease

   If we aren't exposing universal planes to this userspace client,
   and it requests a lease on a crtc, we should implicitly export the
   primary and cursor planes for the crtc.

   If the lessee doesn't request universal planes, it will just see
   the crtc, but if it does request them it will then see the plane
   objects as well.

   This also moves the object look ups earlier as a side effect, so
   we'd exit the ioctl quicker for non-existant objects.

 * Restrict leases to crtc/connector/planes.

   This only allows leasing for objects we wish to allow.

Changes for v7 provided by Dave Airlie <airlied@gmail.com>

 * Check pad args are 0
 * Check create flags and object count are valid.
 * Check return from fd allocation
 * Refactor lease idr setup and add some simple validation
 * Use idr_mutex uniformly (Keith)
Signed-off-by: default avatarKeith Packard <keithp@keithp.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 7de440db
...@@ -665,6 +665,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = { ...@@ -665,6 +665,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
}; };
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
......
This diff is collapsed.
...@@ -111,7 +111,7 @@ void drm_mode_object_unregister(struct drm_device *dev, ...@@ -111,7 +111,7 @@ void drm_mode_object_unregister(struct drm_device *dev,
* Returns whether the provided type of drm_mode_object must * Returns whether the provided type of drm_mode_object must
* be owned or leased to be used by a process. * be owned or leased to be used by a process.
*/ */
static bool drm_lease_required(uint32_t type) bool drm_mode_object_lease_required(uint32_t type)
{ {
switch(type) { switch(type) {
case DRM_MODE_OBJECT_CRTC: case DRM_MODE_OBJECT_CRTC:
...@@ -136,7 +136,8 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, ...@@ -136,7 +136,8 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
if (obj && obj->id != id) if (obj && obj->id != id)
obj = NULL; obj = NULL;
if (obj && drm_lease_required(obj->type) && !_drm_lease_held(file_priv, obj->id)) if (obj && drm_mode_object_lease_required(obj->type) &&
!_drm_lease_held(file_priv, obj->id))
obj = NULL; obj = NULL;
if (obj && obj->free_cb) { if (obj && obj->free_cb) {
......
...@@ -31,4 +31,16 @@ void drm_lease_revoke(struct drm_master *master); ...@@ -31,4 +31,16 @@ void drm_lease_revoke(struct drm_master *master);
uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs); uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs);
int drm_mode_create_lease_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
int drm_mode_list_lessees_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
int drm_mode_get_lease_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
#endif /* _DRM_LEASE_H_ */ #endif /* _DRM_LEASE_H_ */
...@@ -154,4 +154,6 @@ int drm_object_property_get_value(struct drm_mode_object *obj, ...@@ -154,4 +154,6 @@ int drm_object_property_get_value(struct drm_mode_object *obj,
void drm_object_attach_property(struct drm_mode_object *obj, void drm_object_attach_property(struct drm_mode_object *obj,
struct drm_property *property, struct drm_property *property,
uint64_t init_val); uint64_t init_val);
bool drm_mode_object_lease_required(uint32_t type);
#endif #endif
...@@ -888,6 +888,11 @@ extern "C" { ...@@ -888,6 +888,11 @@ extern "C" {
#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array) #define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array)
#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array) #define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array)
#define DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC6, struct drm_mode_create_lease)
#define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct drm_mode_list_lessees)
#define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease)
#define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
/** /**
* Device specific ioctls should only be in their respective headers * Device specific ioctls should only be in their respective headers
* The device specific ioctl range is from 0x40 to 0x9f. * The device specific ioctl range is from 0x40 to 0x9f.
......
...@@ -782,6 +782,72 @@ struct drm_mode_destroy_blob { ...@@ -782,6 +782,72 @@ struct drm_mode_destroy_blob {
__u32 blob_id; __u32 blob_id;
}; };
/**
* Lease mode resources, creating another drm_master.
*/
struct drm_mode_create_lease {
/** Pointer to array of object ids (__u32) */
__u64 object_ids;
/** Number of object ids */
__u32 object_count;
/** flags for new FD (O_CLOEXEC, etc) */
__u32 flags;
/** Return: unique identifier for lessee. */
__u32 lessee_id;
/** Return: file descriptor to new drm_master file */
__u32 fd;
};
/**
* List lesses from a drm_master
*/
struct drm_mode_list_lessees {
/** Number of lessees.
* On input, provides length of the array.
* On output, provides total number. No
* more than the input number will be written
* back, so two calls can be used to get
* the size and then the data.
*/
__u32 count_lessees;
__u32 pad;
/** Pointer to lessees.
* pointer to __u64 array of lessee ids
*/
__u64 lessees_ptr;
};
/**
* Get leased objects
*/
struct drm_mode_get_lease {
/** Number of leased objects.
* On input, provides length of the array.
* On output, provides total number. No
* more than the input number will be written
* back, so two calls can be used to get
* the size and then the data.
*/
__u32 count_objects;
__u32 pad;
/** Pointer to objects.
* pointer to __u32 array of object ids
*/
__u64 objects_ptr;
};
/**
* Revoke lease
*/
struct drm_mode_revoke_lease {
/** Unique ID of lessee
*/
__u32 lessee_id;
};
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif
......
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