[COMMON] g2d: increase starter before adding callback
authorhyesoo.yu <hyesoo.yu@samsung.com>
Tue, 20 Jun 2017 05:45:30 +0000 (14:45 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:22:13 +0000 (20:22 +0300)
Always increase task->starter before adding callback
to avoid unexpected operation.

CPU1 CPU2

kref_init(&task->starter);
g2d_get_userdata();
fence_add_callback(fence);
g2d_fence_callback(fence);
kref_put(&task->starter);
g2d_queuework_task();
g2d_device_run();
kref_get(&task->starter);

On the above condition, that forces to run H/W without
getting user data. It makes various types of errors.

Change-Id: Id775237894e7aedcb0c4feb180ab44646557ef5e
Signed-off-by: hyesoo.yu <hyesoo.yu@samsung.com>
drivers/gpu/exynos/g2d/g2d_fence.c
drivers/gpu/exynos/g2d/g2d_uapi_process.c

index 44c29f6e5e9261bbd433802dfdd31a84ad5fb4be..cba020fda6a0559aafada8e13f9441343ddca790 100644 (file)
@@ -219,8 +219,11 @@ struct dma_fence *g2d_get_acquire_fence(struct g2d_device *g2d_dev,
        if (!fence)
                return ERR_PTR(-EINVAL);
 
+       kref_get(&layer->task->starter);
+
        ret = dma_fence_add_callback(fence, &layer->fence_cb, g2d_fence_callback);
        if (ret < 0) {
+               kref_put(&layer->task->starter, g2d_queuework_task);
                dma_fence_put(fence);
                return (ret == -ENOENT) ? NULL : ERR_PTR(ret);
        }
index 26e1e29ea5c21e279ecb3bea38b739b6dbaf12c1..43104077f990f79bf9459504b0663f1d283d8068 100644 (file)
@@ -561,9 +561,6 @@ static int g2d_get_source(struct g2d_device *g2d_dev, struct g2d_task *task,
                return ret;
        }
 
-       if (layer->fence)
-               kref_get(&task->starter);
-
        ret = g2d_get_buffer(g2d_dev, layer, data, DMA_TO_DEVICE);
        if (ret)
                goto err_buffer;
@@ -660,9 +657,6 @@ static int g2d_get_target(struct g2d_device *g2d_dev,
                return ret;
        }
 
-       if (target->fence)
-               kref_get(&task->starter);
-
        ret = g2d_get_buffer(g2d_dev, target, data, DMA_FROM_DEVICE);
        if (ret)
                goto err_buffer;