free(m_cq);
}
+/* smd->cqlock/cqrlock held */
+void m_cq_flush(struct mcm_cq *m_cq)
+{
+ struct ibv_cq *ib_cq = NULL;
+ void *cq_ctx;
+ int ret, cnt=0;
+ struct ibv_wc wc;
+
+ mlog(8, " m_cq %p enter:\n", m_cq);
+ ret = ibv_get_cq_event(m_cq->ib_ch, &ib_cq, (void *)&cq_ctx);
+ if (ret == 0)
+ ibv_ack_cq_events(m_cq->ib_cq, 1);
+
+ do {
+ ret = ibv_poll_cq(m_cq->ib_cq, 1, &wc);
+ cnt += ret;
+ }
+ while (ret > 0);
+ mlog(8, " m_cq %p exit: %d events flushed\n", m_cq, cnt);
+}
+
/* destroy proxy CQ, fits in header */
static int mix_cq_destroy(mcm_scif_dev_t *smd, dat_mix_hdr_t *pmsg)
{
mpxy_unlock(&m_qp->smd->qprlock);
}
- mlog(8, " m_qp %p m_cm %p cm_id %d\n",
- m_qp, m_qp->cm, m_qp->cm ? m_qp->cm->entry.tid:0);
+ mlog(8, " m_qp %p m_cm %p cm_id %d cm_state %d\n",
+ m_qp, m_qp->cm, m_qp->cm ? m_qp->cm->entry.tid:0,
+ m_qp->cm ? m_qp->cm->state:0);
+
+ if (m_qp->cm)
+ m_qp->cm->state = MCM_DISCONNECTED;
+
+ mcm_flush_qp(m_qp); /* QP to error, flush consumer messages */
+
+ if (m_qp->m_cq_tx) { /* flush pending PO WRs on cq_tx */
+ mpxy_lock(&m_qp->smd->cqlock);
+ m_cq_flush(m_qp->m_cq_tx);
+ mpxy_unlock(&m_qp->smd->cqlock);
+ }
+
+ if (m_qp->m_cq_rx) { /* flush pending PI WRs on cq_rx */
+ mpxy_lock(&m_qp->smd->cqrlock);
+ m_cq_flush(m_qp->m_cq_rx);
+ mpxy_unlock(&m_qp->smd->cqrlock);
+ }
if (m_qp->cm) { /* unlink CM, serialized */
struct mcm_cm *cm = m_qp->cm;
mpxy_unlock(&cm->lock);
mcm_dqconn_free(m_qp->smd, cm);
}
- mcm_flush_qp(m_qp); /* move QP to error, flush */
if (m_qp->ib_qp1) {
ibv_destroy_qp(m_qp->ib_qp1);
if (m_qp->m_cq_rx) {
mpxy_lock(&m_qp->smd->cqrlock);
m_cq_free(m_qp->m_cq_rx);
+ m_qp->m_cq_rx = NULL;
mpxy_unlock(&m_qp->smd->cqrlock);
}
mpxy_lock_destroy(&m_qp->txlock); /* proxy out */
if (msg.wc[i].status != IBV_WC_SUCCESS) {
if (msg.wc[i].status != IBV_WC_WR_FLUSH_ERR) {
- mlog(0, " [%d:%d] ERROR (ep=%d): cq %p id %d ctx %p stat %d"
- " op 0x%x ln %d wr_id %p wc's %d verr 0x%x errno=%d,%s\n",
- m_cq->smd->md->mc->scif_id, m_cq->smd->entry.tid,
- m_cq->smd->scif_op_ep, m_cq, msg.cq_id, msg.cq_ctx,
- msg.wc[i].status, msg.wc[i].opcode, msg.wc[i].byte_len,
- msg.wc[i].wr_id, msg.wc_cnt, msg.wc[i].vendor_err,
+ mlog(0, " [%d:%d] ERROR (ep=%d): id %d stat %d"
+ " op %x flg %x ln %d wr_id %p wc's %d"
+ " verr 0x%x errno=%d,%s\n",
+ m_cq->smd->md->mc->scif_id,
+ m_cq->smd->entry.tid,
+ m_cq->smd->scif_op_ep, msg.cq_id,
+ msg.wc[i].status, msg.wc[i].opcode,
+ msg.wc[i].wc_flags, msg.wc[i].byte_len,
+ msg.wc[i].wr_id, msg.wc_cnt,
+ msg.wc[i].vendor_err,
errno, strerror(errno));
}
} else {
mpxy_lock(&m_qp->txlock);
if (((m_qp->wr_hd + 1) & m_qp->wr_end) == m_qp->wr_tl) { /* full */
ret = ENOMEM;
+ mlog(0, " ERR: WR full hd %d tl %d\n", m_qp->wr_hd, m_qp->wr_tl);
goto bail;
}
m_qp->wr_hd = (m_qp->wr_hd + 1) & m_qp->wr_end; /* move hd */