| From 62a57c70d8c002248fa8f6c8d8bd7a2c7e717620 Mon Sep 17 00:00:00 2001 |
| From: Sun Ke <sunke32@huawei.com> |
| Date: Wed, 22 Jan 2020 11:18:57 +0800 |
| Subject: [PATCH] nbd: add a flush_workqueue in nbd_start_device |
| |
| commit 5c0dd228b5fc30a3b732c7ae2657e0161ec7ed80 upstream. |
| |
| When kzalloc fail, may cause trying to destroy the |
| workqueue from inside the workqueue. |
| |
| If num_connections is m (2 < m), and NO.1 ~ NO.n |
| (1 < n < m) kzalloc are successful. The NO.(n + 1) |
| failed. Then, nbd_start_device will return ENOMEM |
| to nbd_start_device_ioctl, and nbd_start_device_ioctl |
| will return immediately without running flush_workqueue. |
| However, we still have n recv threads. If nbd_release |
| run first, recv threads may have to drop the last |
| config_refs and try to destroy the workqueue from |
| inside the workqueue. |
| |
| To fix it, add a flush_workqueue in nbd_start_device. |
| |
| Fixes: e9e006f5fcf2 ("nbd: fix max number of supported devs") |
| Signed-off-by: Sun Ke <sunke32@huawei.com> |
| Signed-off-by: Jens Axboe <axboe@kernel.dk> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c |
| index 72f4df37f625..c6a9ad14c27b 100644 |
| --- a/drivers/block/nbd.c |
| +++ b/drivers/block/nbd.c |
| @@ -1225,6 +1225,16 @@ static int nbd_start_device(struct nbd_device *nbd) |
| args = kzalloc(sizeof(*args), GFP_KERNEL); |
| if (!args) { |
| sock_shutdown(nbd); |
| + /* |
| + * If num_connections is m (2 < m), |
| + * and NO.1 ~ NO.n(1 < n < m) kzallocs are successful. |
| + * But NO.(n + 1) failed. We still have n recv threads. |
| + * So, add flush_workqueue here to prevent recv threads |
| + * dropping the last config_refs and trying to destroy |
| + * the workqueue from inside the workqueue. |
| + */ |
| + if (i) |
| + flush_workqueue(nbd->recv_workq); |
| return -ENOMEM; |
| } |
| sk_set_memalloc(config->socks[i]->sock->sk); |
| -- |
| 2.7.4 |
| |