diff options
author | Michael Brown <mcb30@ipxe.org> | 2021-02-01 23:06:04 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2021-02-01 23:08:49 +0000 |
commit | 6f1cb791ee7939c7302c8f815d178e89295b0eda (patch) | |
tree | 7f8cbeb70f9358df9b811193f9087ca407041cf9 /src | |
parent | 8747241b3e843ed9771de21d8f2c57c3e67c77c7 (diff) | |
download | ipxe-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>
Diffstat (limited to 'src')
-rw-r--r-- | src/drivers/infiniband/hermon.c | 18 |
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; |