Skip to content

Commit 8affd8a

Browse files
davejiangvinodkoul
authored andcommitted
dmaengine: idxd: fix missed completion on abort path
Ming reported that with the abort path of the descriptor submission, there can be a window where a completed descriptor can be missed to be completed by the irq completion thread: CPU A CPU B Submit (successful) Submit (fail) irq_process_work_list() // empty llist_abort_desc() // remove all descs from pending list irq_process_pending_llist() // empty exit idxd_wq_thread() with no processing Add opportunistic descriptor completion in the abort path in order to remove the missed completion. Fixes: 6b4b87f ("dmaengine: idxd: fix submission race window") Reported-by: Ming Li <[email protected]> Signed-off-by: Dave Jiang <[email protected]> Link: https://lore.kernel.org/r/163898288714.443911.16084982766671976640.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul <[email protected]>
1 parent 80936d6 commit 8affd8a

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

drivers/dma/idxd/submit.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie,
106106
{
107107
struct idxd_desc *d, *t, *found = NULL;
108108
struct llist_node *head;
109+
LIST_HEAD(flist);
109110

110111
desc->completion->status = IDXD_COMP_DESC_ABORT;
111112
/*
@@ -120,7 +121,11 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie,
120121
found = desc;
121122
continue;
122123
}
123-
list_add_tail(&desc->list, &ie->work_list);
124+
125+
if (d->completion->status)
126+
list_add_tail(&d->list, &flist);
127+
else
128+
list_add_tail(&d->list, &ie->work_list);
124129
}
125130
}
126131

@@ -130,6 +135,17 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie,
130135

131136
if (found)
132137
complete_desc(found, IDXD_COMPLETE_ABORT);
138+
139+
/*
140+
* complete_desc() will return desc to allocator and the desc can be
141+
* acquired by a different process and the desc->list can be modified.
142+
* Delete desc from list so the list trasversing does not get corrupted
143+
* by the other process.
144+
*/
145+
list_for_each_entry_safe(d, t, &flist, list) {
146+
list_del_init(&d->list);
147+
complete_desc(d, IDXD_COMPLETE_NORMAL);
148+
}
133149
}
134150

135151
int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc)

0 commit comments

Comments
 (0)