Skip to content

Commit 2ed077e

Browse files
keith-packardairlied
authored andcommitted
drm: Add drm_object lease infrastructure [v5]
This provides new data structures to hold "lease" information about drm mode setting objects, and provides for creating new drm_masters which have access to a subset of the available drm resources. An 'owner' is a drm_master which is not leasing the objects from another drm_master, and hence 'owns' them. A 'lessee' is a drm_master which is leasing objects from some other drm_master. Each lessee holds the set of objects which it is leasing from the lessor. A 'lessor' is a drm_master which is leasing objects to another drm_master. This is the same as the owner in the current code. The set of objects any drm_master 'controls' is limited to the set of objects it leases (for lessees) or all objects (for owners). Objects not controlled by a drm_master cannot be modified through the various state manipulating ioctls, and any state reported back to user space will be edited to make them appear idle and/or unusable. For instance, connectors always report 'disconnected', while encoders report no possible crtcs or clones. The full list of lessees leasing objects from an owner (either directly, or indirectly through another lessee), can be searched from an idr in the drm_master of the owner. Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>: * Sub-leasing has been disabled. * BUG_ON for lock checking replaced with lockdep_assert_held * 'change' ioctl has been removed. * Leased objects can always be controlled by the lessor; the 'mask_lease' flag has been removed * Checking for leased status has been simplified, replacing the drm_lease_check function with drm_lease_held. Changes in v3, some suggested by Dave Airlie <airlied@gmail.com> * Add revocation. This allows leases to be effectively revoked by removing all of the objects they have access to. The lease itself hangs around as it's hanging off a file. * Free the leases IDR when the master is destroyed * _drm_lease_held should look at lessees, not lessor * Allow non-master files to check for lease status Changes in v4, suggested by Dave Airlie <airlied@gmail.com> * Formatting and whitespace changes Changes in v5 (airlied) * check DRIVER_MODESET before lease destroy call * check DRIVER_MODESET for lease revoke (Chris) * Use idr_mutex uniformly for all lease elements of struct drm_master. (Keith) Signed-off-by: Keith Packard <keithp@keithp.com>
1 parent e7646f8 commit 2ed077e

File tree

6 files changed

+443
-2
lines changed

6 files changed

+443
-2
lines changed

drivers/gpu/drm/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
1717
drm_encoder.o drm_mode_object.o drm_property.o \
1818
drm_plane.o drm_color_mgmt.o drm_print.o \
1919
drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
20-
drm_syncobj.o
20+
drm_syncobj.o drm_lease.o
2121

2222
drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
2323
drm-$(CONFIG_DRM_VM) += drm_vm.o

drivers/gpu/drm/drm_auth.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <drm/drmP.h>
3232
#include "drm_internal.h"
3333
#include "drm_legacy.h"
34+
#include <drm/drm_lease.h>
3435

3536
/**
3637
* DOC: master and authentication
@@ -93,7 +94,7 @@ int drm_authmagic(struct drm_device *dev, void *data,
9394
return file ? 0 : -EINVAL;
9495
}
9596

96-
static struct drm_master *drm_master_create(struct drm_device *dev)
97+
struct drm_master *drm_master_create(struct drm_device *dev)
9798
{
9899
struct drm_master *master;
99100

@@ -107,6 +108,14 @@ static struct drm_master *drm_master_create(struct drm_device *dev)
107108
idr_init(&master->magic_map);
108109
master->dev = dev;
109110

111+
/* initialize the tree of output resource lessees */
112+
master->lessor = NULL;
113+
master->lessee_id = 0;
114+
INIT_LIST_HEAD(&master->lessees);
115+
INIT_LIST_HEAD(&master->lessee_list);
116+
idr_init(&master->leases);
117+
idr_init(&master->lessee_idr);
118+
110119
return master;
111120
}
112121

@@ -189,6 +198,12 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
189198
goto out_unlock;
190199
}
191200

201+
if (file_priv->master->lessor != NULL) {
202+
DRM_DEBUG_LEASE("Attempt to set lessee %d as master\n", file_priv->master->lessee_id);
203+
ret = -EINVAL;
204+
goto out_unlock;
205+
}
206+
192207
ret = drm_set_master(dev, file_priv, false);
193208
out_unlock:
194209
mutex_unlock(&dev->master_mutex);
@@ -270,6 +285,13 @@ void drm_master_release(struct drm_file *file_priv)
270285
if (dev->master == file_priv->master)
271286
drm_drop_master(dev, file_priv);
272287
out:
288+
if (drm_core_check_feature(dev, DRIVER_MODESET) && file_priv->is_master) {
289+
/* Revoke any leases held by this or lessees, but only if
290+
* this is the "real" master
291+
*/
292+
drm_lease_revoke(master);
293+
}
294+
273295
/* drop the master reference held by the file priv */
274296
if (file_priv->master)
275297
drm_master_put(&file_priv->master);
@@ -310,12 +332,18 @@ static void drm_master_destroy(struct kref *kref)
310332
struct drm_master *master = container_of(kref, struct drm_master, refcount);
311333
struct drm_device *dev = master->dev;
312334

335+
if (drm_core_check_feature(dev, DRIVER_MODESET))
336+
drm_lease_destroy(master);
337+
313338
if (dev->driver->master_destroy)
314339
dev->driver->master_destroy(dev, master);
315340

316341
drm_legacy_master_rmmaps(dev, master);
317342

318343
idr_destroy(&master->magic_map);
344+
idr_destroy(&master->leases);
345+
idr_destroy(&master->lessee_idr);
346+
319347
kfree(master->unique);
320348
kfree(master);
321349
}

0 commit comments

Comments
 (0)