Received: by 2002:ac0:a874:0:0:0:0:0 with SMTP id c49csp147221ima; Thu, 14 Mar 2019 22:48:30 -0700 (PDT) X-Google-Smtp-Source: APXvYqz71rgfpCqc+R4DoKFpVv0+v9aX0A/BEcWr/89NoGqSjSnIBrvB9DKTwlvnAiip9leVNOM8 X-Received: by 2002:a63:fd12:: with SMTP id d18mr1674781pgh.88.1552628910057; Thu, 14 Mar 2019 22:48:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1552628910; cv=none; d=google.com; s=arc-20160816; b=S1ER5FZT5vjliSCCA9d7vWi1IxvUyRvZ4zQ0xjwspMD4ZuKqLo9Ak28ZyEyFNdvMTZ Y4Z+TdWRbHp9XE1PQ1k6GsmzZcPnpplzQpigFSs9izR5h0QBNBDrFwsJsGdFeiLpDA92 uOxY1h5I+tY9YEjzbAWP0LSU+7dGyJDMDq76qWLlfWE1/KsveGV9iufmPIxzUc4p6xpm upLhnI7dtcdKQWkIqpcJQNLbMMz48BWJVffymjYPPBcWB3745KVqzZKpokCnoSx9RrdO HiUMeh74D10yZwg5WjKYQGGjZAtCIidqKslCMHMmp3fqyeTH0eINDFjiFZq+yEXWQx9L 6YYQ== 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; bh=8sedS4lox7adROasQTx7z9aMd5TcF9H9xOrLR2q9r/s=; b=rzdGSGjl63/tOnz9KTP2npkZJwLbX6HqpIhV7AWp6ydLUqe8zZZEx9+yq3110vXpyz +FQ5K1r08GFeDGJcYfKRm4eSBetZjc0skZGadLEq68TYbxkc7lJG2U3zITs7Eo4zscQ8 RLbfS+v0fHLRI1Urq+L53mqq97XK0x/qz7bIZV4wj/1f3Bvivy6Ju5VN9zUBVClMXTrH 4XcRiysdKSXKo7WGE9m3r6xjc6E0nXMxUK0o63lZFUD65Y0+CoG8/FXp6h3yTo7lmUTr +vBQ2jX5rjw1AtFouQ8KIJ/pGV5AVqaSHTojKq2DoLgEfSIIxlv8XgYm+sgwQp683F2h NWsA== ARC-Authentication-Results: i=1; mx.google.com; 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 p12si904068pls.111.2019.03.14.22.48.15; Thu, 14 Mar 2019 22:48:30 -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; 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 S1728280AbfCOFrY (ORCPT + 99 others); Fri, 15 Mar 2019 01:47:24 -0400 Received: from orcrist.hmeau.com ([104.223.48.154]:51834 "EHLO deadmen.hmeau.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727151AbfCOFrY (ORCPT ); Fri, 15 Mar 2019 01:47:24 -0400 Received: from gondobar.mordor.me.apana.org.au ([192.168.128.4] helo=gondobar) by deadmen.hmeau.com with esmtps (Exim 4.89 #2 (Debian)) id 1h4fgb-0006o9-2K; Fri, 15 Mar 2019 13:47:17 +0800 Received: from herbert by gondobar with local (Exim 4.89) (envelope-from ) id 1h4fgT-0000WW-Rz; Fri, 15 Mar 2019 13:47:09 +0800 Date: Fri, 15 Mar 2019 13:47:09 +0800 From: Herbert Xu To: NeilBrown Cc: Thomas Graf , netdev@vger.kernel.org, "Paul E. McKenney" , linux-kernel@vger.kernel.org Subject: Re: [PATCH 2/3] rhashtable: don't hold lock on first table throughout insertion. Message-ID: <20190315054709.mlcctcv3qy57wini@gondor.apana.org.au> References: <155253979234.5022.1840929790507376038.stgit@noble.brown> <155253992829.5022.17977838545670077984.stgit@noble.brown> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <155253992829.5022.17977838545670077984.stgit@noble.brown> User-Agent: NeoMutt/20170113 (1.7.2) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Mar 14, 2019 at 04:05:28PM +1100, NeilBrown wrote: > rhashtable_try_insert() currently holds a lock on the bucket in > the first table, while also locking buckets in subsequent tables. > This is unnecessary and looks like a hold-over from some earlier > version of the implementation. > > As insert and remove always lock a bucket in each table in turn, and > as insert only inserts in the final table, there cannot be any races > that are not covered by simply locking a bucket in each table in turn. > > When an insert call reaches that last table it can be sure that there > is no matchinf entry in any other table as it has searched them all, and > insertion never happens anywhere but in the last table. The fact that > code tests for the existence of future_tbl while holding a lock on > the relevant bucket ensures that two threads inserting the same key > will make compatible decisions about which is the "last" table. > > This simplifies the code and allows the ->rehash field to be > discarded. > > We still need a way to ensure that a dead bucket_table is never > re-linked by rhashtable_walk_stop(). This can be achieved by calling > call_rcu() inside the locked region, and checking with > rcu_head_after_call_rcu() in rhashtable_walk_stop() to see if the > bucket table is empty and dead. > > Signed-off-by: NeilBrown > --- > include/linux/rhashtable.h | 13 ----------- > lib/rhashtable.c | 50 +++++++++++++------------------------------- > 2 files changed, 15 insertions(+), 48 deletions(-) Thanks! This looks very nice. > @@ -580,36 +583,14 @@ static void *rhashtable_try_insert(struct rhashtable *ht, const void *key, > struct bucket_table *new_tbl; > struct bucket_table *tbl; > unsigned int hash; > - spinlock_t *lock; > void *data; > > - tbl = rcu_dereference(ht->tbl); > - > - /* All insertions must grab the oldest table containing > - * the hashed bucket that is yet to be rehashed. > - */ > - for (;;) { > - hash = rht_head_hashfn(ht, tbl, obj, ht->p); > - lock = rht_bucket_lock(tbl, hash); > - spin_lock_bh(lock); > - > - if (tbl->rehash <= hash) > - break; > - > - spin_unlock_bh(lock); > - tbl = rht_dereference_rcu(tbl->future_tbl, ht); > - } > - > - data = rhashtable_lookup_one(ht, tbl, hash, key, obj); > - new_tbl = rhashtable_insert_one(ht, tbl, hash, obj, data); > - if (PTR_ERR(new_tbl) != -EEXIST) > - data = ERR_CAST(new_tbl); > + new_tbl = rcu_dereference(ht->tbl); > > - while (!IS_ERR_OR_NULL(new_tbl)) { > + do { > tbl = new_tbl; > hash = rht_head_hashfn(ht, tbl, obj, ht->p); > - spin_lock_nested(rht_bucket_lock(tbl, hash), > - SINGLE_DEPTH_NESTING); > + spin_lock(rht_bucket_lock(tbl, hash)); One small problem. I think this needs to be spin_lock_bh. Cheers, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt