From patchwork Fri Aug 11 22:39:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Ekstrand X-Patchwork-Id: 9896691 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 9558D60351 for ; Fri, 11 Aug 2017 22:39:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8898328CAC for ; Fri, 11 Aug 2017 22:39:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7DC2D28CFE; Fri, 11 Aug 2017 22:39:49 +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 2DD0928CAC for ; Fri, 11 Aug 2017 22:39:49 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B02DB6E760; Fri, 11 Aug 2017 22:39:47 +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 17AD56E760 for ; Fri, 11 Aug 2017 22:39:46 +0000 (UTC) Received: by mail-pf0-x243.google.com with SMTP id c65so4536319pfl.0 for ; Fri, 11 Aug 2017 15:39:46 -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=aXFeAL2j7BV0CNFj+WdVtZ9klAtPXX9UATvwqDz33dc=; b=awYkt9nt8fqjqNvmhA13H3BCrCCvSyYTXS5MZnXno3kvaB77mnWmQjx2gm9KPQH2ef iub7t6cBTJqmir8fsEvxXH0hh1PGrJpDmtqeepA+6OvsBMrbfijFzooSiKRum6ApiroW 1BRSXsNm0ZqHFZFMbSja896CabEIS9ygQwTACoQP8t7wcRvTOIZShQXolX756aT1hTBj zS5goJ6MX/R074fhddVHummpg+1+H8nJUtTpxbG9r5nBIJKw8jCyhYPs5zBPpdatOlfx iFJQuk5oN74bKEzi0tbnG5rRu4oD87g0IL1j3T2JuFCypzmh9OxH+rvZ+y/F05ARQKjl 16cw== 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=aXFeAL2j7BV0CNFj+WdVtZ9klAtPXX9UATvwqDz33dc=; b=fAv+HYnyqNMo1sZZUH9s45Sp3arF0Cho1STEupOr2f79ztDu3xTQsCul0yy/sbHlDo SuIPJC2hGC0FZSMCnW7JHtiCLLrZvA9WXcHjFeykQHeZWMaBIUvV8RhBhGoDf6a1CKN+ ZIrnbHo3BjFEeRVzIS1sbu67oPHmCSj+KcmG+ylj8f8KvAMhxbCZGNuqD28phkti+pfh EYPB9mvwKsbd3AEcMKAU44xzSFGsLx/EWeXLDY8QFMZiXGExRY8TEzUncb3HfHI074au DfTT6/LR7Pnfp5i5ojIfxS1eTlkJG+STCV3rVcmhQ3EN3WA3lFLOTZTpIt6WY5GZY7eW IcTA== X-Gm-Message-State: AHYfb5jdI4n8xl+pGPgXjWb8ZqJitP5sZq4Q70+5ARJsfJO4FdND09xy rQ+t0qOr3Dtu+5GJkza8zQ== X-Received: by 10.84.231.198 with SMTP id g6mr10806388pln.36.1502491185374; Fri, 11 Aug 2017 15:39:45 -0700 (PDT) Received: from omlet.jf.intel.com (fmdmzpr03-ext.fm.intel.com. [192.55.54.38]) by smtp.gmail.com with ESMTPSA id p77sm3244484pfi.153.2017.08.11.15.39.43 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 11 Aug 2017 15:39:44 -0700 (PDT) From: Jason Ekstrand X-Google-Original-From: Jason Ekstrand To: dri-devel@lists.freedesktop.org Subject: [PATCH 2/9] drm/syncobj: Add a race-free drm_syncobj_fence_get helper Date: Fri, 11 Aug 2017 15:39:27 -0700 Message-Id: <1502491174-10913-3-git-send-email-jason.ekstrand@intel.com> X-Mailer: git-send-email 2.5.0.400.gff86faf In-Reply-To: <1502491174-10913-1-git-send-email-jason.ekstrand@intel.com> References: <1502232369-19753-1-git-send-email-jason.ekstrand@intel.com> <1502491174-10913-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 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. Signed-off-by: Jason Ekstrand --- drivers/gpu/drm/drm_syncobj.c | 12 +++++++++--- include/drm/drm_syncobj.h | 6 +++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 0412b0b..0190ec2 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -75,6 +75,12 @@ 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) +{ + return dma_fence_get_rcu_safe(&syncobj->_fence); +} +EXPORT_SYMBOL(drm_syncobj_fence_get); + /** * drm_syncobj_replace_fence - replace fence in a sync object. * @syncobj: Sync object to replace fence in @@ -89,7 +95,7 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, if (fence) dma_fence_get(fence); - old_fence = xchg(&syncobj->fence, fence); + old_fence = xchg(&syncobj->_fence, fence); dma_fence_put(old_fence); } @@ -105,7 +111,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; } @@ -125,7 +131,7 @@ void drm_syncobj_free(struct kref *kref) struct drm_syncobj *syncobj = container_of(kref, struct drm_syncobj, refcount); - dma_fence_put(syncobj->fence); + dma_fence_put(syncobj->_fence); kfree(syncobj); } EXPORT_SYMBOL(drm_syncobj_free); diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h index 7d4ad77..c06a441 100644 --- a/include/drm/drm_syncobj.h +++ b/include/drm/drm_syncobj.h @@ -43,8 +43,11 @@ struct drm_syncobj { /** * @fence: * NULL or a pointer to the fence bound to this object. + * + * This pointer should not be accessed directly. Instead, use + * drm_syncobj_fence_get or drm_syncobj_replace_fence. */ - struct dma_fence *fence; + struct dma_fence *_fence; /** * @file: * a file backing for this syncobj. @@ -79,6 +82,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_syncobj *syncobj, struct dma_fence *fence); int drm_syncobj_find_fence(struct drm_file *file_private,