ioat(4): Allow callouts to be scheduled after hw reset
is_completion_pending governs whether or not a callout will be scheduled when new work is queued on the IOAT device. If true, a callout is already scheduled, so we do not need a new one. If false, we schedule one and set it true. Because resetting the hardware completed all outstanding work but failed to clear is_completion_pending, no new callout could be scheduled after a reset with pending work. This resulted in a driver hang for polled-only work.
This commit is contained in:
parent
93bc3d0682
commit
dab3a7915f
@ -768,6 +768,13 @@ ioat_process_events(struct ioat_softc *ioat)
|
||||
ioat->stats.descriptors_error++;
|
||||
}
|
||||
|
||||
if (ioat->is_completion_pending) {
|
||||
ioat->is_completion_pending = FALSE;
|
||||
callout_reset(&ioat->shrink_timer, IOAT_SHRINK_PERIOD,
|
||||
ioat_shrink_timer_callback, ioat);
|
||||
callout_stop(&ioat->poll_timer);
|
||||
}
|
||||
|
||||
/* Clear error status */
|
||||
ioat_write_4(ioat, IOAT_CHANERR_OFFSET, chanerr);
|
||||
|
||||
@ -1898,6 +1905,7 @@ ioat_reset_hw(struct ioat_softc *ioat)
|
||||
ioat->tail = ioat->head = ioat->hw_head = 0;
|
||||
ioat->last_seen = 0;
|
||||
*ioat->comp_update = 0;
|
||||
KASSERT(!ioat->is_completion_pending, ("bogus completion_pending"));
|
||||
|
||||
ioat_write_chanctrl(ioat, IOAT_CHANCTRL_RUN);
|
||||
ioat_write_chancmp(ioat, ioat->comp_update_bus_addr);
|
||||
|
Loading…
Reference in New Issue
Block a user