Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp2834079imm; Thu, 24 May 2018 17:10:44 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrjyqhyrI/dnzZqk03gpOKt3mLv+bKExqYy+JwStKCsdtc5lRKbIjDcSsTYXH1xTXqx9VFa X-Received: by 2002:a63:735e:: with SMTP id d30-v6mr152515pgn.24.1527207043959; Thu, 24 May 2018 17:10:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527207043; cv=none; d=google.com; s=arc-20160816; b=cH70Tk1r91DxBd5Usik15BbYfau9WWKp5wIKf1jisi4lQvA85lm9NyZ5OE4j5LAuKY DLGQPauF1giQqDx+WDcjJzMFmgY9JpEc0oTF5N7HT2G4t+hnNVtWOfw0lzMqP9OMeDWN g2TdmOLxPEw+gxpg8encnVWAnSYXKhRu4DzCk1UjqlZutLjkD+VSy+zJbkXqpiGwufg+ CJnfv53UmQLRy+LOMkiQidJpBA4GpiBA2ukja3V08OV6QeL6fWOoJ1iivfmD+h0e4wsy ubOv0rt7Pg9z+Dq93biRAhy6MytoLz6HliVK9qHU0+3Grkx7Sb+VvOQc0Dffs5xLygG1 ceGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature:arc-authentication-results; bh=JTqR4acGOYMaaWDdvGY0bNIhVBZs/Xqujv8kYYmqyjw=; b=B3BRR6+p0FuM6HI8l38dBuwxXvmaoFHc2e1f9l+ANK8E/dt4htM5bs7mlaSRT98YTz kc+BBYIXNxxKTRLNlW/LPtkCuPwbzG3i1kavxzJiBAc4PdNC3DlZVMF1jQMOc4tRzviB 4ruQOvPT3/s5cWiixZj9QruxSknahLTB1UL6mu38XB7teAezTPfll/ck/EmwXUHsSC1x lR7Ru6wGtmwwAuEj3iqHgxI5YrWBMPkEw8u0gMjC1KCbjD35zGSxsnFBARqksR1UmY5J iqd0SZ21KcPMEoutKUZFGzIwF68z3ThLc6TjoCcLCzecJtpRaemlnMmdVMsp/AOHey+E WXdw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Lkj1sL9G; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v1-v6si17155749pgr.30.2018.05.24.17.10.04; Thu, 24 May 2018 17:10:43 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Lkj1sL9G; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S969866AbeEXNwW (ORCPT + 99 others); Thu, 24 May 2018 09:52:22 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:52464 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S966066AbeEXNwT (ORCPT ); Thu, 24 May 2018 09:52:19 -0400 Received: by mail-wm0-f66.google.com with SMTP id w194-v6so5339572wmf.2 for ; Thu, 24 May 2018 06:52:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=JTqR4acGOYMaaWDdvGY0bNIhVBZs/Xqujv8kYYmqyjw=; b=Lkj1sL9Gw2bN+w/cxNhSAFgc9CSJPgFG9tUe0iMeyFrxz9ZAFyyWVVx3sXu2kh5Q9I ltUyg4LxoD/cFffAU7Qx+zNdD+YFZzkUvxSD+FcE3nmknJ2eoxXhKYQeM3+alp75hJlW LRArHCcYNJEKTd70LcHXP/ZVbHIBaOhkdgtkvWz/rmDVz5zDvqhWv9gWYqm0uI/CbkBp lNxz4ih3M+zyE/MeV7+hm3wLyE/Lf1xxBxyGdLcQ1msHWPWgZ0tw1LHqfH92TxO3InxW y2gNPWcf2cLwH21KcZNwvmbjEdX5CvC+kLp1fVgb8csIQzGXKM5HwnN33Dhy5ZgtBZtT Fccw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=JTqR4acGOYMaaWDdvGY0bNIhVBZs/Xqujv8kYYmqyjw=; b=XuMfDqzxWj/hRCrOJC5sdHg6d7ZLiitEmePmTvbcXLHqqGiUaMVOhgiKhXSxEf87QF 48SO/sA6YuNv0DpT0oVjHdZ9Moj0xRqzGsNK0ysMem5rOfL7puXSNRG7c/3PaOZj1Qq1 QJfhIHsoZweiuJyFRYHje1MktVg1fgombgE2B0UolSOjg3HB/oTUZUIzbuDdaPo22Xmx GtZOtKxEWev68ZRWRqEVcXXb2zjdpPObIsBebFniGT3aXWjOO6DwFa3wVCo9mCToKG41 XT9aNiM+VBWAQRMBpC55neHNGdMBhqAPslV3Z32Oi96qyJh6UaZPdYuuc1Zq/zJhzCg0 UrEg== X-Gm-Message-State: ALKqPwfPUYmfl/0GrwgxAsVuIZp85N6ttV9pWs31fGUUk4v2SLC+Nwdd aS4MdCLEdAVW3kgU9M4fXik= X-Received: by 2002:a50:8a8b:: with SMTP id j11-v6mr12326300edj.36.1527169937752; Thu, 24 May 2018 06:52:17 -0700 (PDT) Received: from auth2-smtp.messagingengine.com (auth2-smtp.messagingengine.com. [66.111.4.228]) by smtp.gmail.com with ESMTPSA id o47-v6sm11851059edc.95.2018.05.24.06.52.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 24 May 2018 06:52:16 -0700 (PDT) Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailauth.nyi.internal (Postfix) with ESMTP id B1BF321DA9; Thu, 24 May 2018 09:52:12 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Thu, 24 May 2018 09:52:12 -0400 X-ME-Sender: Received: from localhost (unknown [45.32.128.109]) by mail.messagingengine.com (Postfix) with ESMTPA id 0CD59E4118; Thu, 24 May 2018 09:52:12 -0400 (EDT) Date: Thu, 24 May 2018 21:51:58 +0800 From: Boqun Feng To: Will Deacon Cc: Linus Torvalds , psodagud@codeaurora.org, Kees Cook , Andy Lutomirski , Will Drewry , Andrew Morton , Rik van Riel , Thomas Gleixner , Ingo Molnar , Peter Zijlstra , Eric Biggers , Frederic Weisbecker , sherryy@android.com, Vegard Nossum , Christoph Lameter , Andrea Arcangeli , Sasha Levin , Linux Kernel Mailing List Subject: Re: write_lock_irq(&tasklist_lock) Message-ID: <20180524135158.GA19987@tardis> References: <0879f797135033e05e8e9166a3c85628@codeaurora.org> <20180523130547.GF26965@arm.com> <20180523153607.GD2983@arm.com> <20180524124928.GH8689@arm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180524124928.GH8689@arm.com> User-Agent: Mutt/1.9.4 (2018-02-28) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, May 24, 2018 at 01:49:31PM +0100, Will Deacon wrote: > On Wed, May 23, 2018 at 09:26:35AM -0700, Linus Torvalds wrote: > > On Wed, May 23, 2018 at 8:35 AM Will Deacon wrote: > > > > > In other words, qrwlock requires consistent locking order wrt spinlocks. > > > > I *thought* lockdep already tracked and detected this. Or is that only with > > with the sleeping versions? > > There are patches in-flight to detect this: > > https://marc.info/?l=linux-kernel&m=152483640529740&w=2k > > as part of Boqun's work into recursive read locking. > Yeah, lemme put some details here: So we have three cases: Case #1 (from Will) P0: P1: P2: spin_lock(&slock) read_lock(&rwlock) write_lock(&rwlock) read_lock(&rwlock) spin_lock(&slock) , which is a deadlock, and couldn't not be detected by lockdep yet. And lockdep could detect this with the patch I attach at the end of the mail. Case #2 P0: P1: P2: spin_lock(&slock) read_lock(&rwlock) write_lock(&rwlock) read_lock(&rwlock) spin_lock_irq(&slock) , which is not a deadlock, as the read_lock() on P0 can use the unfair fastpass. Case #3 P0: P1: P2: spin_lock_irq(&slock) read_lock(&rwlock) write_lock_irq(&rwlock) read_lock(&rwlock) spin_lock(&slock) , which is a deadlock, as the read_lock() on P0 cannot use the fastpass. To detect this and not to make case #2 as a false positive, the recursive deadlock detection patchset is needed, the WIP version is at: git://git.kernel.org/pub/scm/linux/kernel/git/boqun/linux.git arr-rfc-wip The code is done, I'm just working on the rework for documention stuff, so if anyone is interested, could try it out ;-) Regards, Boqun ------------------->8 Subject: [PATCH] locking: More accurate annotations for read_lock() On the archs using QUEUED_RWLOCKS, read_lock() is not always a recursive read lock, actually it's only recursive if in_interrupt() is true. So change the annotation accordingly to catch more deadlocks. Note we used to treat read_lock() as pure recursive read locks in lib/locking-seftest.c, and this is useful, especially for the lockdep development selftest, so we keep this via a variable to force switching lock annotation for read_lock(). Signed-off-by: Boqun Feng --- include/linux/lockdep.h | 35 ++++++++++++++++++++++++++++++++++- lib/locking-selftest.c | 11 +++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 6fc77d4dbdcd..07793986c063 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -27,6 +27,7 @@ extern int lock_stat; #include #include #include +#include /* * We'd rather not expose kernel/lockdep_states.h this wide, but we do need @@ -540,6 +541,31 @@ static inline void print_irqtrace_events(struct task_struct *curr) } #endif +/* Variable used to make lockdep treat read_lock() as recursive in selftests */ +#ifdef CONFIG_DEBUG_LOCKING_API_SELFTESTS +extern unsigned int force_read_lock_recursive; +#else /* CONFIG_DEBUG_LOCKING_API_SELFTESTS */ +#define force_read_lock_recursive 0 +#endif /* CONFIG_DEBUG_LOCKING_API_SELFTESTS */ + +#ifdef CONFIG_LOCKDEP +/* + * read_lock() is recursive if: + * 1. We force lockdep think this way in selftests or + * 2. The implementation is not queued read/write lock or + * 3. The locker is at an in_interrupt() context. + */ +static inline bool read_lock_is_recursive(void) +{ + return force_read_lock_recursive || + !IS_ENABLED(CONFIG_QUEUED_RWLOCKS) || + in_interrupt(); +} +#else /* CONFIG_LOCKDEP */ +/* If !LOCKDEP, the value is meaningless */ +#define read_lock_is_recursive() 0 +#endif + /* * For trivial one-depth nesting of a lock-class, the following * global define can be used. (Subsystems with multiple levels @@ -561,7 +587,14 @@ static inline void print_irqtrace_events(struct task_struct *curr) #define spin_release(l, n, i) lock_release(l, n, i) #define rwlock_acquire(l, s, t, i) lock_acquire_exclusive(l, s, t, NULL, i) -#define rwlock_acquire_read(l, s, t, i) lock_acquire_shared_recursive(l, s, t, NULL, i) +#define rwlock_acquire_read(l, s, t, i) \ +do { \ + if (read_lock_is_recursive()) \ + lock_acquire_shared_recursive(l, s, t, NULL, i); \ + else \ + lock_acquire_shared(l, s, t, NULL, i); \ +} while (0) + #define rwlock_release(l, n, i) lock_release(l, n, i) #define seqcount_acquire(l, s, t, i) lock_acquire_exclusive(l, s, t, NULL, i) diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index b5c1293ce147..dd92f8ad83d5 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c @@ -28,6 +28,7 @@ * Change this to 1 if you want to see the failure printouts: */ static unsigned int debug_locks_verbose; +unsigned int force_read_lock_recursive; static DEFINE_WW_CLASS(ww_lockdep); @@ -1978,6 +1979,11 @@ void locking_selftest(void) return; } + /* + * treats read_lock() as recursive read locks for testing purpose + */ + force_read_lock_recursive = 1; + /* * Run the testsuite: */ @@ -2072,6 +2078,11 @@ void locking_selftest(void) ww_tests(); + force_read_lock_recursive = 0; + /* + * queued_read_lock() specific test cases can be put here + */ + if (unexpected_testcase_failures) { printk("-----------------------------------------------------------------\n"); debug_locks = 0; -- 2.16.2