diff options
author | Nick Piggin <npiggin@suse.de> | 2010-01-29 15:38:19 -0800 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-04-27 17:32:28 +0200 |
commit | cab5e5bb352fe4426bb255fbc09d866426cc6dd8 (patch) | |
tree | 243702d5f6cc9d65c832e2f3916e78761dfd2ff2 /include | |
parent | f0a176c5482950a40ac31113816b981d4fe6069c (diff) | |
download | lwn-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.h | 33 |
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); |