nvme_disk: Add an interrupt await timeout.

This way, if something stalls in an unexpected way, the whole system
won't just hang.

Should "fix" #15874, but there is probably some other underlying
problem.
This commit is contained in:
Augustin Cavalier
2020-04-20 23:49:24 -04:00
parent 6ef25b8505
commit b6fccb7930
@@ -389,6 +389,7 @@ static void
await_status(nvme_disk_driver_info* info, struct nvme_qpair* qpair, status_t& status)
{
ConditionVariableEntry entry;
int timeouts = 0;
while (status == EINPROGRESS) {
info->interrupt.Add(&entry);
@@ -397,7 +398,19 @@ await_status(nvme_disk_driver_info* info, struct nvme_qpair* qpair, status_t& st
if (status != EINPROGRESS)
return;
entry.Wait();
if (entry.Wait(B_RELATIVE_TIMEOUT, 5 * 1000 * 1000) != B_OK) {
// This should never happen, as we are woken up on every interrupt
// no matter the qpair or transfer within; so if it does occur,
// that probably means the controller stalled or something.
TRACE_ERROR("timed out waiting for interrupt!\n");
if (timeouts++ >= 3) {
nvme_qpair_fail(qpair);
status = B_TIMED_OUT;
return;
}
}
nvme_qpair_poll(qpair, 0);
}
}