Skip to content

Commit 5b0c68c

Browse files
davejiangvinodkoul
authored andcommitted
dmaengine: idxd: support reporting of halt interrupt
Unmask the halt error interrupt so it gets reported to the interrupt handler. When halt state interrupt is received, quiesce the kernel WQs and unmap the portals to stop submission. Signed-off-by: Dave Jiang <[email protected]> Link: https://lore.kernel.org/r/161894441167.3202472.9485946398140619501.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul <[email protected]>
1 parent cf5f86a commit 5b0c68c

File tree

5 files changed

+33
-1
lines changed

5 files changed

+33
-1
lines changed

drivers/dma/idxd/device.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ void idxd_unmask_error_interrupts(struct idxd_device *idxd)
4747

4848
genctrl.bits = ioread32(idxd->reg_base + IDXD_GENCTRL_OFFSET);
4949
genctrl.softerr_int_en = 1;
50+
genctrl.halt_int_en = 1;
5051
iowrite32(genctrl.bits, idxd->reg_base + IDXD_GENCTRL_OFFSET);
5152
}
5253

@@ -56,6 +57,7 @@ void idxd_mask_error_interrupts(struct idxd_device *idxd)
5657

5758
genctrl.bits = ioread32(idxd->reg_base + IDXD_GENCTRL_OFFSET);
5859
genctrl.softerr_int_en = 0;
60+
genctrl.halt_int_en = 0;
5961
iowrite32(genctrl.bits, idxd->reg_base + IDXD_GENCTRL_OFFSET);
6062
}
6163

@@ -312,6 +314,19 @@ void idxd_wq_unmap_portal(struct idxd_wq *wq)
312314
struct device *dev = &wq->idxd->pdev->dev;
313315

314316
devm_iounmap(dev, wq->portal);
317+
wq->portal = NULL;
318+
}
319+
320+
void idxd_wqs_unmap_portal(struct idxd_device *idxd)
321+
{
322+
int i;
323+
324+
for (i = 0; i < idxd->max_wqs; i++) {
325+
struct idxd_wq *wq = idxd->wqs[i];
326+
327+
if (wq->portal)
328+
idxd_wq_unmap_portal(wq);
329+
}
315330
}
316331

317332
int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid)

drivers/dma/idxd/idxd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ int idxd_register_devices(struct idxd_device *idxd);
371371
void idxd_unregister_devices(struct idxd_device *idxd);
372372
int idxd_register_driver(void);
373373
void idxd_unregister_driver(void);
374+
void idxd_wqs_quiesce(struct idxd_device *idxd);
374375

375376
/* device interrupt control */
376377
void idxd_msix_perm_setup(struct idxd_device *idxd);
@@ -400,6 +401,7 @@ int idxd_device_release_int_handle(struct idxd_device *idxd, int handle,
400401
enum idxd_interrupt_type irq_type);
401402

402403
/* work queue control */
404+
void idxd_wqs_unmap_portal(struct idxd_device *idxd);
403405
int idxd_wq_alloc_resources(struct idxd_wq *wq);
404406
void idxd_wq_free_resources(struct idxd_wq *wq);
405407
int idxd_wq_enable(struct idxd_wq *wq);

drivers/dma/idxd/init.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,18 @@ static void idxd_flush_work_list(struct idxd_irq_entry *ie)
647647
}
648648
}
649649

650+
void idxd_wqs_quiesce(struct idxd_device *idxd)
651+
{
652+
struct idxd_wq *wq;
653+
int i;
654+
655+
for (i = 0; i < idxd->max_wqs; i++) {
656+
wq = idxd->wqs[i];
657+
if (wq->state == IDXD_WQ_ENABLED && wq->type == IDXD_WQT_KERNEL)
658+
idxd_wq_quiesce(wq);
659+
}
660+
}
661+
650662
static void idxd_release_int_handles(struct idxd_device *idxd)
651663
{
652664
struct device *dev = &idxd->pdev->dev;

drivers/dma/idxd/irq.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ static int process_misc_interrupts(struct idxd_device *idxd, u32 cause)
202202
queue_work(idxd->wq, &idxd->work);
203203
} else {
204204
spin_lock_bh(&idxd->dev_lock);
205+
idxd_wqs_quiesce(idxd);
206+
idxd_wqs_unmap_portal(idxd);
205207
idxd_device_wqs_clear_state(idxd);
206208
dev_err(&idxd->pdev->dev,
207209
"idxd halted, need %s.\n",

drivers/dma/idxd/registers.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ union gencfg_reg {
120120
union genctrl_reg {
121121
struct {
122122
u32 softerr_int_en:1;
123-
u32 rsvd:31;
123+
u32 halt_int_en:1;
124+
u32 rsvd:30;
124125
};
125126
u32 bits;
126127
} __packed;

0 commit comments

Comments
 (0)