Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <lizhi.hou@amd.com>
Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250226161810.4188334-1-lizhi.hou@amd.com

authored by

Lizhi Hou and committed by
Mario Limonciello
cd740b87 4444e4d7

+13 -4
+13 -4
drivers/accel/amdxdna/amdxdna_mailbox.c
··· 349 349 trace_mbox_irq_handle(MAILBOX_NAME, irq); 350 350 /* Schedule a rx_work to call the callback functions */ 351 351 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); 354 352 355 353 return IRQ_HANDLED; 356 354 } ··· 365 367 return; 366 368 } 367 369 370 + again: 371 + mailbox_reg_write(mb_chann, mb_chann->iohub_int_addr, 0); 372 + 368 373 while (1) { 369 374 /* 370 375 * If return is 0, keep consuming next message, until there is ··· 381 380 if (unlikely(ret)) { 382 381 MB_ERR(mb_chann, "Unexpected ret %d, disable irq", ret); 383 382 WRITE_ONCE(mb_chann->bad_state, true); 384 - disable_irq(mb_chann->msix_irq); 385 - break; 383 + return; 386 384 } 387 385 } 386 + 387 + /* 388 + * The hardware will not generate interrupt if firmware creates a new 389 + * response right after driver clears interrupt register. Check 390 + * the interrupt register to make sure there is not any new response 391 + * before exiting. 392 + */ 393 + if (mailbox_reg_read(mb_chann, mb_chann->iohub_int_addr)) 394 + goto again; 388 395 } 389 396 390 397 int xdna_mailbox_send_msg(struct mailbox_channel *mb_chann,