drm: Return error codes from struct drm_driver.gem_create_object
authorThomas Zimmermann <tzimmermann@suse.de>
Tue, 30 Nov 2021 09:52:55 +0000 (10:52 +0100)
committerThomas Zimmermann <tzimmermann@suse.de>
Thu, 2 Dec 2021 10:12:39 +0000 (11:12 +0100)
GEM helper libraries use struct drm_driver.gem_create_object to let
drivers override GEM object allocation. On failure, the call returns
NULL.

Change the semantics to make the calls return a pointer-encoded error.
This aligns the callback with its callers. Fixes the ingenic driver,
which already returns an error pointer.

Also update the callers to handle the involved types more strictly.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Steven Price <steven.price@arm.com>
Acked-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20211130095255.26710-1-tzimmermann@suse.de
drivers/gpu/drm/drm_gem_cma_helper.c
drivers/gpu/drm/drm_gem_shmem_helper.c
drivers/gpu/drm/drm_gem_vram_helper.c
drivers/gpu/drm/lima/lima_gem.c
drivers/gpu/drm/panfrost/panfrost_gem.c
drivers/gpu/drm/v3d/v3d_bo.c
drivers/gpu/drm/vgem/vgem_drv.c
drivers/gpu/drm/virtio/virtgpu_object.c
include/drm/drm_drv.h

index 5f42e44..6f18f14 100644 (file)
@@ -67,18 +67,21 @@ __drm_gem_cma_create(struct drm_device *drm, size_t size, bool private)
        struct drm_gem_object *gem_obj;
        int ret = 0;
 
-       if (drm->driver->gem_create_object)
+       if (drm->driver->gem_create_object) {
                gem_obj = drm->driver->gem_create_object(drm, size);
-       else
-               gem_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL);
-       if (!gem_obj)
-               return ERR_PTR(-ENOMEM);
+               if (IS_ERR(gem_obj))
+                       return ERR_CAST(gem_obj);
+               cma_obj = to_drm_gem_cma_obj(gem_obj);
+       } else {
+               cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL);
+               if (!cma_obj)
+                       return ERR_PTR(-ENOMEM);
+               gem_obj = &cma_obj->base;
+       }
 
        if (!gem_obj->funcs)
                gem_obj->funcs = &drm_gem_cma_default_funcs;
 
-       cma_obj = container_of(gem_obj, struct drm_gem_cma_object, base);
-
        if (private) {
                drm_gem_private_object_init(drm, gem_obj, size);
 
index 0eeda10..7915047 100644 (file)
@@ -56,14 +56,17 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private)
 
        size = PAGE_ALIGN(size);
 
-       if (dev->driver->gem_create_object)
+       if (dev->driver->gem_create_object) {
                obj = dev->driver->gem_create_object(dev, size);
-       else
-               obj = kzalloc(sizeof(*shmem), GFP_KERNEL);
-       if (!obj)
-               return ERR_PTR(-ENOMEM);
-
-       shmem = to_drm_gem_shmem_obj(obj);
+               if (IS_ERR(obj))
+                       return ERR_CAST(obj);
+               shmem = to_drm_gem_shmem_obj(obj);
+       } else {
+               shmem = kzalloc(sizeof(*shmem), GFP_KERNEL);
+               if (!shmem)
+                       return ERR_PTR(-ENOMEM);
+               obj = &shmem->base;
+       }
 
        if (!obj->funcs)
                obj->funcs = &drm_gem_shmem_funcs;
index bfa386b..3f00192 100644 (file)
@@ -197,8 +197,8 @@ struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev,
 
        if (dev->driver->gem_create_object) {
                gem = dev->driver->gem_create_object(dev, size);
-               if (!gem)
-                       return ERR_PTR(-ENOMEM);
+               if (IS_ERR(gem))
+                       return ERR_CAST(gem);
                gbo = drm_gem_vram_of_gem(gem);
        } else {
                gbo = kzalloc(sizeof(*gbo), GFP_KERNEL);
index 2723d33..f9a9198 100644 (file)
@@ -221,7 +221,7 @@ struct drm_gem_object *lima_gem_create_object(struct drm_device *dev, size_t siz
 
        bo = kzalloc(sizeof(*bo), GFP_KERNEL);
        if (!bo)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        mutex_init(&bo->lock);
        INIT_LIST_HEAD(&bo->va);
index 6d9bdb9..ead65f5 100644 (file)
@@ -223,7 +223,7 @@ struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t
 
        obj = kzalloc(sizeof(*obj), GFP_KERNEL);
        if (!obj)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        INIT_LIST_HEAD(&obj->mappings.list);
        mutex_init(&obj->mappings.lock);
index 0d9af62..6e3113f 100644 (file)
@@ -70,11 +70,11 @@ struct drm_gem_object *v3d_create_object(struct drm_device *dev, size_t size)
        struct drm_gem_object *obj;
 
        if (size == 0)
-               return NULL;
+               return ERR_PTR(-EINVAL);
 
        bo = kzalloc(sizeof(*bo), GFP_KERNEL);
        if (!bo)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
        obj = &bo->base.base;
 
        obj->funcs = &v3d_gem_funcs;
index a87eafa..c5e3e54 100644 (file)
@@ -97,7 +97,7 @@ static struct drm_gem_object *vgem_gem_create_object(struct drm_device *dev, siz
 
        obj = kzalloc(sizeof(*obj), GFP_KERNEL);
        if (!obj)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        /*
         * vgem doesn't have any begin/end cpu access ioctls, therefore must use
index 187e10d..baef2c5 100644 (file)
@@ -139,7 +139,7 @@ struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev,
 
        shmem = kzalloc(sizeof(*shmem), GFP_KERNEL);
        if (!shmem)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        dshmem = &shmem->base.base;
        dshmem->base.funcs = &virtio_gpu_shmem_funcs;
index da0c836..f6159ac 100644 (file)
@@ -291,8 +291,9 @@ struct drm_driver {
        /**
         * @gem_create_object: constructor for gem objects
         *
-        * Hook for allocating the GEM object struct, for use by the CMA and
-        * SHMEM GEM helpers.
+        * Hook for allocating the GEM object struct, for use by the CMA
+        * and SHMEM GEM helpers. Returns a GEM object on success, or an
+        * ERR_PTR()-encoded error code otherwise.
         */
        struct drm_gem_object *(*gem_create_object)(struct drm_device *dev,
                                                    size_t size);