From patchwork Wed Aug 16 04:13:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jason Ekstrand X-Patchwork-Id: 9902865 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 09FFF603B5 for ; Wed, 16 Aug 2017 04:14:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F2971288C3 for ; Wed, 16 Aug 2017 04:14:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E5C2528982; Wed, 16 Aug 2017 04:14:48 +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 42537288CA for ; Wed, 16 Aug 2017 04:14:48 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E53B789FC9; Wed, 16 Aug 2017 04:14:08 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pf0-x241.google.com (mail-pf0-x241.google.com [IPv6:2607:f8b0:400e:c00::241]) by gabe.freedesktop.org (Postfix) with ESMTPS id EB7BF89F53 for ; Wed, 16 Aug 2017 04:14:07 +0000 (UTC) Received: by mail-pf0-x241.google.com with SMTP id p13so274212pfd.4 for ; Tue, 15 Aug 2017 21:14:07 -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 :mime-version:content-transfer-encoding; bh=Ejjwx/YiSr5WH+JtlZBckFcckJ3Kcr6GyxMAAIt4EjQ=; b=vPiNXI2IQ36J98wfSbau/lB2PKKFZJ/962l8vbBGf6nORilZJH9rRQR10y3geKKTVn FrBb0sjm07dcx5YzuWnSPdx6X9X2gXjsKNh95kemgmmjQiSYMtEaoDwgwA/u0hv7A1P+ Br4Gi2zHEg8fxqqYDgvxEdR+kyoRkGkXl/qDB4CLGVayWDYUZYCnUxABU8orQF/Sj2DA a8whktIsT+Y/qvvu7S63y1bIgXoaC6hOLPDNHzHAiNmokt9ebt06RACLCd0u2RcVR0cK hPzHB7Qut8SZG1Enqcuqq8+KB/l+2FU/+Tu2Su5+lkK+E+KSjbyoQ7DAkSELEAiHdb3o LjnA== 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:mime-version:content-transfer-encoding; bh=Ejjwx/YiSr5WH+JtlZBckFcckJ3Kcr6GyxMAAIt4EjQ=; b=sckdSwVvi7vN2jtVRf/K0fUyCzFpNaK76NF6XI30jMwivg1SMPEXVdiAjaGEZnw4s7 Rksom5WGRd9cS+jbbCit0Xjk3hQ/dy5LIfjTP6cxv60IXI9Jp3o5mdab2ZaX26B2tU6e /H+SKDvLcOXLHJVkvE5DPQyOOKaC74CHWIoX4bZxfDZgYVtTwbfrxKOkAdnYSJqe224z v7JP5B0PPc5/SjVC4bzINxY5Z3JuAdbRZjzeudO2y8VhyMcHKz40BnLGEQTNPY0owDR4 4aqJOlpQ1i3XYcx1zG7yYxdECdbvndb9oWtQx4GBgnqOj7dBvIFAfHugOBlfF+0zU/Gi ZapQ== X-Gm-Message-State: AHYfb5gpWDGUItXlhu5RLxV48/U3s4ChIca3mO72nD4z5TbdmNrmOiZT LaH+DasRlcH8VyE3sQ+hCg== X-Received: by 10.84.218.139 with SMTP id r11mr445292pli.25.1502856846949; Tue, 15 Aug 2017 21:14:06 -0700 (PDT) Received: from omlet.jf.intel.com ([192.55.54.40]) by smtp.gmail.com with ESMTPSA id f88sm19684595pff.74.2017.08.15.21.14.05 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 15 Aug 2017 21:14:06 -0700 (PDT) From: Jason Ekstrand X-Google-Original-From: Jason Ekstrand To: dri-devel@lists.freedesktop.org Subject: [PATCH 2/7] drm/syncobj: Add a race-free drm_syncobj_fence_get helper (v2) Date: Tue, 15 Aug 2017 21:13:50 -0700 Message-Id: <1502856835-9433-3-git-send-email-jason.ekstrand@intel.com> X-Mailer: git-send-email 2.5.0.400.gff86faf In-Reply-To: <1502856835-9433-1-git-send-email-jason.ekstrand@intel.com> References: <1502856835-9433-1-git-send-email-jason.ekstrand@intel.com> MIME-Version: 1.0 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: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP The atomic exchange operation in drm_syncobj_replace_fence is sufficient for the case where it races 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. The new helper uses dma_fence_get_rcu_safe to get rid of the race. This is also needed because it allows us to do a bit more than just get a reference in drm_syncobj_fence_get should we wish to do so. v2: - RCU isn't that scary - Call rcu_read_lock/unlock - Don't rename fence to _fence - Make the helper static inline Signed-off-by: Jason Ekstrand Acked-by: Christian König (v1) --- drivers/gpu/drm/drm_syncobj.c | 2 +- include/drm/drm_syncobj.h | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 0412b0b..eea38d8 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -105,7 +105,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; } diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h index 7d4ad77..ce94d14 100644 --- a/include/drm/drm_syncobj.h +++ b/include/drm/drm_syncobj.h @@ -77,6 +77,18 @@ drm_syncobj_put(struct drm_syncobj *obj) kref_put(&obj->refcount, drm_syncobj_free); } +static inline struct dma_fence * +drm_syncobj_fence_get(struct drm_syncobj *syncobj) +{ + struct dma_fence *fence; + + rcu_read_lock(); + fence = dma_fence_get_rcu_safe(&syncobj->fence); + rcu_read_unlock(); + + return fence; +} + struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private, u32 handle); void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,