| From bd293d071ffe65e645b4d8104f9d8fe15ea13862 Mon Sep 17 00:00:00 2001 |
| From: Junxiao Bi <junxiao.bi@oracle.com> |
| Date: Tue, 9 Jul 2019 17:17:19 -0700 |
| Subject: dm bufio: fix deadlock with loop device |
| |
| From: Junxiao Bi <junxiao.bi@oracle.com> |
| |
| commit bd293d071ffe65e645b4d8104f9d8fe15ea13862 upstream. |
| |
| When thin-volume is built on loop device, if available memory is low, |
| the following deadlock can be triggered: |
| |
| One process P1 allocates memory with GFP_FS flag, direct alloc fails, |
| memory reclaim invokes memory shrinker in dm_bufio, dm_bufio_shrink_scan() |
| runs, mutex dm_bufio_client->lock is acquired, then P1 waits for dm_buffer |
| IO to complete in __try_evict_buffer(). |
| |
| But this IO may never complete if issued to an underlying loop device |
| that forwards it using direct-IO, which allocates memory using |
| GFP_KERNEL (see: do_blockdev_direct_IO()). If allocation fails, memory |
| reclaim will invoke memory shrinker in dm_bufio, dm_bufio_shrink_scan() |
| will be invoked, and since the mutex is already held by P1 the loop |
| thread will hang, and IO will never complete. Resulting in ABBA |
| deadlock. |
| |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com> |
| Signed-off-by: Mike Snitzer <snitzer@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/md/dm-bufio.c | 4 +--- |
| 1 file changed, 1 insertion(+), 3 deletions(-) |
| |
| --- a/drivers/md/dm-bufio.c |
| +++ b/drivers/md/dm-bufio.c |
| @@ -1585,9 +1585,7 @@ dm_bufio_shrink_scan(struct shrinker *sh |
| unsigned long freed; |
| |
| c = container_of(shrink, struct dm_bufio_client, shrinker); |
| - if (sc->gfp_mask & __GFP_FS) |
| - dm_bufio_lock(c); |
| - else if (!dm_bufio_trylock(c)) |
| + if (!dm_bufio_trylock(c)) |
| return SHRINK_STOP; |
| |
| freed = __scan(c, sc->nr_to_scan, sc->gfp_mask); |