commit b4a4957d3d1c328b733fce783b7264996f866ad2 upstream.
rvt_destroy_qp() cannot complete until all in process packets have
been released from the underlying hardware. If a link down event
occurs, an application can hang with a kernel stack similar to:
cat /proc/<app PID>/stack
quiesce_qp() waits until all outstanding packets have been freed.
This wait should be momentary. During a link down event, the cleanup
handling does not ensure that all packets caught by the link down are
This is caused by the fact that the freeze path and the link down
event is handled the same. This is not correct. The freeze path
waits until the HFI is unfrozen and then restarts PIO. A link down
is not a freeze event. The link down path cannot restart the PIO
until link is restored. If the PIO path is restarted before the link
comes up, the application (QP) using the PIO path will hang (until
link is restored).
Fix by separating the linkdown path from the freeze path and use the
link down path for link down events.
Close a race condition sc_disable() by acquiring both the progress
and release locks.
Close a race condition in sc_stop() by moving the setting of the flag
bits under the alloc lock.
Cc: <firstname.lastname@example.org> # 4.9.x+
Fixes: 77241056 ("IB/hfi1: add driver files")
Reviewed-by: Mike Marciniszyn <email@example.com>
Signed-off-by: Michael J. Ruhl <firstname.lastname@example.org>
Signed-off-by: Dennis Dalessandro <email@example.com>
Signed-off-by: Jason Gunthorpe <firstname.lastname@example.org>
Signed-off-by: Greg Kroah-Hartman <email@example.com>