Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1714988 > unrolled thread
| Started by | Ben Hutchings <ben@decadent.org.uk> |
|---|---|
| First post | 2017-08-18 15:40 +0200 |
| Last post | 2017-08-18 15:40 +0200 |
| Articles | 1 — 1 participant |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH 3.16 101/134] dm bufio: avoid a possible ABBA deadlock Ben Hutchings <ben@decadent.org.uk> - 2017-08-18 15:40 +0200
| From | Ben Hutchings <ben@decadent.org.uk> |
|---|---|
| Date | 2017-08-18 15:40 +0200 |
| Subject | [PATCH 3.16 101/134] dm bufio: avoid a possible ABBA deadlock |
| Message-ID | <ufPFg-4ln-17@gated-at.bofh.it> |
3.16.47-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <mpatocka@redhat.com>
commit 1b0fb5a5b2dc0dddcfa575060441a7176ba7ac37 upstream.
__get_memory_limit() tests if dm_bufio_cache_size changed and calls
__cache_size_refresh() if it did. It takes dm_bufio_clients_lock while
it already holds the client lock. However, lock ordering is violated
because in cleanup_old_buffers() dm_bufio_clients_lock is taken before
the client lock.
This results in a possible deadlock and lockdep engine warning.
Fix this deadlock by changing mutex_lock() to mutex_trylock(). If the
lock can't be taken, it will be re-checked next time when a new buffer
is allocated.
Also add "unlikely" to the if condition, so that the optimizer assumes
that the condition is false.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/md/dm-bufio.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -873,10 +873,11 @@ static void __get_memory_limit(struct dm
{
unsigned long buffers;
- if (ACCESS_ONCE(dm_bufio_cache_size) != dm_bufio_cache_size_latch) {
- mutex_lock(&dm_bufio_clients_lock);
- __cache_size_refresh();
- mutex_unlock(&dm_bufio_clients_lock);
+ if (unlikely(ACCESS_ONCE(dm_bufio_cache_size) != dm_bufio_cache_size_latch)) {
+ if (mutex_trylock(&dm_bufio_clients_lock)) {
+ __cache_size_refresh();
+ mutex_unlock(&dm_bufio_clients_lock);
+ }
}
buffers = dm_bufio_cache_size_per_client >>
Back to top | Article view | linux.kernel
csiph-web