aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2021-02-01 23:06:04 +0000
committerMichael Brown <mcb30@ipxe.org>2021-02-01 23:08:49 +0000
commit6f1cb791ee7939c7302c8f815d178e89295b0eda (patch)
tree7f8cbeb70f9358df9b811193f9087ca407041cf9
parent8747241b3e843ed9771de21d8f2c57c3e67c77c7 (diff)
downloadipxe-6f1cb791ee7939c7302c8f815d178e89295b0eda.zip
ipxe-6f1cb791ee7939c7302c8f815d178e89295b0eda.tar.gz
ipxe-6f1cb791ee7939c7302c8f815d178e89295b0eda.tar.bz2
[hermon] Avoid parsing length field on completion errors
The CQE length field will not be valid for a completion in error. Avoid parsing the length field and just call the completion handler directly. In debug builds, also dump the queue pair context to allow for inspection of the error. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/drivers/infiniband/hermon.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/drivers/infiniband/hermon.c b/src/drivers/infiniband/hermon.c
index 53e514d..4d5272f 100644
--- a/src/drivers/infiniband/hermon.c
+++ b/src/drivers/infiniband/hermon.c
@@ -1104,7 +1104,9 @@ static uint8_t hermon_qp_st[] = {
*/
static __attribute__ (( unused )) int
hermon_dump_qpctx ( struct hermon *hermon, struct ib_queue_pair *qp ) {
+ struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
struct hermonprm_qp_ee_state_transitions qpctx;
+ unsigned int state;
int rc;
/* Do nothing unless debugging is enabled */
@@ -1118,7 +1120,14 @@ hermon_dump_qpctx ( struct hermon *hermon, struct ib_queue_pair *qp ) {
hermon, qp->qpn, strerror ( rc ) );
return rc;
}
- DBGC ( hermon, "Hermon %p QPN %#lx context:\n", hermon, qp->qpn );
+ state = MLX_GET ( &qpctx, qpc_eec_data.state );
+ if ( state != hermon_qp->state ) {
+ DBGC ( hermon, "Hermon %p QPN %#lx state %d unexpected "
+ "(should be %d)\n",
+ hermon, qp->qpn, state, hermon_qp->state );
+ }
+ DBGC ( hermon, "Hermon %p QPN %#lx state %d context:\n",
+ hermon, qp->qpn, state );
DBGC_HDA ( hermon, 0, &qpctx.u.dwords[2], ( sizeof ( qpctx ) - 8 ) );
return 0;
@@ -1799,6 +1808,11 @@ static int hermon_complete ( struct ib_device *ibdev,
if ( is_send ) {
/* Hand off to completion handler */
ib_complete_send ( ibdev, qp, iobuf, rc );
+ } else if ( rc != 0 ) {
+ /* Dump queue state (for debugging) */
+ hermon_dump_qpctx ( hermon, qp );
+ /* Hand off to completion handler */
+ ib_complete_recv ( ibdev, qp, NULL, NULL, iobuf, rc );
} else {
/* Set received length */
len = MLX_GET ( &cqe->normal, byte_cnt );
@@ -1841,7 +1855,7 @@ static int hermon_complete ( struct ib_device *ibdev,
assert ( len <= iob_tailroom ( iobuf ) );
iob_put ( iobuf, len );
/* Hand off to completion handler */
- ib_complete_recv ( ibdev, qp, &recv_dest, source, iobuf, rc );
+ ib_complete_recv ( ibdev, qp, &recv_dest, source, iobuf, 0 );
}
return rc;