From patchwork Tue Aug 8 22:46:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Ekstrand X-Patchwork-Id: 9889181 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 72803603F2 for ; Tue, 8 Aug 2017 22:47:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 64B7728951 for ; Tue, 8 Aug 2017 22:47:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5976728A1E; Tue, 8 Aug 2017 22:47:17 +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.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E9CEC28A1C for ; Tue, 8 Aug 2017 22:47:16 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 96C756E247; Tue, 8 Aug 2017 22:46:45 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pf0-x244.google.com (mail-pf0-x244.google.com [IPv6:2607:f8b0:400e:c00::244]) by gabe.freedesktop.org (Postfix) with ESMTPS id 515446E277 for ; Tue, 8 Aug 2017 22:46:43 +0000 (UTC) Received: by mail-pf0-x244.google.com with SMTP id h75so4351500pfh.5 for ; Tue, 08 Aug 2017 15:46:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jlekstrand-net.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ZMhydNPEi/m9UhPoW4MpVD+AyexxqSW0PkuVr1XWY8E=; b=Yawa0TO9PKjH3DAbwOt51fCzZJD7sPN9IawmnaC7fI6wTYzDoyW45kKIyi8tL6DGsJ 0DqRjV8Tj9u+aEXc7hrRCJ5YeZUaTwisRxQBPiDQhip53Xqq2EOCy6Y9SxYGsUg/NK3s aEuTuxwwjwjc0MqRAva3BNFopx8HuX+q0RwssKylCpM7Iij1WwZHvQjDMBHGFNoZDoAb OEAi+LqAdcCJrwxWb7evo7LPDycWQCgVDoRiSvBClnHxvqiMdJ9lLrr4aqVn3kZxMPmT vW/nWQ6B4k0mUstXlmI+5WoxB4uWRVOl7FvH4QV+DVn/FZCpxhW+vevziny7RsXTSaaw AswA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ZMhydNPEi/m9UhPoW4MpVD+AyexxqSW0PkuVr1XWY8E=; b=aea5GhTKhhvw8PfTIe2OKQPOGjo81qrN+1ZTCBjhyXo8mtgCo/kNIMqd1bAsXOG1I1 TDPU1DJDZ2/A/Iax4Xj711e0jv3SNjHj66YOuD5whszp7ho6dt3IAqJBCIHhTsioO3qy oIZIDXc+QlNZRS/yIuAKtlV9QWAREcSFezTaLkuxs5O8UrUxywKMOWp3kgqQKzvDb5Rz Rwc6UXQcJTqGClhZ7ITWCmvD8pOvIGh0tgcm8da2IbgwTjc5waDvUw0d/QLFmc3VJbOr 2/3lx51c/B8Z2m/NIu3ysvR7Kwq7KbghhpSshTc/vwWHcEs7+l06BQa/peOlPz2wSfON Sl4g== X-Gm-Message-State: AHYfb5haeg5Qh2RhmmpZe7qxv4mF0hSJ/o0iKc0n27c4THDx5QhNmk3V kKjfrWVDa7H2wz3LFF11LA== X-Received: by 10.99.116.91 with SMTP id e27mr5717581pgn.269.1502232402431; Tue, 08 Aug 2017 15:46:42 -0700 (PDT) Received: from omlet.jf.intel.com ([192.55.54.45]) by smtp.gmail.com with ESMTPSA id l24sm56129pfi.99.2017.08.08.15.46.40 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 08 Aug 2017 15:46:41 -0700 (PDT) From: Jason Ekstrand X-Google-Original-From: Jason Ekstrand To: dri-devel@lists.freedesktop.org Subject: [PATCH 8/9] drm/syncobj: Add a callback mechanism for replace_fence Date: Tue, 8 Aug 2017 15:46:08 -0700 Message-Id: <1502232369-19753-9-git-send-email-jason.ekstrand@intel.com> X-Mailer: git-send-email 2.5.0.400.gff86faf In-Reply-To: <1502232369-19753-1-git-send-email-jason.ekstrand@intel.com> References: <1502232369-19753-1-git-send-email-jason.ekstrand@intel.com> Cc: Jason Ekstrand , Jason Ekstrand 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 It is useful in certain circumstances to know when the fence is replaced in a syncobj. Specifically, it may be useful to know when the fence goes from NULL to something valid. This does make syncobj_replace_fence a little more expensive because it has to take a lock but, in the common case where there is no callback list, it spends a very short amount of time inside the lock. Signed-off-by: Jason Ekstrand --- drivers/gpu/drm/drm_syncobj.c | 51 ++++++++++++++++++++++++++++++++++++++++++- include/drm/drm_syncobj.h | 33 +++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 25807f5..510dfc2 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -96,6 +96,46 @@ struct dma_fence *drm_syncobj_fence_get(struct drm_syncobj *syncobj) } EXPORT_SYMBOL(drm_syncobj_fence_get); +static void drm_syncobj_add_callback_locked(struct drm_syncobj *syncobj, + struct drm_syncobj_cb *cb, + drm_syncobj_func_t func) +{ + cb->func = func; + list_add_tail(&cb->node, &syncobj->cb_list); +} + +/** + * drm_syncobj_add_callback - adds a callback to syncobj::cb_list + * @syncobj: Sync object to which to add the callback + * @cb: Callback to add + * @func: Func to use when initializing the drm_syncobj_cb struct + * + * This adds a callback to be called next time the fence is replaced + */ +void drm_syncobj_add_callback(struct drm_syncobj *syncobj, + struct drm_syncobj_cb *cb, + drm_syncobj_func_t func) +{ + spin_lock(&syncobj->lock); + drm_syncobj_add_callback_locked(syncobj, cb, func); + spin_unlock(&syncobj->lock); +} +EXPORT_SYMBOL(drm_syncobj_add_callback); + +/** + * drm_syncobj_add_callback - removes a callback to syncobj::cb_list + * @syncobj: Sync object from which to remove the callback + * @cb: Callback to remove + */ +void drm_syncobj_remove_callback(struct drm_syncobj *syncobj, + struct drm_syncobj_cb *cb) +{ + spin_lock(&syncobj->lock); + list_del_init(&cb->node); + spin_unlock(&syncobj->lock); +} +EXPORT_SYMBOL(drm_syncobj_remove_callback); + /** * drm_syncobj_replace_fence - replace fence in a sync object. * @file_private: drm file private pointer. @@ -108,13 +148,21 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, struct dma_fence *fence) { struct dma_fence *old_fence = NULL; + struct drm_syncobj_cb *cur, *tmp; if (fence) dma_fence_get(fence); spin_lock(&syncobj->lock); + old_fence = syncobj->fence; syncobj->fence = fence; + + list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) { + list_del_init(&cur->node); + cur->func(syncobj, cur); + } + spin_unlock(&syncobj->lock); dma_fence_put(old_fence); @@ -151,7 +199,7 @@ void drm_syncobj_free(struct kref *kref) struct drm_syncobj *syncobj = container_of(kref, struct drm_syncobj, refcount); - dma_fence_put(syncobj->fence); + drm_syncobj_replace_fence(syncobj, NULL); kfree(syncobj); } EXPORT_SYMBOL(drm_syncobj_free); @@ -167,6 +215,7 @@ static int drm_syncobj_create(struct drm_file *file_private, return -ENOMEM; kref_init(&syncobj->refcount); + INIT_LIST_HEAD(&syncobj->cb_list); spin_lock_init(&syncobj->lock); idr_preload(GFP_KERNEL); diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h index 1c81658..a81af76 100644 --- a/include/drm/drm_syncobj.h +++ b/include/drm/drm_syncobj.h @@ -28,6 +28,8 @@ #include "linux/dma-fence.h" +struct drm_syncobj_cb; + /** * struct drm_syncobj - sync object. * @@ -46,8 +48,13 @@ struct drm_syncobj { */ struct dma_fence *fence; /** + * @list + * List of callbaks to call when the fence gets replaced + */ + struct list_head cb_list; + /** * @spinlock: - * locks fence. + * locks fence and cb_list. */ spinlock_t lock; /** @@ -57,6 +64,25 @@ struct drm_syncobj { struct file *file; }; +typedef void (*drm_syncobj_func_t)(struct drm_syncobj *syncobj, + struct drm_syncobj_cb *cb); + +/** + * struct drm_syncobj_cb - callback for drm_syncobj_add_callback + * @node: used by drm_syncob_add_callback to append this struct to + * syncobj::cb_list + * @func: drm_syncobj_func_t to call + * + * This struct will be initialized by drm_syncobj_add_callback, additional + * data can be passed along by embedding drm_syncobj_cb in another struct. + * The callback will get called the next time drm_syncobj_replace_fence is + * called. + */ +struct drm_syncobj_cb { + struct list_head node; + drm_syncobj_func_t func; +}; + void drm_syncobj_free(struct kref *kref); /** @@ -85,6 +111,11 @@ drm_syncobj_put(struct drm_syncobj *obj) struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private, u32 handle); struct dma_fence *drm_syncobj_fence_get(struct drm_syncobj *syncobj); +void drm_syncobj_add_callback(struct drm_syncobj *syncobj, + struct drm_syncobj_cb *cb, + drm_syncobj_func_t func); +void drm_syncobj_remove_callback(struct drm_syncobj *syncobj, + struct drm_syncobj_cb *cb); void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, struct dma_fence *fence); int drm_syncobj_find_fence(struct drm_file *file_private,