diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-18 12:04:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-18 12:04:17 -0400 |
commit | e0ed1c22d480a3b5ec5fce4e5399cf4481da95a6 (patch) | |
tree | f8750b76d55bcfe6c0d81678d2d87ccf92ad9e62 | |
parent | 50276c9abb9c236a359854f30eb8bb81fd14a22d (diff) | |
parent | 5f43086bb9224987010460dcf3dee68fbd4f574d (diff) |
Merge branch 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking fixes from Ingo Molnar:
"Two fixes:
- a file locks fix (missing critical section, bug introduced in this
merge window)
- an x86 down_write() stack frame annotation"
* 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
locking, fs/locks: Add missing file_sem locks
locking/rwsem/x86: Add stack frame dependency for ____down_write()
-rw-r--r-- | arch/x86/include/asm/rwsem.h | 6 | ||||
-rw-r--r-- | fs/locks.c | 6 |
2 files changed, 10 insertions, 2 deletions
diff --git a/arch/x86/include/asm/rwsem.h b/arch/x86/include/asm/rwsem.h index 3d33a719f5c1..a34e0d4b957d 100644 --- a/arch/x86/include/asm/rwsem.h +++ b/arch/x86/include/asm/rwsem.h | |||
@@ -103,8 +103,10 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem) | |||
103 | ({ \ | 103 | ({ \ |
104 | long tmp; \ | 104 | long tmp; \ |
105 | struct rw_semaphore* ret; \ | 105 | struct rw_semaphore* ret; \ |
106 | register void *__sp asm(_ASM_SP); \ | ||
107 | \ | ||
106 | asm volatile("# beginning down_write\n\t" \ | 108 | asm volatile("# beginning down_write\n\t" \ |
107 | LOCK_PREFIX " xadd %1,(%3)\n\t" \ | 109 | LOCK_PREFIX " xadd %1,(%4)\n\t" \ |
108 | /* adds 0xffff0001, returns the old value */ \ | 110 | /* adds 0xffff0001, returns the old value */ \ |
109 | " test " __ASM_SEL(%w1,%k1) "," __ASM_SEL(%w1,%k1) "\n\t" \ | 111 | " test " __ASM_SEL(%w1,%k1) "," __ASM_SEL(%w1,%k1) "\n\t" \ |
110 | /* was the active mask 0 before? */\ | 112 | /* was the active mask 0 before? */\ |
@@ -112,7 +114,7 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem) | |||
112 | " call " slow_path "\n" \ | 114 | " call " slow_path "\n" \ |
113 | "1:\n" \ | 115 | "1:\n" \ |
114 | "# ending down_write" \ | 116 | "# ending down_write" \ |
115 | : "+m" (sem->count), "=d" (tmp), "=a" (ret) \ | 117 | : "+m" (sem->count), "=d" (tmp), "=a" (ret), "+r" (__sp) \ |
116 | : "a" (sem), "1" (RWSEM_ACTIVE_WRITE_BIAS) \ | 118 | : "a" (sem), "1" (RWSEM_ACTIVE_WRITE_BIAS) \ |
117 | : "memory", "cc"); \ | 119 | : "memory", "cc"); \ |
118 | ret; \ | 120 | ret; \ |
diff --git a/fs/locks.c b/fs/locks.c index ce93b416b490..22c5b4aa4961 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1609,6 +1609,7 @@ int fcntl_getlease(struct file *filp) | |||
1609 | 1609 | ||
1610 | ctx = smp_load_acquire(&inode->i_flctx); | 1610 | ctx = smp_load_acquire(&inode->i_flctx); |
1611 | if (ctx && !list_empty_careful(&ctx->flc_lease)) { | 1611 | if (ctx && !list_empty_careful(&ctx->flc_lease)) { |
1612 | percpu_down_read_preempt_disable(&file_rwsem); | ||
1612 | spin_lock(&ctx->flc_lock); | 1613 | spin_lock(&ctx->flc_lock); |
1613 | time_out_leases(inode, &dispose); | 1614 | time_out_leases(inode, &dispose); |
1614 | list_for_each_entry(fl, &ctx->flc_lease, fl_list) { | 1615 | list_for_each_entry(fl, &ctx->flc_lease, fl_list) { |
@@ -1618,6 +1619,8 @@ int fcntl_getlease(struct file *filp) | |||
1618 | break; | 1619 | break; |
1619 | } | 1620 | } |
1620 | spin_unlock(&ctx->flc_lock); | 1621 | spin_unlock(&ctx->flc_lock); |
1622 | percpu_up_read_preempt_enable(&file_rwsem); | ||
1623 | |||
1621 | locks_dispose_list(&dispose); | 1624 | locks_dispose_list(&dispose); |
1622 | } | 1625 | } |
1623 | return type; | 1626 | return type; |
@@ -2529,11 +2532,14 @@ locks_remove_lease(struct file *filp, struct file_lock_context *ctx) | |||
2529 | if (list_empty(&ctx->flc_lease)) | 2532 | if (list_empty(&ctx->flc_lease)) |
2530 | return; | 2533 | return; |
2531 | 2534 | ||
2535 | percpu_down_read_preempt_disable(&file_rwsem); | ||
2532 | spin_lock(&ctx->flc_lock); | 2536 | spin_lock(&ctx->flc_lock); |
2533 | list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) | 2537 | list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) |
2534 | if (filp == fl->fl_file) | 2538 | if (filp == fl->fl_file) |
2535 | lease_modify(fl, F_UNLCK, &dispose); | 2539 | lease_modify(fl, F_UNLCK, &dispose); |
2536 | spin_unlock(&ctx->flc_lock); | 2540 | spin_unlock(&ctx->flc_lock); |
2541 | percpu_up_read_preempt_enable(&file_rwsem); | ||
2542 | |||
2537 | locks_dispose_list(&dispose); | 2543 | locks_dispose_list(&dispose); |
2538 | } | 2544 | } |
2539 | 2545 | ||