From patchwork Thu Jun 23 15:29:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Padovan X-Patchwork-Id: 9195483 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id F3EEA6075A for ; Thu, 23 Jun 2016 15:31:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E331F28464 for ; Thu, 23 Jun 2016 15:31:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D7AE728466; Thu, 23 Jun 2016 15:31:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5674128464 for ; Thu, 23 Jun 2016 15:31:08 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AA3BD6E3BC; Thu, 23 Jun 2016 15:31:05 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yw0-f193.google.com (mail-yw0-f193.google.com [209.85.161.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id AD8196E97C for ; Thu, 23 Jun 2016 15:30:29 +0000 (UTC) Received: by mail-yw0-f193.google.com with SMTP id v77so11394180ywg.2 for ; Thu, 23 Jun 2016 08:30:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=s4EGgS/X2t/RzDSbBMuACd6PdDKVwOwPZ6Nd18CkRwg=; b=EfP78a4hO1Y0/7p1opH5sXV4Q4glxWxJKkZAwbP1o/XYMphGYwglImA6WyS2oh8jvq ILcwGQaPgu1rl6A2zfYW+cMyMG2lFHhi2S8ujS+7nYhJ/zkw9Puc2xpf4VZI2kYRSsMq enEU+KrB4nu6L65EiTsoJ82Vh8UO0cs1Uy1zhiqlwt/luJNd3AYkWUnzPwYFV3thrYJd 4wDpe2FSxNlkoQUmrjA41qe/BuzBkD6j+XOhNIpj6xtZi/ga8xZHB4bwcOq/owuIYIOQ 1S3ctqRrZ439d2f2QyJaFXMgtw1HzI9k9Ffognp+Y7NdRFa3Tt4kBoR3UIqqC7jBhA2r +5Zg== X-Gm-Message-State: ALyK8tJToLA9zKrS9yKD7ZN6c9nMOhPz6G67fOeC/C36mlo9VzKAITldFHZhOpdyeq6Z6w== X-Received: by 10.13.229.69 with SMTP id o66mr20374401ywe.69.1466695828382; Thu, 23 Jun 2016 08:30:28 -0700 (PDT) Received: from jade.localdomain ([189.61.225.79]) by smtp.gmail.com with ESMTPSA id l81sm346278ywb.34.2016.06.23.08.30.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 23 Jun 2016 08:30:27 -0700 (PDT) From: Gustavo Padovan To: dri-devel@lists.freedesktop.org Subject: [RFC 5/5] dma-buf/sync_file: rework fence storage in struct file Date: Thu, 23 Jun 2016 12:29:50 -0300 Message-Id: <1466695790-2833-6-git-send-email-gustavo@padovan.org> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1466695790-2833-1-git-send-email-gustavo@padovan.org> References: <1466695790-2833-1-git-send-email-gustavo@padovan.org> Cc: marcheu@google.com, Daniel Stone , seanpaul@google.com, Daniel Vetter , linux-kernel@vger.kernel.org, laurent.pinchart@ideasonboard.com, Gustavo Padovan , John Harrison , m.chehab@samsung.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Gustavo Padovan Create sync_file->fence to abstract the type of fence we are using for each sync_file. If only one fence is present we use a normal struct fence but if there is more fences to be added to the sync_file a fence_array is created. This behaviour is transparent all sync_file functions, but sync_file_set_fence() which sets the fence in the sync_file_merge(). It is this functions that decides to use a fence or fence_array based on num_fences. This change cleans up sync_file a bit. We don't need to have sync_file_cb array anymore. Instead, as we always have one fence, only one fence callback is registered per sync_file. Signed-off-by: Gustavo Padovan --- drivers/dma-buf/sync_file.c | 129 +++++++++++++++++++++++++---------- drivers/staging/android/sync_debug.c | 5 +- include/linux/sync_file.h | 12 ++-- 3 files changed, 100 insertions(+), 46 deletions(-) diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index 9aaa608..5044ef2 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c @@ -25,14 +25,15 @@ #include #include #include +#include static const struct file_operations sync_file_fops; -static struct sync_file *sync_file_alloc(int size) +static struct sync_file *sync_file_alloc(void) { struct sync_file *sync_file; - sync_file = kzalloc(size, GFP_KERNEL); + sync_file = kzalloc(sizeof(*sync_file), GFP_KERNEL); if (!sync_file) return NULL; @@ -45,6 +46,8 @@ static struct sync_file *sync_file_alloc(int size) init_waitqueue_head(&sync_file->wq); + INIT_LIST_HEAD(&sync_file->cb.node); + return sync_file; err: @@ -54,11 +57,9 @@ err: static void fence_check_cb_func(struct fence *f, struct fence_cb *cb) { - struct sync_file_cb *check; struct sync_file *sync_file; - check = container_of(cb, struct sync_file_cb, cb); - sync_file = check->sync_file; + sync_file = container_of(cb, struct sync_file, cb); if (atomic_dec_and_test(&sync_file->status)) wake_up_all(&sync_file->wq); @@ -76,21 +77,20 @@ struct sync_file *sync_file_create(struct fence *fence) { struct sync_file *sync_file; - sync_file = sync_file_alloc(offsetof(struct sync_file, cbs[1])); + sync_file = sync_file_alloc(); if (!sync_file) return NULL; + sync_file->fence = fence; sync_file->num_fences = 1; + atomic_set(&sync_file->status, 1); snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%llu-%d", fence->ops->get_driver_name(fence), fence->ops->get_timeline_name(fence), fence->context, fence->seqno); - sync_file->cbs[0].fence = fence; - sync_file->cbs[0].sync_file = sync_file; - if (fence_add_callback(fence, &sync_file->cbs[0].cb, - fence_check_cb_func)) + if (fence_add_callback(fence, &sync_file->cb, fence_check_cb_func)) atomic_dec(&sync_file->status); return sync_file; @@ -121,14 +121,31 @@ err: return NULL; } -static void sync_file_add_pt(struct sync_file *sync_file, int *i, +static int sync_file_set_fence(struct sync_file *sync_file, + struct fence **fences) +{ + struct fence_array *array; + + if (sync_file->num_fences == 1) { + sync_file->fence = fences[0]; + } else { + array = fence_array_create(sync_file->num_fences, fences, + fence_context_alloc(1), 1, false); + if (!array) + return -ENOMEM; + + sync_file->fence = &array->base; + } + + return 0; +} + +static void fences_add_fence(struct fence **fences, int *i, struct fence *fence) { - sync_file->cbs[*i].fence = fence; - sync_file->cbs[*i].sync_file = sync_file; + fences[*i] = fence; - if (!fence_add_callback(fence, &sync_file->cbs[*i].cb, - fence_check_cb_func)) { + if (!fence_is_signaled(fence)) { fence_get(fence); (*i)++; } @@ -149,14 +166,31 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, { int num_fences = a->num_fences + b->num_fences; struct sync_file *sync_file; + struct fence **fences, **a_fences, **b_fences; int i, i_a, i_b; - unsigned long size = offsetof(struct sync_file, cbs[num_fences]); - sync_file = sync_file_alloc(size); + sync_file = sync_file_alloc(); if (!sync_file) return NULL; - atomic_set(&sync_file->status, num_fences); + fences = kcalloc(num_fences, sizeof(**fences), GFP_KERNEL); + if (!fences) + goto err; + + atomic_set(&sync_file->status, 1); + + a_fences = fence_get_fences(a->fence); + if (!a_fences) { + kfree(fences); + goto err; + } + + b_fences = fence_get_fences(b->fence); + if (!b_fences) { + kfree(a_fences); + kfree(fences); + goto err; + } /* * Assume sync_file a and b are both ordered and have no @@ -166,22 +200,22 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, * and sync_file_create, this is a reasonable assumption. */ for (i = i_a = i_b = 0; i_a < a->num_fences && i_b < b->num_fences; ) { - struct fence *pt_a = a->cbs[i_a].fence; - struct fence *pt_b = b->cbs[i_b].fence; + struct fence *pt_a = a_fences[i_a]; + struct fence *pt_b = b_fences[i_b]; if (pt_a->context < pt_b->context) { - sync_file_add_pt(sync_file, &i, pt_a); + fences_add_fence(fences, &i, pt_a); i_a++; } else if (pt_a->context > pt_b->context) { - sync_file_add_pt(sync_file, &i, pt_b); + fences_add_fence(fences, &i, pt_b); i_b++; } else { if (pt_a->seqno - pt_b->seqno <= INT_MAX) - sync_file_add_pt(sync_file, &i, pt_a); + fences_add_fence(fences, &i, pt_a); else - sync_file_add_pt(sync_file, &i, pt_b); + fences_add_fence(fences, &i, pt_b); i_a++; i_b++; @@ -189,31 +223,49 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, } for (; i_a < a->num_fences; i_a++) - sync_file_add_pt(sync_file, &i, a->cbs[i_a].fence); + fences_add_fence(fences, &i, a_fences[i_a]); for (; i_b < b->num_fences; i_b++) - sync_file_add_pt(sync_file, &i, b->cbs[i_b].fence); + fences_add_fence(fences, &i, b_fences[i_b]); - if (num_fences > i) - atomic_sub(num_fences - i, &sync_file->status); + if (num_fences > i) { + fences = krealloc(fences, i * sizeof(**fences), + GFP_KERNEL); + if (!fences) + goto ab_err; + } sync_file->num_fences = i; + if (sync_file_set_fence(sync_file, fences) < 0) { + kfree(fences); + goto ab_err; + } + + if (fence_add_callback(sync_file->fence, &sync_file->cb, + fence_check_cb_func)) + atomic_dec(&sync_file->status); + strlcpy(sync_file->name, name, sizeof(sync_file->name)); return sync_file; + +ab_err: + kfree(a_fences); + kfree(b_fences); + +err: + fput(sync_file->file); + return NULL; + } static void sync_file_free(struct kref *kref) { struct sync_file *sync_file = container_of(kref, struct sync_file, kref); - int i; - - for (i = 0; i < sync_file->num_fences; ++i) { - fence_remove_callback(sync_file->cbs[i].fence, - &sync_file->cbs[i].cb); - fence_put(sync_file->cbs[i].fence); - } + fence_remove_callback(sync_file->fence, &sync_file->cb); + fence_teardown(sync_file->fence); + fence_put(sync_file->fence); kfree(sync_file); } @@ -315,6 +367,7 @@ static long sync_file_ioctl_fence_info(struct sync_file *sync_file, { struct sync_file_info info; struct sync_fence_info *fence_info = NULL; + struct fence **fences; __u32 size; int ret, i; @@ -341,8 +394,10 @@ static long sync_file_ioctl_fence_info(struct sync_file *sync_file, if (!fence_info) return -ENOMEM; - for (i = 0; i < sync_file->num_fences; ++i) - sync_fill_fence_info(sync_file->cbs[i].fence, &fence_info[i]); + fences = fence_get_fences(sync_file->fence); + for (i = 0; i < sync_file->num_fences; i++) + sync_fill_fence_info(fences[i], &fence_info[i]); + kfree(fences); if (copy_to_user(u64_to_user_ptr(info.sync_fence_info), fence_info, size)) { diff --git a/drivers/staging/android/sync_debug.c b/drivers/staging/android/sync_debug.c index 5f57499..5fb6d3d 100644 --- a/drivers/staging/android/sync_debug.c +++ b/drivers/staging/android/sync_debug.c @@ -156,13 +156,16 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj) static void sync_print_sync_file(struct seq_file *s, struct sync_file *sync_file) { + struct fence **fences; int i; seq_printf(s, "[%p] %s: %s\n", sync_file, sync_file->name, sync_status_str(atomic_read(&sync_file->status))); + fences = fence_get_fences(sync_file->fence); for (i = 0; i < sync_file->num_fences; ++i) - sync_print_fence(s, sync_file->cbs[i].fence, true); + sync_print_fence(s, fences[i], true); + kfree(fences); } static int sync_debugfs_show(struct seq_file *s, void *unused) diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h index c6ffe8b..d13885f 100644 --- a/include/linux/sync_file.h +++ b/include/linux/sync_file.h @@ -20,12 +20,6 @@ #include #include -struct sync_file_cb { - struct fence_cb cb; - struct fence *fence; - struct sync_file *sync_file; -}; - /** * struct sync_file - sync file to export to the userspace * @file: file representing this fence @@ -35,7 +29,8 @@ struct sync_file_cb { * @num_fences: number of sync_pts in the fence * @wq: wait queue for fence signaling * @status: 0: signaled, >0:active, <0: error - * @cbs: sync_pts callback information + * @fence: fence with the fences in the sync_file + * @cb: fence callback information */ struct sync_file { struct file *file; @@ -49,7 +44,8 @@ struct sync_file { wait_queue_head_t wq; atomic_t status; - struct sync_file_cb cbs[]; + struct fence *fence; + struct fence_cb cb; }; struct sync_file *sync_file_create(struct fence *fence);