Received: by 10.223.185.116 with SMTP id b49csp1984605wrg; Thu, 22 Feb 2018 06:27:27 -0800 (PST) X-Google-Smtp-Source: AH8x2272IVev1BRcB+u3uO5127X8I7HZ9hyM2klu0LLm+QCJ+jBWlqlwQ4miBlMhSbtQ2/l4+4dQ X-Received: by 2002:a17:902:8b88:: with SMTP id ay8-v6mr6800234plb.197.1519309647830; Thu, 22 Feb 2018 06:27:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519309647; cv=none; d=google.com; s=arc-20160816; b=M8daOwogFelqkQUYfgzbXpu3pEF96PHublodetps8jdo7VhP7MNtqNwq5tAJIxMybS v3E4Egi0k+j9bjjzC9B0sqpzVEg0oXkg8vZVey5cOS8F+hboUEpVqR7NnuiGFvlhiy0R nCVvw5lytKeAgX3IGtAhdNFIpcrG98T+OW9QBGXze+NKud2+nbyAUM0jkfIF5gHUT0ni 408+1I+YVEu/DOiCSFgB3Faw9jwzbtf0w3hLwVf4hYxlFuFQx9NavNSIN+gt3D6u8i55 96XFmJPIqZRNhmdrtEZleEv4W7qNJOqr9b9Mp1lHXS2CttoowY/PSO1Fqs4/GAFaslF1 tw8w== 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=mZTrRtHGx2wamhxAdCEeq8dkeyqP/b2eeGBTPOpoJQ0=; b=kKq1SfGlDbJizv1DQ5qO8yYUuShcP0xIfwZQImFl1fAJHgyuOQCt4/ORmOLnnpmvGO Qh2+brnA2O3RoDZeIn7EkUjOAxR7XUR8iMGMTpCiQjw6cdWeiJI6NXvDViIwSEkLwdeN veuel7HEb6UyBDjaVwNccMwcnTm73256AwAgDgYudALJxwvJLc5k+rFPFmjdRAVOxPLr YJZdZ1Ix3lFbmkQeM4cn+V4Y1NKaAEbtMcn+9Jqsh7lX8KqIP1Rc+f6FnjfH69vrzyxc OdINSHHxBj6RiJOE6lSQUCoKggSScroMV21sL4eBbyHxiuL+Xtg7mgv9CBHB77fd6DpH y9/g== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@infradead.org header.s=bombadil.20170209 header.b=ZfRkNqe8; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r7si121869pfg.30.2018.02.22.06.27.12; Thu, 22 Feb 2018 06:27:27 -0800 (PST) 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=fail header.i=@infradead.org header.s=bombadil.20170209 header.b=ZfRkNqe8; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932801AbeBVO0X (ORCPT + 99 others); Thu, 22 Feb 2018 09:26:23 -0500 Received: from bombadil.infradead.org ([198.137.202.133]:56380 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932564AbeBVO0W (ORCPT ); Thu, 22 Feb 2018 09:26:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=In-Reply-To:Content-Type:MIME-Version :References:Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=mZTrRtHGx2wamhxAdCEeq8dkeyqP/b2eeGBTPOpoJQ0=; b=ZfRkNqe8xr2CYlUbVGIKTq2Y4 idgMYOmLoUdbwa9LGaQ95f2lIUmJ+dlKpVeimz5APn+nxzreBA/zQLGuzkI7yUeZSh5Ii0KwPtfa6 TT7viWCXAbwrI9w557NUJOYfbstbPIHU4Qk3Ojeb41hxaooxAlmGH/atQyoX1u35DZsXwqvvBcpgN X3nsE9Is3Uj6g87z+S3B0fAhr4OtuG4Zs+YE3Q3MrUB78tb0k/N//q6vhcuL64y4PXCoL6NCB0txb ch9JzH5BOYADiDIYuHZjKpQAbklq2QbtB6D4EbVaC+WxlXv0NeTC81GVtIrWON0mr4iGiedNUGgBR VW0ds7Tww==; Received: from j217100.upc-j.chello.nl ([24.132.217.100] helo=hirez.programming.kicks-ass.net) by bombadil.infradead.org with esmtpsa (Exim 4.89 #1 (Red Hat Linux)) id 1eorpA-0001F9-L9; Thu, 22 Feb 2018 14:26:17 +0000 Received: by hirez.programming.kicks-ass.net (Postfix, from userid 1000) id 13C1F2029FA04; Thu, 22 Feb 2018 15:26:14 +0100 (CET) Date: Thu, 22 Feb 2018 15:26:14 +0100 From: Peter Zijlstra To: Boqun Feng Cc: linux-kernel@vger.kernel.org, Ingo Molnar , Andrea Parri Subject: Re: [RFC tip/locking/lockdep v5 05/17] lockdep: Extend __bfs() to work with multiple kinds of dependencies Message-ID: <20180222142614.GR25201@hirez.programming.kicks-ass.net> References: <20180222070904.548-1-boqun.feng@gmail.com> <20180222070904.548-6-boqun.feng@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180222070904.548-6-boqun.feng@gmail.com> User-Agent: Mutt/1.9.2 (2017-12-15) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Feb 22, 2018 at 03:08:52PM +0800, Boqun Feng wrote: > Now we have four kinds of dependencies in the dependency graph, and not > all the pathes carry strong dependencies, for example: > > Given lock A, B, C, if we have: > > CPU1 CPU2 > ============= ============== > write_lock(A); read_lock(B); > read_lock(B); write_lock(C); > > then we have dependencies A--(NR)-->B, and B--(RN)-->C, (NR and > RN are to indicate the dependency kind), A actually doesn't have > strong dependency to C(IOW, C doesn't depend on A), to see this, ^ missing space You're fairly consistent with not putting spaces before opening braces in text, please don't do this, this is not a C function call. Also double check all your braces are matched, IIRC there's at least one that isn't closed in the previous patches. > let's say we have a third CPU3 doing: > > CPU3: > ============= > write_lock(C); > write_lock(A); > > , this is not a deadlock. However if we change the read_lock() > on CPU2 to a write_lock(), it's a deadlock then. > > So A --(NR)--> B --(RN)--> C is not a strong dependency path but > A --(NR)--> B --(NN)-->C is a strong dependency path. I'm not really satisfied with the above reasoning. I don't disagree, but if possible it would be nice to have something a little more solid. > We can generalize this as: If a path of dependencies doesn't have two > adjacent dependencies as (*R)--L-->(R*), where L is some lock, it is a > strong dependency path, otherwise it's not. > > Now our mission is to make __bfs() traverse only the strong dependency > paths, which is simple: we record whether we have -(*R)-> at the current > tail of the path in lock_list::is_rr, and whenever we pick a dependency > in the traverse, we 1) make sure we don't pick a -(R*)-> dependency if > our current tail is -(*R)-> and 2) greedily pick a -(*N)-> as hard as > possible. > > With this extension for __bfs(), we now need to initialize the root of > __bfs() properly(with a correct ->is_rr), to do so, we introduce some ^ another missing space Also, I don't like is_rr as a name, have_xr might be better. Only if we combine *R with R* do we have RR. > +/* > + * return -1 if no proper dependency could be picked > + * return 0 if a -(*N)-> dependency could be picked > + * return 1 if only a -(*R)-> dependency could be picked > + * > + * N: non-recursive lock > + * R: recursive read lock > + */ > +static inline int pick_dep(u16 is_rr, u16 cap_dep) > +{ > + if (is_rr) { /* could only pick -(N*)-> */ > + if (cap_dep & DEP_NN_MASK) > + return 0; > + else if (cap_dep & DEP_NR_MASK) > + return 1; > + else > + return -1; > + } else { > + if (cap_dep & DEP_NN_MASK || cap_dep & DEP_RN_MASK) if (cap_dep & (DEP_NN_MASK | DEP_RN_MASK)) > + return 0; > + else > + return 1; > + } > +} However, I would suggest: static inline bool is_xr(u16 dep) { return !!(dep & (DEP_NR_MASK | DEP_RR_MASK)); } static inline bool is_rx(u16 dep) { return !!(dep & (DEP_RN_MASK | DEP_RR_MASK)); } > @@ -1095,11 +1179,18 @@ static enum bfs_result __bfs(struct lock_list *source_entry, > else > head = &lock->class->locks_before; > > + is_rr = lock->is_rr; > + > DEBUG_LOCKS_WARN_ON(!irqs_disabled()); > > list_for_each_entry_rcu(entry, head, entry) { > unsigned int cq_depth; > > + next_is_rr = pick_dep(is_rr, entry->dep); > + if (next_is_rr < 0) > + continue; > + entry->is_rr = next_is_rr; /* Skip *R -> R* relations */ if (have_xr && is_rx(entry->dep)) continue; entry->have_xr = is_xr(entry->dep); Which to me is a much simpler construct, hmm? > + > visit_lock_entry(entry, lock); > if (match(entry, data)) { > *target_entry = entry;