All of lore.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@ZenIV.linux.org.uk>
To: "J. R. Okajima" <hooanon05g@gmail.com>
Cc: linux-fsdevel@vger.kernel.org
Subject: Re: Q. hlist_bl_add_head_rcu() in d_alloc_parallel()
Date: Fri, 17 Jun 2016 23:16:14 +0100	[thread overview]
Message-ID: <20160617221614.GE14480@ZenIV.linux.org.uk> (raw)
In-Reply-To: <13136.1466196630@jrobl>

On Sat, Jun 18, 2016 at 05:50:30AM +0900, J. R. Okajima wrote:
> 	hlist_bl_lock(b);
> 	rcu_read_unlock();
> 	hlist_bl_for_each_entry(dentry, node, b, d_u.d_in_lookup_hash) {
> 		if (!matched_dentry_found)
> 			continue;
> 		dget(dentry);
> 		hlist_bl_unlock(b);
> 		return dentry;
> 	}
> 	hlist_bl_add_head_rcu(&new->d_u.d_in_lookup_hash, b);
> 	hlist_bl_unlock(b);
> 	return new;
> }

> When two processes try opening a single existing file and enters
> d_alloc_parallel() at the same time, only one process wins and should
> succeeds hlist_bl_add_head_rcu(). The other process should find the
> dentry in d_u.d_in_lookup_hash and return 'dentry' (instead of
> 'new'). Am I right?
> 
> My question is when will 'new' be added into d_u.d_in_lookup_hash?

You've quoted it yourself:
> 	hlist_bl_add_head_rcu(&new->d_u.d_in_lookup_hash, b);

> It should be between these two lines, I guess.
> 	rcu_read_unlock();
> 	hlist_bl_for_each_entry(dentry, node, b, d_u.d_in_lookup_hash) {
> But can it surely happen?
> If 'new' is not added here because someone else is in rcu_read_lock
> region or other reason, then both processes will add the same named but
> different dentry?

Huh?  If you have two processes reaching that insertion into the in-lookup
hash, whoever gets the hlist_bl_lock() first wins; the loser will find
the instance added by the winner and bugger off with it.  RCU is completely
unrelated to that.  It's about the search in *primary* hash.
 
> Is it better to change the lock/unlock-order like this?
> 
> 	rcu_read_unlock();
> 	rcu_barrier();
> 	hlist_bl_lock(b);
> 	hlist_bl_for_each_entry(dentry, node, b, d_u.d_in_lookup_hash) {

No.  We need to verify that nothing had been transferred from in-lookup to
primary hash after we'd found no match in the primary.  That's what the
->i_dir_seq check is about, and it has to be done after we'd locked the
in-lookup hash chain.  We could drop rcu_read_lock before locking the
chain, but this way we make sure we won't get preempted between fetching
the ->i_dir_seq and checking if it had been changed.  The last thing we
want is rcu_barrier() - WTF for?  To get an extra chance of something
being moved from in-lookup to primary, forcing us to repeat the primary
hash lookup?

We are *NOT* modifying the primary hash in d_alloc_parallel().  At all.
With respect to the primary hash it's a pure reader.  And in-lookup hash
is only accessed under hlist_bl_lock() on its chains - no RCU accesses to
that one.

  reply	other threads:[~2016-06-17 22:16 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-17 20:50 Q. hlist_bl_add_head_rcu() in d_alloc_parallel() J. R. Okajima
2016-06-17 22:16 ` Al Viro [this message]
2016-06-17 22:56   ` Al Viro
2016-06-19  5:24   ` J. R. Okajima
2016-06-19 16:55     ` Al Viro
2016-06-20  4:34       ` J. R. Okajima
2016-06-20  5:35         ` Al Viro
2016-06-20 14:51           ` Al Viro
2016-06-20 17:14             ` [git pull] vfs fixes Al Viro
2016-06-23  1:19           ` Q. hlist_bl_add_head_rcu() in d_alloc_parallel() J. R. Okajima
2016-06-23  2:58             ` Al Viro
2016-06-24  5:57               ` Linus Torvalds
2016-06-25 22:54                 ` Al Viro
2016-06-26  1:25                   ` Linus Torvalds
2016-06-29  8:17                     ` Al Viro
2016-06-29  9:22                       ` Hekuang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160617221614.GE14480@ZenIV.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=hooanon05g@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.