114 lines
2.8 KiB
Diff
114 lines
2.8 KiB
Diff
Subject: fs: dcache: Use cpu_chill() in trylock loops
|
|
From: Thomas Gleixner <tglx@linutronix.de>
|
|
Date: Wed, 07 Mar 2012 21:00:34 +0100
|
|
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/3.10/patches-3.10.10-rt7.tar.xz
|
|
|
|
Retry loops on RT might loop forever when the modifying side was
|
|
preempted. Use cpu_chill() instead of cpu_relax() to let the system
|
|
make progress.
|
|
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
Cc: stable-rt@vger.kernel.org
|
|
---
|
|
fs/autofs4/autofs_i.h | 1 +
|
|
fs/autofs4/expire.c | 2 +-
|
|
fs/dcache.c | 7 ++++---
|
|
fs/namespace.c | 7 ++++---
|
|
4 files changed, 10 insertions(+), 7 deletions(-)
|
|
|
|
--- a/fs/autofs4/autofs_i.h
|
|
+++ b/fs/autofs4/autofs_i.h
|
|
@@ -34,6 +34,7 @@
|
|
#include <linux/sched.h>
|
|
#include <linux/mount.h>
|
|
#include <linux/namei.h>
|
|
+#include <linux/delay.h>
|
|
#include <asm/current.h>
|
|
#include <asm/uaccess.h>
|
|
|
|
--- a/fs/autofs4/expire.c
|
|
+++ b/fs/autofs4/expire.c
|
|
@@ -157,7 +157,7 @@ again:
|
|
parent = p->d_parent;
|
|
if (!spin_trylock(&parent->d_lock)) {
|
|
spin_unlock(&p->d_lock);
|
|
- cpu_relax();
|
|
+ cpu_chill();
|
|
goto relock;
|
|
}
|
|
spin_unlock(&p->d_lock);
|
|
--- a/fs/dcache.c
|
|
+++ b/fs/dcache.c
|
|
@@ -37,6 +37,7 @@
|
|
#include <linux/rculist_bl.h>
|
|
#include <linux/prefetch.h>
|
|
#include <linux/ratelimit.h>
|
|
+#include <linux/delay.h>
|
|
#include "internal.h"
|
|
#include "mount.h"
|
|
|
|
@@ -453,7 +454,7 @@ static inline struct dentry *dentry_kill
|
|
if (inode && !spin_trylock(&inode->i_lock)) {
|
|
relock:
|
|
spin_unlock(&dentry->d_lock);
|
|
- cpu_relax();
|
|
+ cpu_chill();
|
|
return dentry; /* try again with same dentry */
|
|
}
|
|
if (IS_ROOT(dentry))
|
|
@@ -835,7 +836,7 @@ relock:
|
|
|
|
if (!spin_trylock(&dentry->d_lock)) {
|
|
spin_unlock(&dcache_lru_lock);
|
|
- cpu_relax();
|
|
+ cpu_chill();
|
|
goto relock;
|
|
}
|
|
|
|
@@ -2072,7 +2073,7 @@ again:
|
|
if (dentry->d_count == 1) {
|
|
if (!spin_trylock(&inode->i_lock)) {
|
|
spin_unlock(&dentry->d_lock);
|
|
- cpu_relax();
|
|
+ cpu_chill();
|
|
goto again;
|
|
}
|
|
dentry->d_flags &= ~DCACHE_CANT_MOUNT;
|
|
--- a/fs/namespace.c
|
|
+++ b/fs/namespace.c
|
|
@@ -23,6 +23,7 @@
|
|
#include <linux/uaccess.h>
|
|
#include <linux/proc_ns.h>
|
|
#include <linux/magic.h>
|
|
+#include <linux/delay.h>
|
|
#include "pnode.h"
|
|
#include "internal.h"
|
|
|
|
@@ -317,7 +318,7 @@ int __mnt_want_write(struct vfsmount *m)
|
|
smp_mb();
|
|
while (ACCESS_ONCE(mnt->mnt.mnt_flags) & MNT_WRITE_HOLD) {
|
|
preempt_enable();
|
|
- cpu_relax();
|
|
+ cpu_chill();
|
|
preempt_disable();
|
|
}
|
|
/*
|
|
@@ -1289,7 +1290,7 @@ static int do_umount(struct mount *mnt,
|
|
return retval;
|
|
}
|
|
|
|
-/*
|
|
+/*
|
|
* Is the caller allowed to modify his namespace?
|
|
*/
|
|
static inline bool may_mount(void)
|
|
@@ -1717,7 +1718,7 @@ static int do_loopback(struct path *path
|
|
|
|
err = -EINVAL;
|
|
if (mnt_ns_loop(&old_path))
|
|
- goto out;
|
|
+ goto out;
|
|
|
|
mp = lock_mount(path);
|
|
err = PTR_ERR(mp);
|