From patchwork Mon Aug 29 07:08:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 9303195 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 793076077C for ; Mon, 29 Aug 2016 07:24:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 621F626E54 for ; Mon, 29 Aug 2016 07:24:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 52ED128736; Mon, 29 Aug 2016 07:24:58 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B8BDC26E54 for ; Mon, 29 Aug 2016 07:24:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756466AbcH2HYu (ORCPT ); Mon, 29 Aug 2016 03:24:50 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:34878 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756459AbcH2HYu (ORCPT ); Mon, 29 Aug 2016 03:24:50 -0400 Received: by mail-wm0-f67.google.com with SMTP id i5so8258049wmg.2 for ; Mon, 29 Aug 2016 00:24:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yu2RnT7NyC90w/zoKpq9LDcoCwJsutPVYo0wlpuYs40=; b=yvFB5zk7/OFFhXmeniQ7eRibIbXwSoAUpB+Mb0mQjir24YAcPXVZni0/HhPs6uf+QI IoT5qHad7W7Ru37IONzNYPYgH0y2vJa72oZbbITyD3D9PbnjjZ37F72C43yCSkjzKsf4 g7E/qmfMuI+Kwjqd7+WorndPPmzTvfRsMvXxVzFY4JUhvZsrRhP+Q50ZXA4QCN4uCJbL i8Col9QgOuhUpmOdvJo2mHw7cD4JRjfDWsZ5EU/Wl6IAHoHhhR0AodGVujKLEu8/Np3Y PFbXVESMLtES/caUsLK5DiAVQqzVNmjgzdUdBtzpA3hOtEBWPaX4/ZHM+w8pXJ6Wn50G C5Vw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=yu2RnT7NyC90w/zoKpq9LDcoCwJsutPVYo0wlpuYs40=; b=QyPtBF4WZqZJO/3ipOkqtADlwKS4GgwyodIwNOX8F1aEZfUNsdJZ0mEDKFcm+HXLTL 4wlBCbP8x8qzS5giy+MIdVy1DSKfvJflEQuR1olchVdhRovULJag1dpYlbHCQp4NR3SP oMA6bBiTc/Rw86VJYpj97Mo8jyVaM4o5BKXWYmhCnblfJ6cti6JgU4csBI9Geo/kpX1R iholIeBEPwo83euNRs6Ao5rS4IY5C+dUXXG7h6U8dEReENDQFs8C7KiingA3Jm1c9nFi FLfQ6NMDTw/qholBzPH1fm+oEXUZHuSQRnpiPG9AWXYoNfTIUfzkH66L3uqMBs1uu+ma UWZg== X-Gm-Message-State: AE9vXwNDjcfNcKFOjC7UyyCOT7pt6Uzec+nN2tzVYR446TmhFNXljXU6zDRw6kKDUauecg== X-Received: by 10.194.105.201 with SMTP id go9mr13974376wjb.177.1472454531382; Mon, 29 Aug 2016 00:08:51 -0700 (PDT) Received: from haswell.alporthouse.com ([78.156.65.138]) by smtp.gmail.com with ESMTPSA id v203sm11954826wmv.2.2016.08.29.00.08.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 29 Aug 2016 00:08:50 -0700 (PDT) From: Chris Wilson To: dri-devel@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org, Chris Wilson , Daniel Vetter , Maarten Lankhorst , =?UTF-8?q?Christian=20K=C3=B6nig?= , Alex Deucher , Sumit Semwal , linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org Subject: [PATCH 09/11] dma-buf: Restart reservation_object_test_signaled_rcu() after writes Date: Mon, 29 Aug 2016 08:08:32 +0100 Message-Id: <20160829070834.22296-9-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20160829070834.22296-1-chris@chris-wilson.co.uk> References: <20160829070834.22296-1-chris@chris-wilson.co.uk> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In order to be completely generic, we have to double check the read seqlock after acquiring a reference to the fence. If the driver is allocating fences from a SLAB_DESTROY_BY_RCU, or similar freelist, then within an RCU grace period a fence may be freed and reallocated. The RCU read side critical section does not prevent this reallocation, instead we have to inspect the reservation's seqlock to double check if the fences have been reassigned as we were acquiring our reference. Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Maarten Lankhorst Cc: Christian König Cc: Alex Deucher Cc: Sumit Semwal Cc: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linaro-mm-sig@lists.linaro.org Reviewed-by: Daniel Vetter --- drivers/dma-buf/reservation.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c index 3369e4668e96..e74493e7332b 100644 --- a/drivers/dma-buf/reservation.c +++ b/drivers/dma-buf/reservation.c @@ -474,12 +474,13 @@ bool reservation_object_test_signaled_rcu(struct reservation_object *obj, bool test_all) { unsigned seq, shared_count; - int ret = true; + int ret; + rcu_read_lock(); retry: + ret = true; shared_count = 0; seq = read_seqcount_begin(&obj->seq); - rcu_read_lock(); if (test_all) { unsigned i; @@ -490,46 +491,35 @@ retry: if (fobj) shared_count = fobj->shared_count; - if (read_seqcount_retry(&obj->seq, seq)) - goto unlock_retry; - for (i = 0; i < shared_count; ++i) { struct fence *fence = rcu_dereference(fobj->shared[i]); ret = reservation_object_test_signaled_single(fence); if (ret < 0) - goto unlock_retry; + goto retry; else if (!ret) break; } - /* - * There could be a read_seqcount_retry here, but nothing cares - * about whether it's the old or newer fence pointers that are - * signaled. That race could still have happened after checking - * read_seqcount_retry. If you care, use ww_mutex_lock. - */ + if (read_seqcount_retry(&obj->seq, seq)) + goto retry; } if (!shared_count) { struct fence *fence_excl = rcu_dereference(obj->fence_excl); - if (read_seqcount_retry(&obj->seq, seq)) - goto unlock_retry; - if (fence_excl) { ret = reservation_object_test_signaled_single( fence_excl); if (ret < 0) - goto unlock_retry; + goto retry; + + if (read_seqcount_retry(&obj->seq, seq)) + goto retry; } } rcu_read_unlock(); return ret; - -unlock_retry: - rcu_read_unlock(); - goto retry; } EXPORT_SYMBOL_GPL(reservation_object_test_signaled_rcu);