From patchwork Mon Aug 26 09:04:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lionel Landwerlin X-Patchwork-Id: 11114277 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C8C0F14DE for ; Mon, 26 Aug 2019 09:05:05 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AF95421744 for ; Mon, 26 Aug 2019 09:05:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AF95421744 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C17C289A94; Mon, 26 Aug 2019 09:04:59 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 831138982E for ; Mon, 26 Aug 2019 09:04:55 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Aug 2019 02:04:55 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,431,1559545200"; d="scan'208";a="204510208" Received: from jbroders-mobl1.ger.corp.intel.com (HELO delly.ger.corp.intel.com) ([10.252.38.38]) by fmsmga004.fm.intel.com with ESMTP; 26 Aug 2019 02:04:53 -0700 From: Lionel Landwerlin To: dri-devel@lists.freedesktop.org Subject: [PATCH 1/3] drm/syncobj: protect timeline syncobjs Date: Mon, 26 Aug 2019 12:04:46 +0300 Message-Id: <20190826090448.12819-2-lionel.g.landwerlin@intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190826090448.12819-1-lionel.g.landwerlin@intel.com> References: <20190826090448.12819-1-lionel.g.landwerlin@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Christian.Koenig@amd.com, jason@jlekstrand.net Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Binary/legacy signal operations on a syncobj work by replacing the dma_fence held within the syncobj. Whe dealing with timeline semaphores we would like to avoid this as this would effectivelly lead to looser synchronization (by discarding the dma_fence_chain mechanism waiting on all previous dma_fence to signal before signal itself). This change adds a flags that can be used at creation of the syncobj to mean that the syncobj will hold a timeline of dma_fence (using dma_fence_chain). When flagged as such, the dma_fence held by the syncobj should not be replaced but instead we should always adding to the timeline. Signed-off-by: Lionel Landwerlin --- drivers/gpu/drm/drm_syncobj.c | 30 +++++++++++++++++++++++++++++- include/drm/drm_syncobj.h | 8 ++++++++ include/uapi/drm/drm.h | 1 + 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 72d083acd388..69d43c791a42 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -476,6 +476,8 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, if (flags & DRM_SYNCOBJ_CREATE_SIGNALED) drm_syncobj_assign_null_handle(syncobj); + if (flags & DRM_SYNCOBJ_CREATE_TIMELINE) + syncobj->is_timeline = true; if (fence) drm_syncobj_replace_fence(syncobj, fence); @@ -661,6 +663,10 @@ static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, dma_fence_put(fence); return -ENOENT; } + if (syncobj->is_timeline) { + dma_fence_put(fence); + return -EINVAL; + } drm_syncobj_replace_fence(syncobj, fence); dma_fence_put(fence); @@ -749,7 +755,13 @@ drm_syncobj_create_ioctl(struct drm_device *dev, void *data, return -EOPNOTSUPP; /* no valid flags yet */ - if (args->flags & ~DRM_SYNCOBJ_CREATE_SIGNALED) + if (args->flags & ~(DRM_SYNCOBJ_CREATE_SIGNALED | + DRM_SYNCOBJ_CREATE_TIMELINE)) + return -EINVAL; + + /* Creating a signaled timeline makes no sense. */ + if ((args->flags & DRM_SYNCOBJ_CREATE_SIGNALED) && + (args->flags & DRM_SYNCOBJ_CREATE_TIMELINE)) return -EINVAL; return drm_syncobj_create_as_handle(file_private, @@ -862,6 +874,10 @@ drm_syncobj_transfer_to_binary(struct drm_file *file_private, binary_syncobj = drm_syncobj_find(file_private, args->dst_handle); if (!binary_syncobj) return -ENOENT; + if (binary_syncobj->is_timeline) { + ret = -EINVAL; + goto err; + } ret = drm_syncobj_find_fence(file_private, args->src_handle, args->src_point, args->flags, &fence); if (ret) @@ -1137,6 +1153,7 @@ static int drm_syncobj_array_wait(struct drm_device *dev, static int drm_syncobj_array_find(struct drm_file *file_private, void __user *user_handles, uint32_t count_handles, + bool no_timeline, struct drm_syncobj ***syncobjs_out) { uint32_t i, *handles; @@ -1165,6 +1182,10 @@ static int drm_syncobj_array_find(struct drm_file *file_private, ret = -ENOENT; goto err_put_syncobjs; } + if (no_timeline && syncobjs[i]->is_timeline) { + ret = -EINVAL; + goto err_put_syncobjs; + } } kfree(handles); @@ -1211,6 +1232,7 @@ drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), args->count_handles, + false, &syncobjs); if (ret < 0) return ret; @@ -1245,6 +1267,7 @@ drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), args->count_handles, + false, &syncobjs); if (ret < 0) return ret; @@ -1279,6 +1302,7 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), args->count_handles, + false, &syncobjs); if (ret < 0) return ret; @@ -1314,6 +1338,7 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), args->count_handles, + true, &syncobjs); if (ret < 0) return ret; @@ -1349,6 +1374,7 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), args->count_handles, + false, &syncobjs); if (ret < 0) return ret; @@ -1420,6 +1446,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), args->count_handles, + false, &syncobjs); if (ret < 0) return ret; @@ -1484,6 +1511,7 @@ int drm_syncobj_binary_ioctl(struct drm_device *dev, void *data, ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), args->count_handles, + false, &syncobjs); if (ret < 0) return ret; diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h index aa76cb3f9107..f96a95fbe025 100644 --- a/include/drm/drm_syncobj.h +++ b/include/drm/drm_syncobj.h @@ -70,6 +70,14 @@ struct drm_syncobj { * seqno will be put into the syncobj. */ atomic64_t binary_payload; + /** + * @is_timeline: Whether the syncobj holds a timeline. + * + * Holding a timeline adds some restriction to prevent userspace from + * accidentally "losing" the timeline. This could happen for example + * by replacing &fence. + */ + bool is_timeline; }; void drm_syncobj_free(struct kref *kref); diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 78a0a413b788..b3c46b2993be 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -719,6 +719,7 @@ struct drm_prime_handle { struct drm_syncobj_create { __u32 handle; #define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0) +#define DRM_SYNCOBJ_CREATE_TIMELINE (1 << 1) __u32 flags; };