Message ID | 20180103222110.45855-2-noralf@tronnes.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Jan 03, 2018 at 11:21:03PM +0100, Noralf Trønnes wrote: > From: David Herrmann <dh.herrmann@gmail.com> > > Rather than doing drm_file allocation/destruction right in the fops, lets > provide separate helpers. This decouples drm_file management from the > still-mandatory drm-fops. It prepares for use of drm_file without the > fops, both by possible separate fops implementations and APIs (not that I > am aware of any such plans), and more importantly from in-kernel use where > no real file is available. > > Signed-off-by: David Herrmann <dh.herrmann@gmail.com> > [rebased] > Signed-off-by: Noralf Trønnes <noralf@tronnes.org> > --- > drivers/gpu/drm/drm_file.c | 309 +++++++++++++++++++++++------------------ > drivers/gpu/drm/drm_internal.h | 2 + > 2 files changed, 179 insertions(+), 132 deletions(-) > > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c > index b3c6e997ccdb..d208faade27e 100644 > --- a/drivers/gpu/drm/drm_file.c > +++ b/drivers/gpu/drm/drm_file.c > @@ -101,6 +101,179 @@ DEFINE_MUTEX(drm_global_mutex); > > static int drm_open_helper(struct file *filp, struct drm_minor *minor); > > +/** > + * drm_file_alloc - allocate file context > + * @minor: minor to allocate on > + * > + * This allocates a new DRM file context. It is not linked into any context and > + * can be used by the caller freely. Note that the context keeps a pointer to > + * @minor, so it must be freed before @minor is. > + * > + * The legacy paths might require the drm_global_mutex to be held. I'd remove this line, since it's only relevant to close the driver load vs. file open race for drivers still using the deprecated ->load callback. This only confuses and doesn't help anyone writing a new/modern driver. > + * > + * RETURNS: > + * Pointer to newly allocated context, ERR_PTR on failure. > + */ > +struct drm_file *drm_file_alloc(struct drm_minor *minor) > +{ > + struct drm_device *dev = minor->dev; > + struct drm_file *file; > + int ret; > + > + file = kzalloc(sizeof(*file), GFP_KERNEL); > + if (!file) > + return ERR_PTR(-ENOMEM); > + > + file->pid = get_pid(task_pid(current)); > + file->minor = minor; > + > + /* for compatibility root is always authenticated */ > + file->authenticated = capable(CAP_SYS_ADMIN); > + file->lock_count = 0; > + > + INIT_LIST_HEAD(&file->lhead); > + INIT_LIST_HEAD(&file->fbs); > + mutex_init(&file->fbs_lock); > + INIT_LIST_HEAD(&file->blobs); > + INIT_LIST_HEAD(&file->pending_event_list); > + INIT_LIST_HEAD(&file->event_list); > + init_waitqueue_head(&file->event_wait); > + file->event_space = 4096; /* set aside 4k for event buffer */ > + > + mutex_init(&file->event_read_lock); > + > + if (drm_core_check_feature(dev, DRIVER_GEM)) > + drm_gem_open(dev, file); > + > + if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) > + drm_syncobj_open(file); > + > + if (drm_core_check_feature(dev, DRIVER_PRIME)) > + drm_prime_init_file_private(&file->prime); > + > + if (dev->driver->open) { > + ret = dev->driver->open(dev, file); > + if (ret < 0) > + goto out_prime_destroy; > + } > + > + if (drm_is_primary_client(file)) { > + ret = drm_master_open(file); > + if (ret) > + goto out_close; > + } > + > + return file; > + > +out_close: > + if (dev->driver->postclose) > + dev->driver->postclose(dev, file); > +out_prime_destroy: > + if (drm_core_check_feature(dev, DRIVER_PRIME)) > + drm_prime_destroy_file_private(&file->prime); > + if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) > + drm_syncobj_release(file); > + if (drm_core_check_feature(dev, DRIVER_GEM)) > + drm_gem_release(dev, file); > + put_pid(file->pid); > + kfree(file); > + > + return ERR_PTR(ret); > +} > + > +static void drm_events_release(struct drm_file *file_priv) > +{ > + struct drm_device *dev = file_priv->minor->dev; > + struct drm_pending_event *e, *et; > + unsigned long flags; > + > + spin_lock_irqsave(&dev->event_lock, flags); > + > + /* Unlink pending events */ > + list_for_each_entry_safe(e, et, &file_priv->pending_event_list, > + pending_link) { > + list_del(&e->pending_link); > + e->file_priv = NULL; > + } > + > + /* Remove unconsumed events */ > + list_for_each_entry_safe(e, et, &file_priv->event_list, link) { > + list_del(&e->link); > + kfree(e); > + } > + > + spin_unlock_irqrestore(&dev->event_lock, flags); > +} > + > +/** > + * drm_file_free - free file context > + * @file: context to free, or NULL > + * > + * This destroys and deallocates a DRM file context previously allocated via > + * drm_file_alloc(). The caller must make sure to unlink it from any contexts > + * before calling this. > + * > + * The legacy paths might require the drm_global_mutex to be held. Same here. With the bikesheds address and maybe the EXPORT_SYMBOL for these from patch 3 moved to here: Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> > + * > + * If NULL is passed, this is a no-op. > + * > + * RETURNS: > + * 0 on success, or error code on failure. > + */ > +void drm_file_free(struct drm_file *file) > +{ > + struct drm_device *dev; > + > + if (!file) > + return; > + > + dev = file->minor->dev; > + > + DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", > + task_pid_nr(current), > + (long)old_encode_dev(file->minor->kdev->devt), > + dev->open_count); > + > + if (drm_core_check_feature(dev, DRIVER_LEGACY) && > + dev->driver->preclose) > + dev->driver->preclose(dev, file); > + > + if (drm_core_check_feature(dev, DRIVER_LEGACY)) > + drm_legacy_lock_release(dev, file->filp); > + > + if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) > + drm_legacy_reclaim_buffers(dev, file); > + > + drm_events_release(file); > + > + if (drm_core_check_feature(dev, DRIVER_MODESET)) { > + drm_fb_release(file); > + drm_property_destroy_user_blobs(dev, file); > + } > + > + if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) > + drm_syncobj_release(file); > + > + if (drm_core_check_feature(dev, DRIVER_GEM)) > + drm_gem_release(dev, file); > + > + drm_legacy_ctxbitmap_flush(dev, file); > + > + if (drm_is_primary_client(file)) > + drm_master_release(file); > + > + if (dev->driver->postclose) > + dev->driver->postclose(dev, file); > + > + if (drm_core_check_feature(dev, DRIVER_PRIME)) > + drm_prime_destroy_file_private(&file->prime); > + > + WARN_ON(!list_empty(&file->event_list)); > + > + put_pid(file->pid); > + kfree(file); > +} > + > static int drm_setup(struct drm_device * dev) > { > int ret; > @@ -196,7 +369,6 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) > { > struct drm_device *dev = minor->dev; > struct drm_file *priv; > - int ret; > > if (filp->f_flags & O_EXCL) > return -EBUSY; /* No exclusive opens */ > @@ -207,50 +379,12 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) > > DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor->index); > > - priv = kzalloc(sizeof(*priv), GFP_KERNEL); > - if (!priv) > - return -ENOMEM; > + priv = drm_file_alloc(minor); > + if (IS_ERR(priv)) > + return PTR_ERR(priv); > > filp->private_data = priv; > priv->filp = filp; > - priv->pid = get_pid(task_pid(current)); > - priv->minor = minor; > - > - /* for compatibility root is always authenticated */ > - priv->authenticated = capable(CAP_SYS_ADMIN); > - priv->lock_count = 0; > - > - INIT_LIST_HEAD(&priv->lhead); > - INIT_LIST_HEAD(&priv->fbs); > - mutex_init(&priv->fbs_lock); > - INIT_LIST_HEAD(&priv->blobs); > - INIT_LIST_HEAD(&priv->pending_event_list); > - INIT_LIST_HEAD(&priv->event_list); > - init_waitqueue_head(&priv->event_wait); > - priv->event_space = 4096; /* set aside 4k for event buffer */ > - > - mutex_init(&priv->event_read_lock); > - > - if (drm_core_check_feature(dev, DRIVER_GEM)) > - drm_gem_open(dev, priv); > - > - if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) > - drm_syncobj_open(priv); > - > - if (drm_core_check_feature(dev, DRIVER_PRIME)) > - drm_prime_init_file_private(&priv->prime); > - > - if (dev->driver->open) { > - ret = dev->driver->open(dev, priv); > - if (ret < 0) > - goto out_prime_destroy; > - } > - > - if (drm_is_primary_client(priv)) { > - ret = drm_master_open(priv); > - if (ret) > - goto out_close; > - } > > mutex_lock(&dev->filelist_mutex); > list_add(&priv->lhead, &dev->filelist); > @@ -277,45 +411,6 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) > #endif > > return 0; > - > -out_close: > - if (dev->driver->postclose) > - dev->driver->postclose(dev, priv); > -out_prime_destroy: > - if (drm_core_check_feature(dev, DRIVER_PRIME)) > - drm_prime_destroy_file_private(&priv->prime); > - if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) > - drm_syncobj_release(priv); > - if (drm_core_check_feature(dev, DRIVER_GEM)) > - drm_gem_release(dev, priv); > - put_pid(priv->pid); > - kfree(priv); > - filp->private_data = NULL; > - return ret; > -} > - > -static void drm_events_release(struct drm_file *file_priv) > -{ > - struct drm_device *dev = file_priv->minor->dev; > - struct drm_pending_event *e, *et; > - unsigned long flags; > - > - spin_lock_irqsave(&dev->event_lock, flags); > - > - /* Unlink pending events */ > - list_for_each_entry_safe(e, et, &file_priv->pending_event_list, > - pending_link) { > - list_del(&e->pending_link); > - e->file_priv = NULL; > - } > - > - /* Remove unconsumed events */ > - list_for_each_entry_safe(e, et, &file_priv->event_list, link) { > - list_del(&e->link); > - kfree(e); > - } > - > - spin_unlock_irqrestore(&dev->event_lock, flags); > } > > static void drm_legacy_dev_reinit(struct drm_device *dev) > @@ -382,57 +477,7 @@ int drm_release(struct inode *inode, struct file *filp) > list_del(&file_priv->lhead); > mutex_unlock(&dev->filelist_mutex); > > - if (drm_core_check_feature(dev, DRIVER_LEGACY) && > - dev->driver->preclose) > - dev->driver->preclose(dev, file_priv); > - > - /* ======================================================== > - * Begin inline drm_release > - */ > - > - DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", > - task_pid_nr(current), > - (long)old_encode_dev(file_priv->minor->kdev->devt), > - dev->open_count); > - > - if (drm_core_check_feature(dev, DRIVER_LEGACY)) > - drm_legacy_lock_release(dev, filp); > - > - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) > - drm_legacy_reclaim_buffers(dev, file_priv); > - > - drm_events_release(file_priv); > - > - if (drm_core_check_feature(dev, DRIVER_MODESET)) { > - drm_fb_release(file_priv); > - drm_property_destroy_user_blobs(dev, file_priv); > - } > - > - if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) > - drm_syncobj_release(file_priv); > - > - if (drm_core_check_feature(dev, DRIVER_GEM)) > - drm_gem_release(dev, file_priv); > - > - drm_legacy_ctxbitmap_flush(dev, file_priv); > - > - if (drm_is_primary_client(file_priv)) > - drm_master_release(file_priv); > - > - if (dev->driver->postclose) > - dev->driver->postclose(dev, file_priv); > - > - if (drm_core_check_feature(dev, DRIVER_PRIME)) > - drm_prime_destroy_file_private(&file_priv->prime); > - > - WARN_ON(!list_empty(&file_priv->event_list)); > - > - put_pid(file_priv->pid); > - kfree(file_priv); > - > - /* ======================================================== > - * End inline drm_release > - */ > + drm_file_free(file_priv); > > if (!--dev->open_count) { > drm_lastclose(dev); > diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h > index b72242e93ea4..40179c5fc6b8 100644 > --- a/drivers/gpu/drm/drm_internal.h > +++ b/drivers/gpu/drm/drm_internal.h > @@ -26,6 +26,8 @@ > > /* drm_file.c */ > extern struct mutex drm_global_mutex; > +struct drm_file *drm_file_alloc(struct drm_minor *minor); > +void drm_file_free(struct drm_file *file); > void drm_lastclose(struct drm_device *dev); > > /* drm_pci.c */ > -- > 2.14.2 >
Hi On Tue, Jan 9, 2018 at 11:20 AM, Daniel Vetter <daniel@ffwll.ch> wrote: > On Wed, Jan 03, 2018 at 11:21:03PM +0100, Noralf Trønnes wrote: >> From: David Herrmann <dh.herrmann@gmail.com> >> >> Rather than doing drm_file allocation/destruction right in the fops, lets >> provide separate helpers. This decouples drm_file management from the >> still-mandatory drm-fops. It prepares for use of drm_file without the >> fops, both by possible separate fops implementations and APIs (not that I >> am aware of any such plans), and more importantly from in-kernel use where >> no real file is available. >> >> Signed-off-by: David Herrmann <dh.herrmann@gmail.com> >> [rebased] >> Signed-off-by: Noralf Trønnes <noralf@tronnes.org> >> --- For completeness: Still fine with me! Thanks for picking it up. Thanks David
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index b3c6e997ccdb..d208faade27e 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -101,6 +101,179 @@ DEFINE_MUTEX(drm_global_mutex); static int drm_open_helper(struct file *filp, struct drm_minor *minor); +/** + * drm_file_alloc - allocate file context + * @minor: minor to allocate on + * + * This allocates a new DRM file context. It is not linked into any context and + * can be used by the caller freely. Note that the context keeps a pointer to + * @minor, so it must be freed before @minor is. + * + * The legacy paths might require the drm_global_mutex to be held. + * + * RETURNS: + * Pointer to newly allocated context, ERR_PTR on failure. + */ +struct drm_file *drm_file_alloc(struct drm_minor *minor) +{ + struct drm_device *dev = minor->dev; + struct drm_file *file; + int ret; + + file = kzalloc(sizeof(*file), GFP_KERNEL); + if (!file) + return ERR_PTR(-ENOMEM); + + file->pid = get_pid(task_pid(current)); + file->minor = minor; + + /* for compatibility root is always authenticated */ + file->authenticated = capable(CAP_SYS_ADMIN); + file->lock_count = 0; + + INIT_LIST_HEAD(&file->lhead); + INIT_LIST_HEAD(&file->fbs); + mutex_init(&file->fbs_lock); + INIT_LIST_HEAD(&file->blobs); + INIT_LIST_HEAD(&file->pending_event_list); + INIT_LIST_HEAD(&file->event_list); + init_waitqueue_head(&file->event_wait); + file->event_space = 4096; /* set aside 4k for event buffer */ + + mutex_init(&file->event_read_lock); + + if (drm_core_check_feature(dev, DRIVER_GEM)) + drm_gem_open(dev, file); + + if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + drm_syncobj_open(file); + + if (drm_core_check_feature(dev, DRIVER_PRIME)) + drm_prime_init_file_private(&file->prime); + + if (dev->driver->open) { + ret = dev->driver->open(dev, file); + if (ret < 0) + goto out_prime_destroy; + } + + if (drm_is_primary_client(file)) { + ret = drm_master_open(file); + if (ret) + goto out_close; + } + + return file; + +out_close: + if (dev->driver->postclose) + dev->driver->postclose(dev, file); +out_prime_destroy: + if (drm_core_check_feature(dev, DRIVER_PRIME)) + drm_prime_destroy_file_private(&file->prime); + if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + drm_syncobj_release(file); + if (drm_core_check_feature(dev, DRIVER_GEM)) + drm_gem_release(dev, file); + put_pid(file->pid); + kfree(file); + + return ERR_PTR(ret); +} + +static void drm_events_release(struct drm_file *file_priv) +{ + struct drm_device *dev = file_priv->minor->dev; + struct drm_pending_event *e, *et; + unsigned long flags; + + spin_lock_irqsave(&dev->event_lock, flags); + + /* Unlink pending events */ + list_for_each_entry_safe(e, et, &file_priv->pending_event_list, + pending_link) { + list_del(&e->pending_link); + e->file_priv = NULL; + } + + /* Remove unconsumed events */ + list_for_each_entry_safe(e, et, &file_priv->event_list, link) { + list_del(&e->link); + kfree(e); + } + + spin_unlock_irqrestore(&dev->event_lock, flags); +} + +/** + * drm_file_free - free file context + * @file: context to free, or NULL + * + * This destroys and deallocates a DRM file context previously allocated via + * drm_file_alloc(). The caller must make sure to unlink it from any contexts + * before calling this. + * + * The legacy paths might require the drm_global_mutex to be held. + * + * If NULL is passed, this is a no-op. + * + * RETURNS: + * 0 on success, or error code on failure. + */ +void drm_file_free(struct drm_file *file) +{ + struct drm_device *dev; + + if (!file) + return; + + dev = file->minor->dev; + + DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", + task_pid_nr(current), + (long)old_encode_dev(file->minor->kdev->devt), + dev->open_count); + + if (drm_core_check_feature(dev, DRIVER_LEGACY) && + dev->driver->preclose) + dev->driver->preclose(dev, file); + + if (drm_core_check_feature(dev, DRIVER_LEGACY)) + drm_legacy_lock_release(dev, file->filp); + + if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) + drm_legacy_reclaim_buffers(dev, file); + + drm_events_release(file); + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + drm_fb_release(file); + drm_property_destroy_user_blobs(dev, file); + } + + if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + drm_syncobj_release(file); + + if (drm_core_check_feature(dev, DRIVER_GEM)) + drm_gem_release(dev, file); + + drm_legacy_ctxbitmap_flush(dev, file); + + if (drm_is_primary_client(file)) + drm_master_release(file); + + if (dev->driver->postclose) + dev->driver->postclose(dev, file); + + if (drm_core_check_feature(dev, DRIVER_PRIME)) + drm_prime_destroy_file_private(&file->prime); + + WARN_ON(!list_empty(&file->event_list)); + + put_pid(file->pid); + kfree(file); +} + static int drm_setup(struct drm_device * dev) { int ret; @@ -196,7 +369,6 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) { struct drm_device *dev = minor->dev; struct drm_file *priv; - int ret; if (filp->f_flags & O_EXCL) return -EBUSY; /* No exclusive opens */ @@ -207,50 +379,12 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor->index); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + priv = drm_file_alloc(minor); + if (IS_ERR(priv)) + return PTR_ERR(priv); filp->private_data = priv; priv->filp = filp; - priv->pid = get_pid(task_pid(current)); - priv->minor = minor; - - /* for compatibility root is always authenticated */ - priv->authenticated = capable(CAP_SYS_ADMIN); - priv->lock_count = 0; - - INIT_LIST_HEAD(&priv->lhead); - INIT_LIST_HEAD(&priv->fbs); - mutex_init(&priv->fbs_lock); - INIT_LIST_HEAD(&priv->blobs); - INIT_LIST_HEAD(&priv->pending_event_list); - INIT_LIST_HEAD(&priv->event_list); - init_waitqueue_head(&priv->event_wait); - priv->event_space = 4096; /* set aside 4k for event buffer */ - - mutex_init(&priv->event_read_lock); - - if (drm_core_check_feature(dev, DRIVER_GEM)) - drm_gem_open(dev, priv); - - if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) - drm_syncobj_open(priv); - - if (drm_core_check_feature(dev, DRIVER_PRIME)) - drm_prime_init_file_private(&priv->prime); - - if (dev->driver->open) { - ret = dev->driver->open(dev, priv); - if (ret < 0) - goto out_prime_destroy; - } - - if (drm_is_primary_client(priv)) { - ret = drm_master_open(priv); - if (ret) - goto out_close; - } mutex_lock(&dev->filelist_mutex); list_add(&priv->lhead, &dev->filelist); @@ -277,45 +411,6 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) #endif return 0; - -out_close: - if (dev->driver->postclose) - dev->driver->postclose(dev, priv); -out_prime_destroy: - if (drm_core_check_feature(dev, DRIVER_PRIME)) - drm_prime_destroy_file_private(&priv->prime); - if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) - drm_syncobj_release(priv); - if (drm_core_check_feature(dev, DRIVER_GEM)) - drm_gem_release(dev, priv); - put_pid(priv->pid); - kfree(priv); - filp->private_data = NULL; - return ret; -} - -static void drm_events_release(struct drm_file *file_priv) -{ - struct drm_device *dev = file_priv->minor->dev; - struct drm_pending_event *e, *et; - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); - - /* Unlink pending events */ - list_for_each_entry_safe(e, et, &file_priv->pending_event_list, - pending_link) { - list_del(&e->pending_link); - e->file_priv = NULL; - } - - /* Remove unconsumed events */ - list_for_each_entry_safe(e, et, &file_priv->event_list, link) { - list_del(&e->link); - kfree(e); - } - - spin_unlock_irqrestore(&dev->event_lock, flags); } static void drm_legacy_dev_reinit(struct drm_device *dev) @@ -382,57 +477,7 @@ int drm_release(struct inode *inode, struct file *filp) list_del(&file_priv->lhead); mutex_unlock(&dev->filelist_mutex); - if (drm_core_check_feature(dev, DRIVER_LEGACY) && - dev->driver->preclose) - dev->driver->preclose(dev, file_priv); - - /* ======================================================== - * Begin inline drm_release - */ - - DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", - task_pid_nr(current), - (long)old_encode_dev(file_priv->minor->kdev->devt), - dev->open_count); - - if (drm_core_check_feature(dev, DRIVER_LEGACY)) - drm_legacy_lock_release(dev, filp); - - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - drm_legacy_reclaim_buffers(dev, file_priv); - - drm_events_release(file_priv); - - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - drm_fb_release(file_priv); - drm_property_destroy_user_blobs(dev, file_priv); - } - - if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) - drm_syncobj_release(file_priv); - - if (drm_core_check_feature(dev, DRIVER_GEM)) - drm_gem_release(dev, file_priv); - - drm_legacy_ctxbitmap_flush(dev, file_priv); - - if (drm_is_primary_client(file_priv)) - drm_master_release(file_priv); - - if (dev->driver->postclose) - dev->driver->postclose(dev, file_priv); - - if (drm_core_check_feature(dev, DRIVER_PRIME)) - drm_prime_destroy_file_private(&file_priv->prime); - - WARN_ON(!list_empty(&file_priv->event_list)); - - put_pid(file_priv->pid); - kfree(file_priv); - - /* ======================================================== - * End inline drm_release - */ + drm_file_free(file_priv); if (!--dev->open_count) { drm_lastclose(dev); diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index b72242e93ea4..40179c5fc6b8 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -26,6 +26,8 @@ /* drm_file.c */ extern struct mutex drm_global_mutex; +struct drm_file *drm_file_alloc(struct drm_minor *minor); +void drm_file_free(struct drm_file *file); void drm_lastclose(struct drm_device *dev); /* drm_pci.c */