Skip to content

Commit

Permalink
nbd: use our own workqueue for recv threads
Browse files Browse the repository at this point in the history
Since we are in the memory reclaim path we need our recv work to be on a
workqueue that has WQ_MEM_RECLAIM set so we can avoid deadlocks.  Also
set WQ_HIGHPRI since we are in the completion path for IO.

Signed-off-by: Josef Bacik <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
Josef Bacik authored and axboe committed Feb 1, 2017
1 parent 72f2f8f commit 124d6db
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions drivers/block/nbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ static struct dentry *nbd_dbg_dir;
static unsigned int nbds_max = 16;
static struct nbd_device *nbd_dev;
static int max_part;
static struct workqueue_struct *recv_workqueue;

static inline struct device *nbd_to_dev(struct nbd_device *nbd)
{
Expand Down Expand Up @@ -781,7 +782,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
INIT_WORK(&args[i].work, recv_work);
args[i].nbd = nbd;
args[i].index = i;
queue_work(system_long_wq, &args[i].work);
queue_work(recv_workqueue, &args[i].work);
}
wait_event_interruptible(nbd->recv_wq,
atomic_read(&nbd->recv_threads) == 0);
Expand Down Expand Up @@ -1030,10 +1031,16 @@ static int __init nbd_init(void)

if (nbds_max > 1UL << (MINORBITS - part_shift))
return -EINVAL;
recv_workqueue = alloc_workqueue("knbd-recv",
WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
if (!recv_workqueue)
return -ENOMEM;

nbd_dev = kcalloc(nbds_max, sizeof(*nbd_dev), GFP_KERNEL);
if (!nbd_dev)
if (!nbd_dev) {
destroy_workqueue(recv_workqueue);
return -ENOMEM;
}

for (i = 0; i < nbds_max; i++) {
struct request_queue *q;
Expand Down Expand Up @@ -1113,6 +1120,7 @@ static int __init nbd_init(void)
put_disk(nbd_dev[i].disk);
}
kfree(nbd_dev);
destroy_workqueue(recv_workqueue);
return err;
}

Expand All @@ -1132,6 +1140,7 @@ static void __exit nbd_cleanup(void)
put_disk(disk);
}
}
destroy_workqueue(recv_workqueue);
unregister_blkdev(NBD_MAJOR, "nbd");
kfree(nbd_dev);
printk(KERN_INFO "nbd: unregistered device at major %d\n", NBD_MAJOR);
Expand Down

0 comments on commit 124d6db

Please sign in to comment.