--- a/sys/dev/drm/drm_file.c +++ b/sys/dev/drm/drm_file.c @@ -370,6 +370,7 @@ struct inode *inode = filp->f_data; /* A Linux inode is a Unix vnode */ #endif struct drm_file *file_priv = filp->private_data; + struct drm_minor *open_minor = file_priv->minor; struct drm_minor *minor = drm_minor_acquire(iminor(inode)); struct drm_device *dev = minor->dev; @@ -444,6 +445,14 @@ drm_minor_release(minor); + /* + * drm_open() acquired a reference at drm_file.c:325 that it + * intentionally keeps on success (the file owns it; Linux drops + * it in drm_release()). drm_close() so far dropped only its own + * acquire above, leaking one drm_device kref per open/close. + */ + drm_minor_release(open_minor); + return 0; } EXPORT_SYMBOL(drm_close);