Open hmaarrfk opened 5 years ago
Proposed patch:
From a432b7a86a14eefed708ca08669fdfcae9a76c66 Mon Sep 17 00:00:00 2001
From: Mark Harfouche <mark.harfouche@gmail.com>
Date: Mon, 20 May 2019 20:07:59 -0400
Subject: [PATCH] attemp to fixup early free of resources in xpdev_queue_delete
---
QDMA/linux-kernel/drv/qdma_mod.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/QDMA/linux-kernel/drv/qdma_mod.c b/QDMA/linux-kernel/drv/qdma_mod.c
index 1557dc3..6552899 100644
--- a/QDMA/linux-kernel/drv/qdma_mod.c
+++ b/QDMA/linux-kernel/drv/qdma_mod.c
@@ -1547,7 +1547,7 @@ int xpdev_queue_delete(struct xlnx_pci_dev *xpdev, unsigned int qidx, bool c2h,
{
struct xlnx_qdata *qdata = xpdev_queue_get(xpdev, qidx, c2h, 1, ebuf,
ebuflen);
- int rv = 0;
+ int rv = 1;
if (!qdata)
return -EINVAL;
@@ -1555,12 +1555,6 @@ int xpdev_queue_delete(struct xlnx_pci_dev *xpdev, unsigned int qidx, bool c2h,
if(!qdata->xcdev)
return -EINVAL;
- spin_lock(&xpdev->cdev_lock);
- qdata->xcdev->dir_init &= ~(1 << (c2h ? 1 : 0));
- if (qdata->xcdev && !qdata->xcdev->dir_init)
- qdma_cdev_destroy(qdata->xcdev);
- spin_unlock(&xpdev->cdev_lock);
-
if (qdata->qhndl != QDMA_QUEUE_IDX_INVALID)
rv = qdma_queue_remove(xpdev->dev_hndl, qdata->qhndl,
ebuf, ebuflen);
@@ -1570,6 +1564,13 @@ int xpdev_queue_delete(struct xlnx_pci_dev *xpdev, unsigned int qidx, bool c2h,
if (rv < 0)
goto exit;
+ // Optimistically remvoe the direction flag
+ spin_lock(&xpdev->cdev_lock);
+ qdata->xcdev->dir_init &= ~(1 << (c2h ? 1 : 0));
+ if (qdata->xcdev && !qdata->xcdev->dir_init)
+ qdma_cdev_destroy(qdata->xcdev);
+ spin_unlock(&xpdev->cdev_lock);
+
memset(qdata, 0, sizeof(*qdata));
exit:
return rv;
--
2.21.0
comments are appreciated. Maybe we need to optimistically hide resources from other threads attempt to delete the queue, then revert if we fail????
https://github.com/Xilinx/dma_ip_drivers/blob/f3828c8604126fa1ab149d5969d4b4c85509991f/QDMA/linux-kernel/drv/qdma_mod.c#L1553-L1560
in the case that removing the device false (say the queue was still in the "start" state) the
qdata->xcdev
can be freed.