From patchwork Tue Aug 8 22:46:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Ekstrand X-Patchwork-Id: 9889187 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 2BEAD601EB for ; Tue, 8 Aug 2017 22:47:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1ED9128944 for ; Tue, 8 Aug 2017 22:47:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1399728A1C; Tue, 8 Aug 2017 22:47:19 +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 926B528944 for ; Tue, 8 Aug 2017 22:47:15 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3ADEB6E24C; Tue, 8 Aug 2017 22:46:33 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pf0-x243.google.com (mail-pf0-x243.google.com [IPv6:2607:f8b0:400e:c00::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id 93F3A6E24C for ; Tue, 8 Aug 2017 22:46:31 +0000 (UTC) Received: by mail-pf0-x243.google.com with SMTP id j68so4362327pfc.2 for ; Tue, 08 Aug 2017 15:46:31 -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=rGIyCmaV7tlKy5pvp32GumS/NYWgxwIbRxViQ8BbeMk=; b=GY1vYrXfKD+GiLXl01RYU2hC2BGOnXAQ740U/IgFT0F+vvTll6sBPHB6pz3mB/+vPK 7cRh+qMTqdFMbdN7O5rct7XpQU0dQXpL6HvrfNieb+gVItmDQCTmd2aHCr2CP86n5HPS CB6B1ALcvaVYrHCmklbS8gACp8VptsWAtPieqMK5AuAazm6tOeWt7E2W1pG0BialLdBX l2Vw5mOyMu7YCqRiWdm9xyPkUWgUujVUGC3KSgyyJKKQA/IbHayIRqtXf1VS0ejnOmsd VU4pk5g82yqNu2+FaDdUT+rb7uH/XQ83Rupk+qi50XtYQB5PWsqEvws6sCGiIVHgaxf0 lx0w== 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=rGIyCmaV7tlKy5pvp32GumS/NYWgxwIbRxViQ8BbeMk=; b=gz+DPqfGJfpRi5n19w8vmlOOhLnGJBl2YfoM0Q2GzEl0qzhwfRMAe6b1MQ8/X6dlOB sDquYy0VdM+a6uMWoldw8eampSsShrGXdo9I/bZ1yQV31fLqFpTYgfiGI/EFkSgEkknW BPqeijXcRVTcr7QRkfQe+QMjYQDO1Q1ihdFTSJ8j0OUf51/0iR6XfMr4oLzR8iOQ3YkK uZZpevSOsY53+TLm7vQqj9JGeV4hJ0CDfET3qgkM6PqD7u38XyLpnaX/aIepXcL+FlvK N6jFEZKswL61dHnZ8NkdI7s4KCxiXGKvUp9AJcPd1P0MCkPpRCsxh7bXWF5Ok5ue3Zod MQhQ== X-Gm-Message-State: AHYfb5j4g9Tt7WJQVi9S3SShUIdiXi3m8flONME4GanUYRrb8/fOxPJt 9RQrWb68rgoRMFWnC6WkkA== X-Received: by 10.99.156.1 with SMTP id f1mr5481204pge.327.1502232390876; Tue, 08 Aug 2017 15:46:30 -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.29 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 08 Aug 2017 15:46:29 -0700 (PDT) From: Jason Ekstrand X-Google-Original-From: Jason Ekstrand To: dri-devel@lists.freedesktop.org Subject: [PATCH 2/9] drm/syncobj: Lock around drm_syncobj::fence Date: Tue, 8 Aug 2017 15:46:02 -0700 Message-Id: <1502232369-19753-3-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 The atomic exchange operation we were doing before in replace_fence was sufficient for the case where it raced with itself. However, if you have a race between a replace_fence and dma_fence_get(syncobj->fence), you may end up with the entire replace_fence happening between the point in time where the one thread gets the syncobj->fence pointer and when it calls dma_fence_get() on it. If this happens, then the reference may be dropped before we get a chance to get a new one. Signed-off-by: Jason Ekstrand --- drivers/gpu/drm/drm_syncobj.c | 25 +++++++++++++++++++++++-- include/drm/drm_syncobj.h | 6 ++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 6f2a6041..dafca83 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -75,6 +75,22 @@ struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private, } EXPORT_SYMBOL(drm_syncobj_find); +struct dma_fence *drm_syncobj_fence_get(struct drm_syncobj *syncobj) +{ + struct dma_fence *fence; + + /* Lock to prevent someone from replacing the fence and dropping + * the syncobj's reference between when we get the dma_fence + * pointer and wehen we have a chance to incref. + */ + spin_lock(&syncobj->lock); + fence = dma_fence_get(syncobj->fence); + spin_unlock(&syncobj->lock); + + return fence; +} +EXPORT_SYMBOL(drm_syncobj_fence_get); + /** * drm_syncobj_replace_fence - replace fence in a sync object. * @file_private: drm file private pointer. @@ -91,7 +107,11 @@ void drm_syncobj_replace_fence(struct drm_file *file_private, if (fence) dma_fence_get(fence); - old_fence = xchg(&syncobj->fence, fence); + + spin_lock(&syncobj->lock); + old_fence = syncobj->fence; + syncobj->fence = fence; + spin_unlock(&syncobj->lock); dma_fence_put(old_fence); } @@ -107,7 +127,7 @@ int drm_syncobj_find_fence(struct drm_file *file_private, if (!syncobj) return -ENOENT; - *fence = dma_fence_get(syncobj->fence); + *fence = drm_syncobj_fence_get(syncobj); if (!*fence) { ret = -EINVAL; } @@ -143,6 +163,7 @@ static int drm_syncobj_create(struct drm_file *file_private, return -ENOMEM; kref_init(&syncobj->refcount); + spin_lock_init(&syncobj->lock); idr_preload(GFP_KERNEL); spin_lock(&file_private->syncobj_table_lock); diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h index 9ffff22..422d631 100644 --- a/include/drm/drm_syncobj.h +++ b/include/drm/drm_syncobj.h @@ -46,6 +46,11 @@ struct drm_syncobj { */ struct dma_fence *fence; /** + * @spinlock: + * locks fence. + */ + spinlock_t lock; + /** * @file: * a file backing for this syncobj. */ @@ -79,6 +84,7 @@ 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_replace_fence(struct drm_file *file_private, struct drm_syncobj *syncobj, struct dma_fence *fence);