From: Al Viro <viro@ZenIV.linux.org.uk>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: LKML <linux-kernel@vger.kernel.org>,
Linus Torvalds <torvalds@osdl.org>, Ingo Molnar <mingo@elte.hu>,
Peter Zijlstra <peterz@infradead.org>,
Nick Piggin <npiggin@kernel.dk>
Subject: Re: [patch 0/5] seqlock consolidation
Date: Thu, 15 Mar 2012 18:39:40 +0000 [thread overview]
Message-ID: <20120315183940.GE8943@ZenIV.linux.org.uk> (raw)
In-Reply-To: <alpine.LFD.2.02.1203151854110.2466@ionos>
On Thu, Mar 15, 2012 at 06:55:18PM +0100, Thomas Gleixner wrote:
> > If that's it, I suggest to look for a solution that would express just that...
> > Or do you want something on the reader side as well?
>
> The problem is the reader side. If the reader preempts the writer then
> the only way to make progress is to take the lock, but therefor I need
> to know which lock I should take.
So just make writers non-preemptable in those sections. Really, the
worst non-deterministic behaviour you get for d_seq ones is memcpy()
of up to ->d_name.len bytes. And on the fs_struct side it's trivial
to reduce the work done in those sections to several comparisons and
assignments. Not even path_get_longterm() needs to be there - see
below for how it can be done:
diff --git a/fs/fs_struct.c b/fs/fs_struct.c
index 78b519c..f5818c4 100644
--- a/fs/fs_struct.c
+++ b/fs/fs_struct.c
@@ -26,11 +26,11 @@ void set_fs_root(struct fs_struct *fs, struct path *path)
{
struct path old_root;
+ path_get_longterm(path);
spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq);
old_root = fs->root;
fs->root = *path;
- path_get_longterm(path);
write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
if (old_root.dentry)
@@ -45,11 +45,11 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
{
struct path old_pwd;
+ path_get_longterm(path);
spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq);
old_pwd = fs->pwd;
fs->pwd = *path;
- path_get_longterm(path);
write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
@@ -57,6 +57,14 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
path_put_longterm(&old_pwd);
}
+static inline int replace_path(struct path *p, const struct path *old, const struct path *new)
+{
+ if (likely(p->dentry != old->dentry || p->mnt != old->mnt))
+ return 0;
+ *p = *new;
+ return 1;
+}
+
void chroot_fs_refs(struct path *old_root, struct path *new_root)
{
struct task_struct *g, *p;
@@ -68,21 +76,16 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root)
task_lock(p);
fs = p->fs;
if (fs) {
+ int hits = 0;
spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq);
- if (fs->root.dentry == old_root->dentry
- && fs->root.mnt == old_root->mnt) {
- path_get_longterm(new_root);
- fs->root = *new_root;
+ hits += replace_path(&fs->root, old_root, new_root);
+ hits += replace_path(&fs->pwd, old_root, new_root);
+ write_seqcount_end(&fs->seq);
+ while (hits--) {
count++;
- }
- if (fs->pwd.dentry == old_root->dentry
- && fs->pwd.mnt == old_root->mnt) {
path_get_longterm(new_root);
- fs->pwd = *new_root;
- count++;
}
- write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
}
task_unlock(p);
next prev parent reply other threads:[~2012-03-15 18:39 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-15 11:44 [patch 0/5] seqlock consolidation Thomas Gleixner
2012-03-15 11:44 ` [patch 1/5] seqlock: Remove unused functions Thomas Gleixner
2012-03-15 16:29 ` Linus Torvalds
2012-03-15 17:39 ` Al Viro
2012-03-15 17:53 ` Thomas Gleixner
2012-03-15 11:44 ` [patch 3/5] seqlock: Provide seq_spin_* functions Thomas Gleixner
2012-03-15 11:44 ` [patch 2/5] seqlock: Use seqcount for seqlock Thomas Gleixner
2012-03-15 11:44 ` [patch 4/5] fs: fs_struct use seqlock Thomas Gleixner
2012-03-15 11:44 ` [patch 5/5] fs: Use seqlock in struct dentry Thomas Gleixner
2012-03-15 12:21 ` [patch 0/5] seqlock consolidation Al Viro
2012-03-15 12:28 ` Thomas Gleixner
2012-03-15 17:43 ` Al Viro
2012-03-15 17:55 ` Thomas Gleixner
2012-03-15 18:39 ` Al Viro [this message]
2012-03-15 19:17 ` Thomas Gleixner
2012-03-15 20:42 ` Al Viro
2012-03-15 22:08 ` Thomas Gleixner
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=20120315183940.GE8943@ZenIV.linux.org.uk \
--to=viro@zeniv.linux.org.uk \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=npiggin@kernel.dk \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=torvalds@osdl.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox