dma-buf/sync_file: Increment refcount of fence when all are signaled.
authorRafael Antognolli <rafael.antognolli@intel.com>
Thu, 15 Sep 2016 19:14:25 +0000 (12:14 -0700)
committerSumit Semwal <sumit.semwal@linaro.org>
Tue, 20 Sep 2016 12:23:39 +0000 (17:53 +0530)
When we merge several fences, if all of them are signaled already, we
still keep one of them. So instead of using add_fence(), which will not
increase the refcount of signaled fences, we should explicitly call
fence_get() for the fence we are keeping.

This patch fixes a kernel panic that can be triggered by creating a fence
that is expired (or increasing the timeline until it expires), then
creating a merged fence out of it, and deleting the merged fence. This
will make the original expired fence's refcount go to zero.

Testcase: igt/sw_sync/sync_expired_merge
Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
Link: http://patchwork.freedesktop.org/patch/msgid/1473966865-4508-1-git-send-email-rafael.antognolli@intel.com
drivers/dma-buf/sync_file.c

index abb5fda..0fe7ec2 100644 (file)
@@ -253,10 +253,8 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
        for (; i_b < b_num_fences; i_b++)
                add_fence(fences, &i, b_fences[i_b]);
 
-       if (i == 0) {
-               add_fence(fences, &i, a_fences[0]);
-               i++;
-       }
+       if (i == 0)
+               fences[i++] = fence_get(a_fences[0]);
 
        if (num_fences > i) {
                nfences = krealloc(fences, i * sizeof(*fences),