msm: kgsl: Cleanup the fence if it cannot be added
If a callback cannot be registered for a fence, remove it from
the sync timeline. This avoids a memory leak if the fence is
not signaled.
Change-Id: I8ce8ba3ad6fd2fec90e2eb862f51fbac0167815d
Signed-off-by: Lynus Vaz <lvaz@codeaurora.org>
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
index 7701395..9c078b6 100644
--- a/drivers/gpu/msm/kgsl_sync.c
+++ b/drivers/gpu/msm/kgsl_sync.c
@@ -152,6 +152,17 @@
return ret;
}
+/* Only to be used if creating a related event failed */
+static void kgsl_sync_cancel(struct kgsl_sync_fence *kfence)
+{
+ spin_lock(&kfence->parent->lock);
+ if (!list_empty(&kfence->child_list)) {
+ list_del_init(&kfence->child_list);
+ fence_put(&kfence->fence);
+ }
+ spin_unlock(&kfence->parent->lock);
+}
+
/**
* kgsl_add_fence_event - Create a new fence event
* @device - KGSL device to create the event on
@@ -235,6 +246,7 @@
put_unused_fd(priv.fence_fd);
if (kfence) {
+ kgsl_sync_cancel(kfence);
/*
* Put the refcount of sync file. This will release
* kfence->fence as well.
@@ -366,7 +378,7 @@
list_for_each_entry_safe(kfence, next, &ktimeline->child_list_head,
child_list) {
if (fence_is_signaled_locked(&kfence->fence)) {
- list_del(&kfence->child_list);
+ list_del_init(&kfence->child_list);
fence_put(&kfence->fence);
}
}