From: Nikhil Rao <nikhil.rao@xxxxxxxxx> add the wq lock in cdev open and release call. This fixes race conditions observed in the open and close routines. Fixes: 42d279f9137a ("dmaengine: idxd: add char driver to expose submission portal to userland") Signed-off-by: Nikhil Rao <nikhil.rao@xxxxxxxxx> Signed-off-by: Dave Jiang <dave.jiang@xxxxxxxxx> --- drivers/dma/idxd/cdev.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c index ff49847e37a8..207555296913 100644 --- a/drivers/dma/idxd/cdev.c +++ b/drivers/dma/idxd/cdev.c @@ -74,6 +74,7 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp) struct idxd_device *idxd; struct idxd_wq *wq; struct device *dev; + int rc; wq = inode_wq(inode); idxd = wq->idxd; @@ -81,17 +82,29 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp) dev_dbg(dev, "%s called: %d\n", __func__, idxd_wq_refcount(wq)); - if (idxd_wq_refcount(wq) > 0 && wq_dedicated(wq)) - return -EBUSY; + mutex_lock(&wq->wq_lock); + + if (idxd_wq_refcount(wq) > 0 && wq_dedicated(wq)) { + rc = -EBUSY; + goto failed; + } ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + if (!ctx) { + rc = -ENOMEM; + goto failed; + } ctx->wq = wq; filp->private_data = ctx; idxd_wq_get(wq); + mutex_unlock(&wq->wq_lock); return 0; + + failed: + mutex_unlock(&wq->wq_lock); + kfree(ctx); + return rc; } static int idxd_cdev_release(struct inode *node, struct file *filep) @@ -105,7 +118,9 @@ static int idxd_cdev_release(struct inode *node, struct file *filep) filep->private_data = NULL; kfree(ctx); + mutex_lock(&wq->wq_lock); idxd_wq_put(wq); + mutex_unlock(&wq->wq_lock); return 0; }