fs/file_table.c | 2 +- fs/internal.h | 2 +- fs/locks.c | 2 +- include/linux/lglock.h | 29 ++++++++++++----------------- kernel/lglock.c | 46 ++++++++++++++++++++++++++-------------------- 5 files changed, 41 insertions(+), 40 deletions(-) diff --git a/fs/file_table.c b/fs/file_table.c index b44e4c559786..e0bee9e05db9 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -36,7 +36,7 @@ struct files_stat_struct files_stat = { .max_files = NR_FILE }; -DEFINE_STATIC_LGLOCK(files_lglock); +static DEFINE_LGLOCK(files_lglock); /* SLAB cache for file structures */ static struct kmem_cache *filp_cachep __read_mostly; diff --git a/fs/internal.h b/fs/internal.h index 7c5f01cf619d..2db5882d77b2 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -59,7 +59,7 @@ extern int sb_prepare_remount_readonly(struct super_block *); extern void __init mnt_init(void); -extern struct lglock vfsmount_lock; +DECLARE_LGLOCK(vfsmount_lock); extern int __mnt_want_write(struct vfsmount *); extern int __mnt_want_write_file(struct file *); diff --git a/fs/locks.c b/fs/locks.c index b27a3005d78d..4b4704aee6c6 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -162,7 +162,7 @@ int lease_break_time = 45; * the file_lock_lglock. Note that alterations to the list also require that * the relevant i_lock is held. */ -DEFINE_STATIC_LGLOCK(file_lock_lglock); +static DEFINE_LGLOCK(file_lock_lglock); static DEFINE_PER_CPU(struct hlist_head, file_lock_list); /* diff --git a/include/linux/lglock.h b/include/linux/lglock.h index 0d24e932db0b..232de2c46208 100644 --- a/include/linux/lglock.h +++ b/include/linux/lglock.h @@ -42,29 +42,24 @@ #endif struct lglock { - arch_spinlock_t __percpu *lock; + arch_spinlock_t lock; #ifdef CONFIG_DEBUG_LOCK_ALLOC struct lock_class_key lock_key; struct lockdep_map lock_dep_map; #endif }; -#define DEFINE_LGLOCK(name) \ - static DEFINE_PER_CPU(arch_spinlock_t, name ## _lock) \ - = __ARCH_SPIN_LOCK_UNLOCKED; \ - struct lglock name = { .lock = &name ## _lock } +#define DECLARE_LGLOCK(name) \ + DECLARE_PER_CPU(struct lglock, name) +#define DEFINE_LGLOCK(name) \ + DEFINE_PER_CPU(struct lglock, name) = { .lock = __ARCH_SPIN_LOCK_UNLOCKED } -#define DEFINE_STATIC_LGLOCK(name) \ - static DEFINE_PER_CPU(arch_spinlock_t, name ## _lock) \ - = __ARCH_SPIN_LOCK_UNLOCKED; \ - static struct lglock name = { .lock = &name ## _lock } - -void lg_lock_init(struct lglock *lg, char *name); -void lg_local_lock(struct lglock *lg); -void lg_local_unlock(struct lglock *lg); -void lg_local_lock_cpu(struct lglock *lg, int cpu); -void lg_local_unlock_cpu(struct lglock *lg, int cpu); -void lg_global_lock(struct lglock *lg); -void lg_global_unlock(struct lglock *lg); +void lg_lock_init(struct lglock __percpu *lg, char *name); +void lg_local_lock(struct lglock __percpu *lg); +void lg_local_unlock(struct lglock __percpu *lg); +void lg_local_lock_cpu(struct lglock __percpu *lg, int cpu); +void lg_local_unlock_cpu(struct lglock __percpu *lg, int cpu); +void lg_global_lock(struct lglock __percpu *lg); +void lg_global_unlock(struct lglock __percpu *lg); #endif diff --git a/kernel/lglock.c b/kernel/lglock.c index 6535a667a5a7..a9e327ba89e6 100644 --- a/kernel/lglock.c +++ b/kernel/lglock.c @@ -4,84 +4,90 @@ #include #include +/* We only fill in the name and lock_dep_map for the first CPU */ +#define lg_lock_dep_map(lg) \ + per_cpu_ptr(&lg->lock_dep_map,0) +#define lg_lock_key(lg) \ + per_cpu_ptr(&lg->lock_key,0) + /* * Note there is no uninit, so lglocks cannot be defined in * modules (but it's fine to use them from there) * Could be added though, just undo lg_lock_init */ -void lg_lock_init(struct lglock *lg, char *name) +void lg_lock_init(struct lglock __percpu *lg, char *name) { - LOCKDEP_INIT_MAP(&lg->lock_dep_map, name, &lg->lock_key, 0); + LOCKDEP_INIT_MAP(lg_lock_dep_map(lg), name, lg_lock_key(lg), 0); } EXPORT_SYMBOL(lg_lock_init); -void lg_local_lock(struct lglock *lg) +void lg_local_lock(struct lglock __percpu *lg) { arch_spinlock_t *lock; preempt_disable(); - rwlock_acquire_read(&lg->lock_dep_map, 0, 0, _RET_IP_); - lock = this_cpu_ptr(lg->lock); + rwlock_acquire_read(lg_lock_dep_map(lg), 0, 0, _RET_IP_); + lock = this_cpu_ptr(&lg->lock); arch_spin_lock(lock); } EXPORT_SYMBOL(lg_local_lock); -void lg_local_unlock(struct lglock *lg) +void lg_local_unlock(struct lglock __percpu *lg) { arch_spinlock_t *lock; - rwlock_release(&lg->lock_dep_map, 1, _RET_IP_); - lock = this_cpu_ptr(lg->lock); + rwlock_release(lg_lock_dep_map(lg), 1, _RET_IP_); + lock = this_cpu_ptr(&lg->lock); arch_spin_unlock(lock); preempt_enable(); } EXPORT_SYMBOL(lg_local_unlock); -void lg_local_lock_cpu(struct lglock *lg, int cpu) +void lg_local_lock_cpu(struct lglock __percpu *lg, int cpu) { arch_spinlock_t *lock; preempt_disable(); - rwlock_acquire_read(&lg->lock_dep_map, 0, 0, _RET_IP_); - lock = per_cpu_ptr(lg->lock, cpu); + rwlock_acquire_read(lg_lock_dep_map(lg), 0, 0, _RET_IP_); + lock = per_cpu_ptr(&lg->lock, cpu); arch_spin_lock(lock); } EXPORT_SYMBOL(lg_local_lock_cpu); -void lg_local_unlock_cpu(struct lglock *lg, int cpu) +void lg_local_unlock_cpu(struct lglock __percpu *lg, int cpu) { arch_spinlock_t *lock; - rwlock_release(&lg->lock_dep_map, 1, _RET_IP_); - lock = per_cpu_ptr(lg->lock, cpu); + rwlock_release(lg_lock_dep_map(lg), 1, _RET_IP_); + lock = per_cpu_ptr(&lg->lock, cpu); arch_spin_unlock(lock); preempt_enable(); } EXPORT_SYMBOL(lg_local_unlock_cpu); -void lg_global_lock(struct lglock *lg) +void lg_global_lock(struct lglock __percpu *lg) { int i; preempt_disable(); - rwlock_acquire(&lg->lock_dep_map, 0, 0, _RET_IP_); + rwlock_acquire(lg_lock_dep_map(lg), 0, 0, _RET_IP_); for_each_possible_cpu(i) { arch_spinlock_t *lock; - lock = per_cpu_ptr(lg->lock, i); + lock = per_cpu_ptr(&lg->lock, i); arch_spin_lock(lock); } } EXPORT_SYMBOL(lg_global_lock); -void lg_global_unlock(struct lglock *lg) +void lg_global_unlock(struct lglock __percpu *lg) { int i; - rwlock_release(&lg->lock_dep_map, 1, _RET_IP_); + rwlock_release(lg_lock_dep_map(lg), 1, _RET_IP_); for_each_possible_cpu(i) { arch_spinlock_t *lock; - lock = per_cpu_ptr(lg->lock, i); + lock = per_cpu_ptr(&lg->lock, i); arch_spin_unlock(lock); } preempt_enable();