Skip to content

Commit de5819b

Browse files
snitsvinodkoul
authored andcommitted
dmaengine: idxd: track enabled workqueues in bitmap
Now that idxd_wq_disable_cleanup() sets the workqueue state to IDXD_WQ_DISABLED, use a bitmap to track which workqueues have been enabled. This will then be used to determine which workqueues should be re-enabled when attempting a software reset to recover from a device halt state. Cc: Fenghua Yu <[email protected]> Cc: Dave Jiang <[email protected]> Cc: Vinod Koul <[email protected]> Signed-off-by: Jerry Snitselaar <[email protected]> Reviewed-by: Dave Jiang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 8e527aa commit de5819b

File tree

5 files changed

+14
-2
lines changed

5 files changed

+14
-2
lines changed

drivers/dma/idxd/device.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ int idxd_wq_enable(struct idxd_wq *wq)
196196
}
197197

198198
wq->state = IDXD_WQ_ENABLED;
199+
set_bit(wq->id, idxd->wq_enable_map);
199200
dev_dbg(dev, "WQ %d enabled\n", wq->id);
200201
return 0;
201202
}
@@ -223,6 +224,7 @@ int idxd_wq_disable(struct idxd_wq *wq, bool reset_config)
223224

224225
if (reset_config)
225226
idxd_wq_disable_cleanup(wq);
227+
clear_bit(wq->id, idxd->wq_enable_map);
226228
wq->state = IDXD_WQ_DISABLED;
227229
dev_dbg(dev, "WQ %d disabled\n", wq->id);
228230
return 0;

drivers/dma/idxd/idxd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/idr.h>
1212
#include <linux/pci.h>
1313
#include <linux/ioasid.h>
14+
#include <linux/bitmap.h>
1415
#include <linux/perf_event.h>
1516
#include <uapi/linux/idxd.h>
1617
#include "registers.h"
@@ -299,6 +300,7 @@ struct idxd_device {
299300
int rdbuf_limit;
300301
int nr_rdbufs; /* non-reserved read buffers */
301302
unsigned int wqcfg_size;
303+
unsigned long *wq_enable_map;
302304

303305
union sw_err_reg sw_err;
304306
wait_queue_head_t cmd_waitq;

drivers/dma/idxd/init.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
151151
if (!idxd->wqs)
152152
return -ENOMEM;
153153

154+
idxd->wq_enable_map = bitmap_zalloc_node(idxd->max_wqs, GFP_KERNEL, dev_to_node(dev));
155+
if (!idxd->wq_enable_map) {
156+
kfree(idxd->wqs);
157+
return -ENOMEM;
158+
}
159+
154160
for (i = 0; i < idxd->max_wqs; i++) {
155161
wq = kzalloc_node(sizeof(*wq), GFP_KERNEL, dev_to_node(dev));
156162
if (!wq) {

drivers/dma/idxd/irq.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,12 @@ static void idxd_device_reinit(struct work_struct *work)
4949
goto out;
5050

5151
for (i = 0; i < idxd->max_wqs; i++) {
52-
struct idxd_wq *wq = idxd->wqs[i];
52+
if (test_bit(i, idxd->wq_enable_map)) {
53+
struct idxd_wq *wq = idxd->wqs[i];
5354

54-
if (wq->state == IDXD_WQ_ENABLED) {
5555
rc = idxd_wq_enable(wq);
5656
if (rc < 0) {
57+
clear_bit(i, idxd->wq_enable_map);
5758
dev_warn(dev, "Unable to re-enable wq %s\n",
5859
dev_name(wq_confdev(wq)));
5960
}

drivers/dma/idxd/sysfs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,6 +1405,7 @@ static void idxd_conf_device_release(struct device *dev)
14051405
struct idxd_device *idxd = confdev_to_idxd(dev);
14061406

14071407
kfree(idxd->groups);
1408+
bitmap_free(idxd->wq_enable_map);
14081409
kfree(idxd->wqs);
14091410
kfree(idxd->engines);
14101411
ida_free(&idxd_ida, idxd->id);

0 commit comments

Comments
 (0)