Received: by 2002:a25:868d:0:0:0:0:0 with SMTP id z13csp432395ybk; Wed, 13 May 2020 04:07:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxPzLMrT5BD0cWn7oOvCqLQTTHs8S82YfA5ZRUfmeVBPsPy81pYzH3x5y3iu5t3eIZdFest X-Received: by 2002:a50:f017:: with SMTP id r23mr5629370edl.290.1589368050780; Wed, 13 May 2020 04:07:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1589368050; cv=none; d=google.com; s=arc-20160816; b=DH0SYiDJXJ1bZOkMoGRCFkTAafABxsi+gNRW2GdolCJ4UEhqqhRwhXevaH2GAMt9WY kDUbjV4egppfiQ0MQ0hpq9kpXiHCAuquPZ71Lf1yD/x8QBzwko/O/vfUxogRPO321PwE tKUNSlUJKbcTmUn0eDEqFHt23UjDEHGd4tP7Uh3bvbj3+QPnKD+R2bnM6UhnaUmt4xZx MSjZ5Surf5HILldpr2SnbfG8b45EzceuNvqYWQo7eCd4VOx8TYmwijTF/4nI/Or/kP0G uT5+tipym7hQbf3f/4dGdzq6c80pljSCcFlTpNJwKHNz9IyowFAlakXUGz4TAA/Z0xxG nzsA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=P/cQOw5xN+TfOYRkXBpG74KgaYsRxjssQU8OCSQs0lw=; b=oBi2pZoLxzMRPcaXstXnM5CvmRGz7yPHVhjeuf9gn8Qms/UkFyllkRFQwEPQXkKFvz olW+bZow3vS46xoEyRSE5I+O/rtkj669EpVGAG0GT3CKIzL8ZihiZM2Tol5/gKXURQdE jXW+DHchPPKdVApgrpEM0zgdsZ/2J6QMY/PFBOo9k4D3TPV7keNAuanVKba6gDzOZsyZ Pa8Yo1QLLpDaWBq6MK2dgZesRbTJ+LKJg6oIxTbe7qGu20Q5DaiIFWWCPepnpgchqOPo FFA18KnV+eVrb4Xy4tLTiQqWDLQ0X7z9XQJ4WQOviohEtWK7YsEI71nN5n4vdAz8mamk iuLQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ffwll.ch header.s=google header.b=ZYqNT7S9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id m31si1027116ede.443.2020.05.13.04.07.06; Wed, 13 May 2020 04:07:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@ffwll.ch header.s=google header.b=ZYqNT7S9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732283AbgEMIac (ORCPT + 99 others); Wed, 13 May 2020 04:30:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36832 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732174AbgEMIab (ORCPT ); Wed, 13 May 2020 04:30:31 -0400 Received: from mail-oo1-xc44.google.com (mail-oo1-xc44.google.com [IPv6:2607:f8b0:4864:20::c44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1C833C061A0E for ; Wed, 13 May 2020 01:30:31 -0700 (PDT) Received: by mail-oo1-xc44.google.com with SMTP id c83so3286278oob.6 for ; Wed, 13 May 2020 01:30:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=P/cQOw5xN+TfOYRkXBpG74KgaYsRxjssQU8OCSQs0lw=; b=ZYqNT7S96JIC/2QUMWjtKF68s7Mlj31GoqTmd/vNnuROLIyB0kD9KQbJGZzvzwvUbA E3luqZwNVfQvG5bGKUij9LW4w7tisfb2ZjPEK2MdxiXprewxdAOya4VpMVU2y0meest4 Fp2TkQzADhnoZpBxsZgu12qAiKzzJR0VP+umY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=P/cQOw5xN+TfOYRkXBpG74KgaYsRxjssQU8OCSQs0lw=; b=Ga06PIO5UdlCPNK5AcArrZ+GLH+5TTpfuXi7t00ezy5w0KIcQj1m8lJRDAE13TZOE3 Ji6xxRd64gsXHoP4wBnG78QqYFgRgOVSC80zHOowyzK9P0ATQch2TU35iHDchWLo4lRE gARwaP0EQqQzUAAkqmB5FuMJ9torI9qjkbTh39SvaP25e8B4X3fQrbW9zLR1njZNjUqv AbsaCXaKn/9t4ibnHZ9816oXlmLI0U8UxZIF9E7mLOnwdnl3OdW0XMIVp1wM03WhlDfH 0a0nR5qODyF/QL9qcSQLtDCmePBCzJ0TJo2UH7jEQHLt2ulI6PQHT3SX2BgiUFXHh51N XHmA== X-Gm-Message-State: AGi0PuYqL8vN4Lra0x64Nj3uNnnuxFiCYqXpzuA9vquCZLJhY+s106Im zKDf/3Ojad+Tm0ifEtVuPfAcaMIHzc/Ub8D1o9xLOA== X-Received: by 2002:a4a:d136:: with SMTP id n22mr21115688oor.85.1589358630346; Wed, 13 May 2020 01:30:30 -0700 (PDT) MIME-Version: 1.0 References: <20200512085944.222637-1-daniel.vetter@ffwll.ch> <20200512085944.222637-3-daniel.vetter@ffwll.ch> <158927426244.15653.14406159524439944950@build.alporthouse.com> <20200512090847.GF206103@phenom.ffwll.local> <158927519651.15653.17392305363363808831@build.alporthouse.com> In-Reply-To: <158927519651.15653.17392305363363808831@build.alporthouse.com> From: Daniel Vetter Date: Wed, 13 May 2020 10:30:19 +0200 Message-ID: Subject: Re: [RFC 02/17] dma-fence: basic lockdep annotations To: Chris Wilson Cc: DRI Development , LKML , "open list:DMA BUFFER SHARING FRAMEWORK" , "moderated list:DMA BUFFER SHARING FRAMEWORK" , linux-rdma , amd-gfx list , intel-gfx , Maarten Lankhorst , =?UTF-8?Q?Christian_K=C3=B6nig?= , Daniel Vetter , Dave Airlie , Joonas Lahtinen Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, May 12, 2020 at 11:19 AM Chris Wilson wr= ote: > Quoting Daniel Vetter (2020-05-12 10:08:47) > > On Tue, May 12, 2020 at 10:04:22AM +0100, Chris Wilson wrote: > > > Quoting Daniel Vetter (2020-05-12 09:59:29) > > > > Design is similar to the lockdep annotations for workers, but with > > > > some twists: > > > > > > > > - We use a read-lock for the execution/worker/completion side, so t= hat > > > > this explicit annotation can be more liberally sprinkled around. > > > > With read locks lockdep isn't going to complain if the read-side > > > > isn't nested the same way under all circumstances, so ABBA deadlo= cks > > > > are ok. Which they are, since this is an annotation only. > > > > > > > > - We're using non-recursive lockdep read lock mode, since in recurs= ive > > > > read lock mode lockdep does not catch read side hazards. And we > > > > _very_ much want read side hazards to be caught. For full details= of > > > > this limitation see > > > > > > > > commit e91498589746065e3ae95d9a00b068e525eec34f > > > > Author: Peter Zijlstra > > > > Date: Wed Aug 23 13:13:11 2017 +0200 > > > > > > > > locking/lockdep/selftests: Add mixed read-write ABBA tests > > > > > > > > - To allow nesting of the read-side explicit annotations we explici= tly > > > > keep track of the nesting. lock_is_held() allows us to do that. > > > > > > > > - The wait-side annotation is a write lock, and entirely done withi= n > > > > dma_fence_wait() for everyone by default. > > > > > > > > - To be able to freely annotate helper functions I want to make it = ok > > > > to call dma_fence_begin/end_signalling from soft/hardirq context. > > > > First attempt was using the hardirq locking context for the write > > > > side in lockdep, but this forces all normal spinlocks nested with= in > > > > dma_fence_begin/end_signalling to be spinlocks. That bollocks. > > > > > > > > The approach now is to simple check in_atomic(), and for these ca= ses > > > > entirely rely on the might_sleep() check in dma_fence_wait(). Tha= t > > > > will catch any wrong nesting against spinlocks from soft/hardirq > > > > contexts. > > > > > > > > The idea here is that every code path that's critical for eventuall= y > > > > signalling a dma_fence should be annotated with > > > > dma_fence_begin/end_signalling. The annotation ideally starts right > > > > after a dma_fence is published (added to a dma_resv, exposed as a > > > > sync_file fd, attached to a drm_syncobj fd, or anything else that > > > > makes the dma_fence visible to other kernel threads), up to and > > > > including the dma_fence_wait(). Examples are irq handlers, the > > > > scheduler rt threads, the tail of execbuf (after the corresponding > > > > fences are visible), any workers that end up signalling dma_fences = and > > > > really anything else. Not annotated should be code paths that only > > > > complete fences opportunistically as the gpu progresses, like e.g. > > > > shrinker/eviction code. > > > > > > > > The main class of deadlocks this is supposed to catch are: > > > > > > > > Thread A: > > > > > > > > mutex_lock(A); > > > > mutex_unlock(A); > > > > > > > > dma_fence_signal(); > > > > > > > > Thread B: > > > > > > > > mutex_lock(A); > > > > dma_fence_wait(); > > > > mutex_unlock(A); > > > > > > > > Thread B is blocked on A signalling the fence, but A never gets aro= und > > > > to that because it cannot acquire the lock A. > > > > > > > > Note that dma_fence_wait() is allowed to be nested within > > > > dma_fence_begin/end_signalling sections. To allow this to happen th= e > > > > read lock needs to be upgraded to a write lock, which means that an= y > > > > other lock is acquired between the dma_fence_begin_signalling() cal= l and > > > > the call to dma_fence_wait(), and still held, this will result in a= n > > > > immediate lockdep complaint. The only other option would be to not > > > > annotate such calls, defeating the point. Therefore these annotatio= ns > > > > cannot be sprinkled over the code entirely mindless to avoid false > > > > positives. > > > > > > > > v2: handle soft/hardirq ctx better against write side and dont forg= et > > > > EXPORT_SYMBOL, drivers can't use this otherwise. > > > > > > > > Cc: linux-media@vger.kernel.org > > > > Cc: linaro-mm-sig@lists.linaro.org > > > > Cc: linux-rdma@vger.kernel.org > > > > Cc: amd-gfx@lists.freedesktop.org > > > > Cc: intel-gfx@lists.freedesktop.org > > > > Cc: Chris Wilson > > > > Cc: Maarten Lankhorst > > > > Cc: Christian K=C3=B6nig > > > > Signed-off-by: Daniel Vetter > > > > --- > > > > drivers/dma-buf/dma-fence.c | 53 +++++++++++++++++++++++++++++++++= ++++ > > > > include/linux/dma-fence.h | 12 +++++++++ > > > > 2 files changed, 65 insertions(+) > > > > > > > > diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fenc= e.c > > > > index 6802125349fb..d5c0fd2efc70 100644 > > > > --- a/drivers/dma-buf/dma-fence.c > > > > +++ b/drivers/dma-buf/dma-fence.c > > > > @@ -110,6 +110,52 @@ u64 dma_fence_context_alloc(unsigned num) > > > > } > > > > EXPORT_SYMBOL(dma_fence_context_alloc); > > > > > > > > +#ifdef CONFIG_LOCKDEP > > > > +struct lockdep_map dma_fence_lockdep_map =3D { > > > > + .name =3D "dma_fence_map" > > > > +}; > > > > > > Not another false global sharing lockmap. > > > > It's a global contract, it needs a global lockdep map. And yes a big > > reason for the motivation here is that i915-gem has a tremendous urge t= o > > just redefine all these global locks to fit to some local interpretatio= n > > of what's going on. > > No, you can build the global contract out of the actual contracts > between fence drivers. If you introduce a struct lockdep_map *map into > the fence_ops (so the fence_ops can remain const), you gain correctness > at the cost of having to run through all possible interactions once. > You can also then do if ops->lockmap ?: &global_fence_lockmap for > piecemeal conversion of drivers that do not already use lockmaps for > contract enforcement of their fence waits. I'm not quite sure whether you're actually proposing to have locking contracts per drivers, since that seems rather out of ... I dunno. But if that's what you want, that just doesn't make any sense at all: - Locking is rather core to kernel programming, aside from a few other things like hard/softirq/preempt/... disabled sections and how recursion works for these, or where and what you're allowed to allocate memory. Lockdep, might_sleep and a bunch of other such debug checks help us enforce that. If you instead go with every driver does what they please yolo, then you don't have an abstraction, all you have is smashing a rose and rose and Rose into one thing because they have the same 4 letter name. It's just an interface that can be used only when understanding every single implementation in detail - really not something that's an abstraction. Yes I've seen some of these dubious abstractions in i915, merged fairly recently, that doesn't make them a good idea. - You need to test the full NxN matrix (yes you need to test the driver against itself in this world, since testing against something fake like vgem doesn't cut it). That's nuts. Strike that, that's impossible. - Review is impossible, because the documentation can be summed up as "yolo". Without clear rules all review can do is check every code against every other piece of code, on every change. That's impossible, because we humans are mere mortals, and we're left with push&pray engineering, which really isn't. The other issue with this approach is that it's full on platform problem in extremis. Instead of extending the shared abstraction or adding new useful functionality, i915-gem has resorted to reinpreting rules to fix local problems. That leads to stuff like roughly if (mutex_lock_timeout(HZ*10) =3D=3D -ETIME) { /* I guess we deadlocked, try to bail out */ } except it's for fences. That's neither solid engineering - we don't generally let the kernel deadlock on itself to test whether maybe it was a deadlock or not, nor is this solid upstreaming in a open source project - we fix the problems where they are, not work around them just in our own driver. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch