aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-03-24 10:06:43 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-03-24 10:06:43 -0700
commit2e2d4650b34ffe0a39f70acc9429a58d94e39236 (patch)
tree547082f61a28eda2ddf2ddd71daeaa276fc05e5f /fs/namespace.c
parentMerge tag 'fs.v5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux (diff)
parentfs/namespace: Boost the mount_lock.lock owner instead of spinning on PREEMPT_RT. (diff)
downloadlinux-dev-2e2d4650b34ffe0a39f70acc9429a58d94e39236.tar.xz
linux-dev-2e2d4650b34ffe0a39f70acc9429a58d94e39236.zip
Merge tag 'fs.rt.v5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux
Pull mount attributes PREEMPT_RT update from Christian Brauner: "This contains Sebastian's fix to make changing mount attributes/getting write access compatible with CONFIG_PREEMPT_RT. The change only applies when users explicitly opt-in to real-time via CONFIG_PREEMPT_RT otherwise things are exactly as before. We've waited quite a long time with this to make sure folks could take a good look" * tag 'fs.rt.v5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux: fs/namespace: Boost the mount_lock.lock owner instead of spinning on PREEMPT_RT.
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 627db2e031e9..6e9844b8c6fb 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -344,8 +344,24 @@ int __mnt_want_write(struct vfsmount *m)
* incremented count after it has set MNT_WRITE_HOLD.
*/
smp_mb();
- while (READ_ONCE(mnt->mnt.mnt_flags) & MNT_WRITE_HOLD)
- cpu_relax();
+ might_lock(&mount_lock.lock);
+ while (READ_ONCE(mnt->mnt.mnt_flags) & MNT_WRITE_HOLD) {
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
+ cpu_relax();
+ } else {
+ /*
+ * This prevents priority inversion, if the task
+ * setting MNT_WRITE_HOLD got preempted on a remote
+ * CPU, and it prevents life lock if the task setting
+ * MNT_WRITE_HOLD has a lower priority and is bound to
+ * the same CPU as the task that is spinning here.
+ */
+ preempt_enable();
+ lock_mount_hash();
+ unlock_mount_hash();
+ preempt_disable();
+ }
+ }
/*
* After the slowpath clears MNT_WRITE_HOLD, mnt_is_readonly will
* be set to match its requirements. So we must not load that until