IPoIB/cm: Initialize RX before moving QP to RTR
Fix a crasher bug in IPoIB CM: once a QP is in the RTR state, a receive completion (or even an asynchronous error) might be observed on this QP, so we have to initialize all of our receive data structures before moving to the RTR state. As an optimization (since modify_qp might take a long time), the jiffies update done when moving RX to the passive_ids list is also left in place to reduce the chance of the RX being misdetected as stale. This fixes bug <https://bugs.openfabrics.org/show_bug.cgi?id=662>. Signed-off-by: Michael S. Tsirkin <mst@dev.mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
Родитель
24bce50803
Коммит
3ec7393a68
|
@ -309,6 +309,11 @@ static int ipoib_cm_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *even
|
|||
return -ENOMEM;
|
||||
p->dev = dev;
|
||||
p->id = cm_id;
|
||||
cm_id->context = p;
|
||||
p->state = IPOIB_CM_RX_LIVE;
|
||||
p->jiffies = jiffies;
|
||||
INIT_LIST_HEAD(&p->list);
|
||||
|
||||
p->qp = ipoib_cm_create_rx_qp(dev, p);
|
||||
if (IS_ERR(p->qp)) {
|
||||
ret = PTR_ERR(p->qp);
|
||||
|
@ -320,24 +325,24 @@ static int ipoib_cm_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *even
|
|||
if (ret)
|
||||
goto err_modify;
|
||||
|
||||
spin_lock_irq(&priv->lock);
|
||||
queue_delayed_work(ipoib_workqueue,
|
||||
&priv->cm.stale_task, IPOIB_CM_RX_DELAY);
|
||||
/* Add this entry to passive ids list head, but do not re-add it
|
||||
* if IB_EVENT_QP_LAST_WQE_REACHED has moved it to flush list. */
|
||||
p->jiffies = jiffies;
|
||||
if (p->state == IPOIB_CM_RX_LIVE)
|
||||
list_move(&p->list, &priv->cm.passive_ids);
|
||||
spin_unlock_irq(&priv->lock);
|
||||
|
||||
ret = ipoib_cm_send_rep(dev, cm_id, p->qp, &event->param.req_rcvd, psn);
|
||||
if (ret) {
|
||||
ipoib_warn(priv, "failed to send REP: %d\n", ret);
|
||||
goto err_rep;
|
||||
if (ib_modify_qp(p->qp, &ipoib_cm_err_attr, IB_QP_STATE))
|
||||
ipoib_warn(priv, "unable to move qp to error state\n");
|
||||
}
|
||||
|
||||
cm_id->context = p;
|
||||
p->jiffies = jiffies;
|
||||
p->state = IPOIB_CM_RX_LIVE;
|
||||
spin_lock_irq(&priv->lock);
|
||||
if (list_empty(&priv->cm.passive_ids))
|
||||
queue_delayed_work(ipoib_workqueue,
|
||||
&priv->cm.stale_task, IPOIB_CM_RX_DELAY);
|
||||
list_add(&p->list, &priv->cm.passive_ids);
|
||||
spin_unlock_irq(&priv->lock);
|
||||
return 0;
|
||||
|
||||
err_rep:
|
||||
err_modify:
|
||||
ib_destroy_qp(p->qp);
|
||||
err_qp:
|
||||
|
|
Загрузка…
Ссылка в новой задаче