Revert "drm/framebuffer: Acquire internal references on GEM handles"

This reverts commit 2e2e9b3d70 which is
commit f6bfc9afc7510cb5e6fbe0a17c507917b0120280 upstream.

It breaks the Android kernel abi and can be brought back in the future
in an abi-safe way if it is really needed.

Bug: 161946584
Change-Id: Icdf2b06df07b5c5b7990dc0104137d206dba4855
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2025-07-18 12:01:12 +00:00
parent 9cca897f09
commit 5423646b52
5 changed files with 26 additions and 68 deletions

View File

@@ -844,23 +844,11 @@ void drm_framebuffer_free(struct kref *kref)
int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
const struct drm_framebuffer_funcs *funcs)
{
unsigned int i;
int ret;
bool exists;
if (WARN_ON_ONCE(fb->dev != dev || !fb->format))
return -EINVAL;
for (i = 0; i < fb->format->num_planes; i++) {
if (drm_WARN_ON_ONCE(dev, fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)))
fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
if (fb->obj[i]) {
exists = drm_gem_object_handle_get_if_exists_unlocked(fb->obj[i]);
if (exists)
fb->internal_flags |= DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
}
}
INIT_LIST_HEAD(&fb->filp_head);
fb->funcs = funcs;
@@ -869,7 +857,7 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
ret = __drm_mode_object_add(dev, &fb->base, DRM_MODE_OBJECT_FB,
false, drm_framebuffer_free);
if (ret)
goto err;
goto out;
mutex_lock(&dev->mode_config.fb_lock);
dev->mode_config.num_fb++;
@@ -877,16 +865,7 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
mutex_unlock(&dev->mode_config.fb_lock);
drm_mode_object_register(dev, &fb->base);
return 0;
err:
for (i = 0; i < fb->format->num_planes; i++) {
if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)) {
drm_gem_object_handle_put_unlocked(fb->obj[i]);
fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
}
}
out:
return ret;
}
EXPORT_SYMBOL(drm_framebuffer_init);
@@ -963,12 +942,6 @@ EXPORT_SYMBOL(drm_framebuffer_unregister_private);
void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
{
struct drm_device *dev = fb->dev;
unsigned int i;
for (i = 0; i < fb->format->num_planes; i++) {
if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i))
drm_gem_object_handle_put_unlocked(fb->obj[i]);
}
mutex_lock(&dev->mode_config.fb_lock);
list_del(&fb->head);

View File

@@ -197,34 +197,23 @@ static void drm_gem_object_handle_get(struct drm_gem_object *obj)
}
/**
* drm_gem_object_handle_get_if_exists_unlocked - acquire reference on user-space handle, if any
* drm_gem_object_handle_get_unlocked - acquire reference on user-space handles
* @obj: GEM object
*
* Acquires a reference on the GEM buffer object's handle. Required to keep
* the GEM object alive. Call drm_gem_object_handle_put_if_exists_unlocked()
* to release the reference. Does nothing if the buffer object has no handle.
*
* Returns:
* True if a handle exists, or false otherwise
* Acquires a reference on the GEM buffer object's handle. Required
* to keep the GEM object alive. Call drm_gem_object_handle_put_unlocked()
* to release the reference.
*/
bool drm_gem_object_handle_get_if_exists_unlocked(struct drm_gem_object *obj)
void drm_gem_object_handle_get_unlocked(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
guard(mutex)(&dev->object_name_lock);
/*
* First ref taken during GEM object creation, if any. Some
* drivers set up internal framebuffers with GEM objects that
* do not have a GEM handle. Hence, this counter can be zero.
*/
if (!obj->handle_count)
return false;
drm_WARN_ON(dev, !obj->handle_count); /* first ref taken in create-tail helper */
drm_gem_object_handle_get(obj);
return true;
}
EXPORT_SYMBOL(drm_gem_object_handle_get_unlocked);
/**
* drm_gem_object_handle_free - release resources bound to userspace handles
@@ -257,7 +246,7 @@ static void drm_gem_object_exported_dma_buf_free(struct drm_gem_object *obj)
}
/**
* drm_gem_object_handle_put_unlocked - releases reference on user-space handle
* drm_gem_object_handle_put_unlocked - releases reference on user-space handles
* @obj: GEM object
*
* Releases a reference on the GEM buffer object's handle. Possibly releases
@@ -268,14 +257,14 @@ void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
struct drm_device *dev = obj->dev;
bool final = false;
if (drm_WARN_ON(dev, READ_ONCE(obj->handle_count) == 0))
if (WARN_ON(READ_ONCE(obj->handle_count) == 0))
return;
/*
* Must bump handle count first as this may be the last
* ref, in which case the object would disappear before
* we checked for a name.
*/
* Must bump handle count first as this may be the last
* ref, in which case the object would disappear before we
* checked for a name
*/
mutex_lock(&dev->object_name_lock);
if (--obj->handle_count == 0) {
@@ -288,6 +277,7 @@ void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
if (final)
drm_gem_object_put(obj);
}
EXPORT_SYMBOL(drm_gem_object_handle_put_unlocked);
/*
* Called at device or object close to release the file's

View File

@@ -99,7 +99,7 @@ void drm_gem_fb_destroy(struct drm_framebuffer *fb)
unsigned int i;
for (i = 0; i < fb->format->num_planes; i++)
drm_gem_object_put(fb->obj[i]);
drm_gem_object_handle_put_unlocked(fb->obj[i]);
drm_framebuffer_cleanup(fb);
kfree(fb);
@@ -182,8 +182,10 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
if (!objs[i]) {
drm_dbg_kms(dev, "Failed to lookup GEM object\n");
ret = -ENOENT;
goto err_gem_object_put;
goto err_gem_object_handle_put_unlocked;
}
drm_gem_object_handle_get_unlocked(objs[i]);
drm_gem_object_put(objs[i]);
min_size = (height - 1) * mode_cmd->pitches[i]
+ drm_format_info_min_pitch(info, i, width)
@@ -193,22 +195,22 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
drm_dbg_kms(dev,
"GEM object size (%zu) smaller than minimum size (%u) for plane %d\n",
objs[i]->size, min_size, i);
drm_gem_object_put(objs[i]);
drm_gem_object_handle_put_unlocked(objs[i]);
ret = -EINVAL;
goto err_gem_object_put;
goto err_gem_object_handle_put_unlocked;
}
}
ret = drm_gem_fb_init(dev, fb, mode_cmd, objs, i, funcs);
if (ret)
goto err_gem_object_put;
goto err_gem_object_handle_put_unlocked;
return 0;
err_gem_object_put:
err_gem_object_handle_put_unlocked:
while (i > 0) {
--i;
drm_gem_object_put(objs[i]);
drm_gem_object_handle_put_unlocked(objs[i]);
}
return ret;
}

View File

@@ -155,7 +155,7 @@ void drm_sysfs_lease_event(struct drm_device *dev);
/* drm_gem.c */
int drm_gem_init(struct drm_device *dev);
bool drm_gem_object_handle_get_if_exists_unlocked(struct drm_gem_object *obj);
void drm_gem_object_handle_get_unlocked(struct drm_gem_object *obj);
void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj);
int drm_gem_handle_create_tail(struct drm_file *file_priv,
struct drm_gem_object *obj,

View File

@@ -23,7 +23,6 @@
#ifndef __DRM_FRAMEBUFFER_H__
#define __DRM_FRAMEBUFFER_H__
#include <linux/bits.h>
#include <linux/ctype.h>
#include <linux/list.h>
#include <linux/sched.h>
@@ -101,8 +100,6 @@ struct drm_framebuffer_funcs {
unsigned num_clips);
};
#define DRM_FRAMEBUFFER_HAS_HANDLE_REF(_i) BIT(0u + (_i))
/**
* struct drm_framebuffer - frame buffer object
*
@@ -191,10 +188,6 @@ struct drm_framebuffer {
* DRM_MODE_FB_MODIFIERS.
*/
int flags;
/**
* @internal_flags: Framebuffer flags like DRM_FRAMEBUFFER_HAS_HANDLE_REF.
*/
unsigned int internal_flags;
/**
* @hot_x: X coordinate of the cursor hotspot. Used by the legacy cursor
* IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR