[PATCH 11/12] drm: make minor->index available early
David Herrmann
dh.herrmann at gmail.com
Thu Jul 24 03:16:59 PDT 2014
Hi
On Thu, Jul 24, 2014 at 12:03 PM, Daniel Vetter <daniel at ffwll.ch> wrote:
> On Wed, Jul 23, 2014 at 05:26:46PM +0200, David Herrmann wrote:
>> Instead of allocating the minor-index during registration, we now do this
>> during allocation. This way, debug-messages between minor-allocation and
>> minor-registration will now use the correct minor instead of 0. Same is
>> done for unregistration vs. free, so debug-messages between
>> device-shutdown and device-destruction show proper indices.
>>
>> Even though minor-indices are allocated early, we don't enable minor
>> lookup early. Instead, we keep the entry set to NULL and replace it during
>> registration / unregistration. This way, the index is allocated but lookup
>> only works if registered.
>>
>> Signed-off-by: David Herrmann <dh.herrmann at gmail.com>
>> ---
>> drivers/gpu/drm/drm_stub.c | 84 +++++++++++++++++++++++++---------------------
>> 1 file changed, 46 insertions(+), 38 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
>> index b249f14..8b24db5 100644
>> --- a/drivers/gpu/drm/drm_stub.c
>> +++ b/drivers/gpu/drm/drm_stub.c
>> @@ -256,6 +256,8 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
>> static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
>> {
>> struct drm_minor *minor;
>> + unsigned long flags;
>> + int r;
>>
>> minor = kzalloc(sizeof(*minor), GFP_KERNEL);
>> if (!minor)
>> @@ -264,57 +266,68 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
>> minor->type = type;
>> minor->dev = dev;
>>
>> + idr_preload(GFP_KERNEL);
>> + spin_lock_irqsave(&drm_minor_lock, flags);
>> + r = idr_alloc(&drm_minors_idr,
>> + NULL,
>> + 64 * type,
>> + 64 * (type + 1),
>> + GFP_NOWAIT);
>> + spin_unlock_irqrestore(&drm_minor_lock, flags);
>> + idr_preload_end();
>> +
>> + if (r < 0)
>> + goto err_free;
>> +
>> + minor->index = r;
>> +
>> *drm_minor_get_slot(dev, type) = minor;
>> return 0;
>> +
>> +err_free:
>> + kfree(minor);
>> + return r;
>> }
>>
>> static void drm_minor_free(struct drm_device *dev, unsigned int type)
>> {
>> - struct drm_minor **slot;
>> + struct drm_minor **slot, *minor;
>> + unsigned long flags;
>>
>> slot = drm_minor_get_slot(dev, type);
>> - if (*slot) {
>> - drm_mode_group_destroy(&(*slot)->mode_group);
>> - kfree(*slot);
>> - *slot = NULL;
>> - }
>> + minor = *slot;
>> + if (!minor)
>> + return;
>> +
>> + drm_mode_group_destroy(&minor->mode_group);
>> +
>> + spin_lock_irqsave(&drm_minor_lock, flags);
>> + idr_remove(&drm_minors_idr, minor->index);
>> + spin_unlock_irqrestore(&drm_minor_lock, flags);
>
> I don't understand why you do the idr removal in stages too. Otherwise
> this looks good.
If you call drm_minor_unregister(), we now disable lookup but keep
minor->index. If I also released the ID, a new drm_minor might get
access to it before we call drm_minor_free on the old one. This might
cause misleading debug-messages as both minor objects have the same
index. This is not really a problem, but kinda ugly.
> Aside: If two drivers load concurrently (i.e. in the brave new world
> withou drm_global_mutex) we might end up with interleaved minor ids. Dunno
> whether we'll care since userspace should use udev/sysfs lookups anyway.
> igt sometimes doesn't ;-)
I did post a patch some time ago that makes minor-ID allocations
predictable. I got a NACK from you, so this one is one you ;) But I
agree, we really should fix user-space instead of making random IDs
predictable.
Thanks
David
More information about the dri-devel
mailing list