Skip to content

Commit cd740b8

Browse files
houlz0507superm1
authored andcommitted
accel/amdxdna: Check interrupt register before mailbox_rx_worker exits
There is a timeout failure been found during stress tests. If the firmware generates a mailbox response right after driver clears the mailbox channel interrupt register, the hardware will not generate an interrupt for the response. This causes the unexpected mailbox command timeout. To handle this failure, driver checks the interrupt register before exiting mailbox_rx_worker(). If there is a new response, driver goes back to process it. Signed-off-by: Lizhi Hou <[email protected]> Reviewed-by: Jacek Lawrynowicz <[email protected]> Signed-off-by: Mario Limonciello <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 4444e4d commit cd740b8

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

drivers/accel/amdxdna/amdxdna_mailbox.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,6 @@ static irqreturn_t mailbox_irq_handler(int irq, void *p)
349349
trace_mbox_irq_handle(MAILBOX_NAME, irq);
350350
/* Schedule a rx_work to call the callback functions */
351351
queue_work(mb_chann->work_q, &mb_chann->rx_work);
352-
/* Clear IOHUB register */
353-
mailbox_reg_write(mb_chann, mb_chann->iohub_int_addr, 0);
354352

355353
return IRQ_HANDLED;
356354
}
@@ -367,6 +365,9 @@ static void mailbox_rx_worker(struct work_struct *rx_work)
367365
return;
368366
}
369367

368+
again:
369+
mailbox_reg_write(mb_chann, mb_chann->iohub_int_addr, 0);
370+
370371
while (1) {
371372
/*
372373
* If return is 0, keep consuming next message, until there is
@@ -380,10 +381,18 @@ static void mailbox_rx_worker(struct work_struct *rx_work)
380381
if (unlikely(ret)) {
381382
MB_ERR(mb_chann, "Unexpected ret %d, disable irq", ret);
382383
WRITE_ONCE(mb_chann->bad_state, true);
383-
disable_irq(mb_chann->msix_irq);
384-
break;
384+
return;
385385
}
386386
}
387+
388+
/*
389+
* The hardware will not generate interrupt if firmware creates a new
390+
* response right after driver clears interrupt register. Check
391+
* the interrupt register to make sure there is not any new response
392+
* before exiting.
393+
*/
394+
if (mailbox_reg_read(mb_chann, mb_chann->iohub_int_addr))
395+
goto again;
387396
}
388397

389398
int xdna_mailbox_send_msg(struct mailbox_channel *mb_chann,

0 commit comments

Comments
 (0)