summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2010-01-29 15:38:19 -0800
committerThomas Gleixner <tglx@linutronix.de>2010-04-27 17:32:28 +0200
commitcab5e5bb352fe4426bb255fbc09d866426cc6dd8 (patch)
tree243702d5f6cc9d65c832e2f3916e78761dfd2ff2 /include
parentf0a176c5482950a40ac31113816b981d4fe6069c (diff)
downloadlwn-cab5e5bb352fe4426bb255fbc09d866426cc6dd8.tar.gz
lwn-cab5e5bb352fe4426bb255fbc09d866426cc6dd8.zip
fs-mntget-scale
Improve scalability of mntget/mntput by using per-cpu counters protected by the reader side of the brlock vfsmount_lock. mnt_mounted keeps track of whether the vfsmount is actually attached to the tree so we can shortcut expensive checks in mntput. XXX: count_mnt_count needs write lock. Document this and/or revisit locking (eg. look at writers count) Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: John Stultz <johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include')
-rw-r--r--include/linux/mount.h33
1 files changed, 12 insertions, 21 deletions
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 75c94a59c0b1..7e3194e6bdb5 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -56,20 +56,20 @@ struct vfsmount {
struct mnt_namespace *mnt_ns; /* containing namespace */
int mnt_id; /* mount identifier */
int mnt_group_id; /* peer group identifier */
- /*
- * We put mnt_count & mnt_expiry_mark at the end of struct vfsmount
- * to let these frequently modified fields in a separate cache line
- * (so that reads of mnt_flags wont ping-pong on SMP machines)
- */
- atomic_t mnt_count;
int mnt_expiry_mark; /* true if marked for expiry */
int mnt_pinned;
int mnt_ghosts;
+ int mnt_mounted;
#ifdef CONFIG_SMP
int *mnt_writers;
#else
int mnt_writers;
#endif
+#ifdef CONFIG_SMP
+ int *mnt_count;
+#else
+ int mnt_count;
+#endif
};
static inline int *get_mnt_writers_ptr(struct vfsmount *mnt)
@@ -81,13 +81,6 @@ static inline int *get_mnt_writers_ptr(struct vfsmount *mnt)
#endif
}
-static inline struct vfsmount *mntget(struct vfsmount *mnt)
-{
- if (mnt)
- atomic_inc(&mnt->mnt_count);
- return mnt;
-}
-
struct file; /* forward dec */
extern void vfsmount_read_lock(void);
@@ -95,23 +88,21 @@ extern void vfsmount_read_unlock(void);
extern void vfsmount_write_lock(void);
extern void vfsmount_write_unlock(void);
+extern unsigned int count_mnt_count(struct vfsmount *mnt);
+
extern int mnt_want_write(struct vfsmount *mnt);
extern int mnt_want_write_file(struct file *file);
extern int mnt_clone_write(struct vfsmount *mnt);
extern void mnt_drop_write(struct vfsmount *mnt);
+
extern void mntput_no_expire(struct vfsmount *mnt);
+extern struct vfsmount *mntget(struct vfsmount *mnt);
+extern void mntput(struct vfsmount *mnt);
+
extern void mnt_pin(struct vfsmount *mnt);
extern void mnt_unpin(struct vfsmount *mnt);
extern int __mnt_is_readonly(struct vfsmount *mnt);
-static inline void mntput(struct vfsmount *mnt)
-{
- if (mnt) {
- mnt->mnt_expiry_mark = 0;
- mntput_no_expire(mnt);
- }
-}
-
extern struct vfsmount *do_kern_mount(const char *fstype, int flags,
const char *name, void *data);