locking fixes
Subsystems (3)
Linus,
Please pull the latest locking-urgent-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking-urgent-for-linus
# HEAD: 5f43086bb9224987010460dcf3dee68fbd4f574d locking, fs/locks: Add missing file_sem locks
Two fixes:
- a file locks fix (missing critical section, bug introduced in this merge window)
- an x86 down_write() stack frame annotation
Thanks,
Ingo
------------------>
Josh Poimboeuf (1):
locking/rwsem/x86: Add stack frame dependency for ____down_write()
Peter Zijlstra (1):
locking, fs/locks: Add missing file_sem locks
arch/x86/include/asm/rwsem.h | 6 ++++-- fs/locks.c | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-)
arch/x86/include/asm/rwsem.h +4 -2
@@ -103,8 +103,10 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem) ({ \ long tmp; \ struct rw_semaphore* ret; \ + register void *__sp asm(_ASM_SP); \ + \ asm volatile("# beginning down_write\n\t" \ - LOCK_PREFIX " xadd %1,(%3)\n\t" \ + LOCK_PREFIX " xadd %1,(%4)\n\t" \ /* adds 0xffff0001, returns the old value */ \ " test " __ASM_SEL(%w1,%k1) "," __ASM_SEL(%w1,%k1) "\n\t" \ /* was the active mask 0 before? */\
@@ -112,7 +114,7 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem)" call " slow_path"\n" \"1:\n" \"# ending down_write" \ - : "+m" (sem->count), "=d" (tmp), "=a" (ret) \ + : "+m" (sem->count), "=d" (tmp), "=a" (ret), "+r" (__sp) \ : "a" (sem), "1" (RWSEM_ACTIVE_WRITE_BIAS) \ : "memory", "cc"); \ ret; \
fs/locks.c +6 -0
@@ -1609,6 +1609,7 @@ int fcntl_getlease(struct file *filp) ctx =smp_load_acquire (&inode->i_flctx);if (ctx && !list_empty_careful (&ctx->flc_lease)) { +percpu_down_read_preempt_disable (&file_rwsem);spin_lock (&ctx->flc_lock);time_out_leases (inode, &dispose);list_for_each_entry (fl, &ctx->flc_lease, fl_list) {
@@ -1618,6 +1619,8 @@ int fcntl_getlease(struct file *filp)break ; }spin_unlock (&ctx->flc_lock); +percpu_up_read_preempt_enable (&file_rwsem); +locks_dispose_list (&dispose); }return type;
@@ -2529,11 +2532,14 @@ locks_remove_lease(struct file *filp, struct file_lock_context *ctx)if (list_empty (&ctx->flc_lease))return ; +percpu_down_read_preempt_disable (&file_rwsem);spin_lock (&ctx->flc_lock);list_for_each_entry_safe (fl, tmp, &ctx->flc_lease, fl_list)if (filp == fl->fl_file)lease_modify (fl,F_UNLCK , &dispose);spin_unlock (&ctx->flc_lock); +percpu_up_read_preempt_enable (&file_rwsem); +locks_dispose_list (&dispose); }