Corrects a race condition in ipoib_cm_post_receive_nonsrq()
which allows wqes from one QP context to be post_recv
to another QP context.  The ipoib_cm_post_receive_nonsrq()
saves the wr_id in the shared structure ipoib_cm_dev_priv 
making it possible for the saved wr_id to be overwritten by
a subsequent event and posting to the incorrect qp context.
The patch switches to a local variable to save the wr_id.
Thanks to Hong-Nam Nguyen for finding this bug.

Signed-off-by: Pradeep Satyanarayana <[EMAIL PROTECTED]>
Signed-off-by: David Wilder <[EMAIL PROTECTED]>
---
 drivers/infiniband/ulp/ipoib/ipoib_cm.c |   18 ++++++++++++++----
 1 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c 
b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 97e67d3..8a1f92b 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -116,15 +116,25 @@ static int ipoib_cm_post_receive_nonsrq(struct net_device 
*dev,
                                        struct ipoib_cm_rx *rx, int id)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
-       struct ib_recv_wr *bad_wr;
+       struct ib_recv_wr *bad_wr, rx_wr;
+       struct ib_sge      rx_sge[IPOIB_CM_RX_SG];
        int i, ret;
 
-       priv->cm.rx_wr.wr_id = id | IPOIB_OP_CM | IPOIB_OP_RECV;
+       rx_sge[0].length = IPOIB_CM_HEAD_SIZE;
+       rx_sge[0].lkey   = priv->mr->lkey;
+       for (i = 1; i < IPOIB_CM_RX_SG; ++i) {
+               rx_sge[i].length = PAGE_SIZE;
+               rx_sge[i].lkey   = priv->mr->lkey;
+       }
+       rx_wr.next      = NULL;
+       rx_wr.sg_list   = rx_sge;
+       rx_wr.num_sge   = priv->cm.num_frags;
+       rx_wr.wr_id     = id | IPOIB_OP_CM | IPOIB_OP_RECV;
 
        for (i = 0; i < IPOIB_CM_RX_SG; ++i)
-               priv->cm.rx_sge[i].addr = rx->rx_ring[id].mapping[i];
+               rx_sge[i].addr = rx->rx_ring[id].mapping[i];
 
-       ret = ib_post_recv(rx->qp, &priv->cm.rx_wr, &bad_wr);
+       ret = ib_post_recv(rx->qp, &rx_wr, &bad_wr);
        if (unlikely(ret)) {
                ipoib_warn(priv, "post recv failed for buf %d (%d)\n", id, ret);
                ipoib_cm_dma_unmap_rx(priv, IPOIB_CM_RX_SG - 1,


_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to