]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/infiniband/hw/ipath/ipath_ruc.c
IB/ipath: NMI cpu lockup if local loopback used
[linux-2.6-omap-h63xx.git] / drivers / infiniband / hw / ipath / ipath_ruc.c
index 5c1da2d25e03e6c16ff4572ff59e88de613be0f5..cda84933bb4395b8c76e9c4c3bdbefcb30b6d80b 100644 (file)
@@ -108,7 +108,6 @@ void ipath_insert_rnr_queue(struct ipath_qp *qp)
 
 static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe)
 {
-       struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
        int user = to_ipd(qp->ibqp.pd)->user;
        int i, j, ret;
        struct ib_wc wc;
@@ -119,8 +118,7 @@ static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe)
                        continue;
                /* Check LKEY */
                if ((user && wqe->sg_list[i].lkey == 0) ||
-                   !ipath_lkey_ok(&dev->lk_table,
-                                  &qp->r_sg_list[j], &wqe->sg_list[i],
+                   !ipath_lkey_ok(qp, &qp->r_sg_list[j], &wqe->sg_list[i],
                                   IB_ACCESS_LOCAL_WRITE))
                        goto bad_lkey;
                qp->r_len += wqe->sg_list[i].length;
@@ -139,7 +137,7 @@ bad_lkey:
        wc.vendor_err = 0;
        wc.byte_len = 0;
        wc.imm_data = 0;
-       wc.qp_num = qp->ibqp.qp_num;
+       wc.qp = &qp->ibqp;
        wc.src_qp = 0;
        wc.wc_flags = 0;
        wc.pkey_index = 0;
@@ -204,6 +202,7 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only)
        wq->tail = tail;
 
        ret = 1;
+       qp->r_wrid_valid = 1;
        if (handler) {
                u32 n;
 
@@ -266,7 +265,8 @@ static void ipath_ruc_loopback(struct ipath_qp *sqp)
 again:
        spin_lock_irqsave(&sqp->s_lock, flags);
 
-       if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_SEND_OK)) {
+       if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_SEND_OK) ||
+           qp->s_rnr_timeout) {
                spin_unlock_irqrestore(&sqp->s_lock, flags);
                goto done;
        }
@@ -326,7 +326,7 @@ again:
        case IB_WR_RDMA_WRITE:
                if (wqe->length == 0)
                        break;
-               if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, wqe->length,
+               if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, wqe->length,
                                            wqe->wr.wr.rdma.remote_addr,
                                            wqe->wr.wr.rdma.rkey,
                                            IB_ACCESS_REMOTE_WRITE))) {
@@ -337,7 +337,7 @@ again:
                        wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
                        wc.vendor_err = 0;
                        wc.byte_len = 0;
-                       wc.qp_num = sqp->ibqp.qp_num;
+                       wc.qp = &sqp->ibqp;
                        wc.src_qp = sqp->remote_qpn;
                        wc.pkey_index = 0;
                        wc.slid = sqp->remote_ah_attr.dlid;
@@ -350,7 +350,7 @@ again:
                break;
 
        case IB_WR_RDMA_READ:
-               if (unlikely(!ipath_rkey_ok(dev, &sqp->s_sge, wqe->length,
+               if (unlikely(!ipath_rkey_ok(qp, &sqp->s_sge, wqe->length,
                                            wqe->wr.wr.rdma.remote_addr,
                                            wqe->wr.wr.rdma.rkey,
                                            IB_ACCESS_REMOTE_READ)))
@@ -365,7 +365,7 @@ again:
 
        case IB_WR_ATOMIC_CMP_AND_SWP:
        case IB_WR_ATOMIC_FETCH_AND_ADD:
-               if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, sizeof(u64),
+               if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64),
                                            wqe->wr.wr.rdma.remote_addr,
                                            wqe->wr.wr.rdma.rkey,
                                            IB_ACCESS_REMOTE_ATOMIC)))
@@ -427,7 +427,7 @@ again:
        wc.status = IB_WC_SUCCESS;
        wc.vendor_err = 0;
        wc.byte_len = wqe->length;
-       wc.qp_num = qp->ibqp.qp_num;
+       wc.qp = &qp->ibqp;
        wc.src_qp = qp->remote_qpn;
        /* XXX do we know which pkey matched? Only needed for GSI. */
        wc.pkey_index = 0;
@@ -448,7 +448,7 @@ send_comp:
                wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
                wc.vendor_err = 0;
                wc.byte_len = wqe->length;
-               wc.qp_num = sqp->ibqp.qp_num;
+               wc.qp = &sqp->ibqp;
                wc.src_qp = 0;
                wc.pkey_index = 0;
                wc.slid = 0;
@@ -575,8 +575,7 @@ int ipath_post_ruc_send(struct ipath_qp *qp, struct ib_send_wr *wr)
                }
                if (wr->sg_list[i].length == 0)
                        continue;
-               if (!ipath_lkey_ok(&to_idev(qp->ibqp.device)->lk_table,
-                                  &wqe->sg_list[j], &wr->sg_list[i],
+               if (!ipath_lkey_ok(qp, &wqe->sg_list[j], &wr->sg_list[i],
                                   acc)) {
                        spin_unlock_irqrestore(&qp->s_lock, flags);
                        ret = -EINVAL;