Merge tag 'gpmc-omap-fixes-for-v4.7' of https://github.com/rogerq/linux into fixes
[cascardo/linux.git] / drivers / infiniband / sw / rdmavt / qp.c
index a9e3bcc..7de5134 100644 (file)
@@ -397,6 +397,7 @@ static void free_qpn(struct rvt_qpn_table *qpt, u32 qpn)
 static void rvt_clear_mr_refs(struct rvt_qp *qp, int clr_sends)
 {
        unsigned n;
+       struct rvt_dev_info *rdi = ib_to_rvt(qp->ibqp.device);
 
        if (test_and_clear_bit(RVT_R_REWIND_SGE, &qp->r_aflags))
                rvt_put_ss(&qp->s_rdma_read_sge);
@@ -431,7 +432,7 @@ static void rvt_clear_mr_refs(struct rvt_qp *qp, int clr_sends)
        if (qp->ibqp.qp_type != IB_QPT_RC)
                return;
 
-       for (n = 0; n < ARRAY_SIZE(qp->s_ack_queue); n++) {
+       for (n = 0; n < rvt_max_atomic(rdi); n++) {
                struct rvt_ack_entry *e = &qp->s_ack_queue[n];
 
                if (e->opcode == IB_OPCODE_RC_RDMA_READ_REQUEST &&
@@ -501,6 +502,12 @@ static void rvt_remove_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp)
  */
 static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp,
                  enum ib_qp_type type)
+       __releases(&qp->s_lock)
+       __releases(&qp->s_hlock)
+       __releases(&qp->r_lock)
+       __acquires(&qp->r_lock)
+       __acquires(&qp->s_hlock)
+       __acquires(&qp->s_lock)
 {
        if (qp->state != IB_QPS_RESET) {
                qp->state = IB_QPS_RESET;
@@ -569,7 +576,12 @@ static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp,
        qp->s_ssn = 1;
        qp->s_lsn = 0;
        qp->s_mig_state = IB_MIG_MIGRATED;
-       memset(qp->s_ack_queue, 0, sizeof(qp->s_ack_queue));
+       if (qp->s_ack_queue)
+               memset(
+                       qp->s_ack_queue,
+                       0,
+                       rvt_max_atomic(rdi) *
+                               sizeof(*qp->s_ack_queue));
        qp->r_head_ack_queue = 0;
        qp->s_tail_ack_queue = 0;
        qp->s_num_rd_atomic = 0;
@@ -653,9 +665,9 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
                if (gfp == GFP_NOIO)
                        swq = __vmalloc(
                                (init_attr->cap.max_send_wr + 1) * sz,
-                               gfp, PAGE_KERNEL);
+                               gfp | __GFP_ZERO, PAGE_KERNEL);
                else
-                       swq = vmalloc_node(
+                       swq = vzalloc_node(
                                (init_attr->cap.max_send_wr + 1) * sz,
                                rdi->dparms.node);
                if (!swq)
@@ -677,6 +689,16 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
                        goto bail_swq;
 
                RCU_INIT_POINTER(qp->next, NULL);
+               if (init_attr->qp_type == IB_QPT_RC) {
+                       qp->s_ack_queue =
+                               kzalloc_node(
+                                       sizeof(*qp->s_ack_queue) *
+                                        rvt_max_atomic(rdi),
+                                       gfp,
+                                       rdi->dparms.node);
+                       if (!qp->s_ack_queue)
+                               goto bail_qp;
+               }
 
                /*
                 * Driver needs to set up it's private QP structure and do any
@@ -704,9 +726,9 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
                                qp->r_rq.wq = __vmalloc(
                                                sizeof(struct rvt_rwq) +
                                                qp->r_rq.size * sz,
-                                               gfp, PAGE_KERNEL);
+                                               gfp | __GFP_ZERO, PAGE_KERNEL);
                        else
-                               qp->r_rq.wq = vmalloc_node(
+                               qp->r_rq.wq = vzalloc_node(
                                                sizeof(struct rvt_rwq) +
                                                qp->r_rq.size * sz,
                                                rdi->dparms.node);
@@ -829,13 +851,13 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
        case IB_QPT_SMI:
        case IB_QPT_GSI:
        case IB_QPT_UD:
-               qp->allowed_ops = IB_OPCODE_UD_SEND_ONLY & RVT_OPCODE_QP_MASK;
+               qp->allowed_ops = IB_OPCODE_UD;
                break;
        case IB_QPT_RC:
-               qp->allowed_ops = IB_OPCODE_RC_SEND_ONLY & RVT_OPCODE_QP_MASK;
+               qp->allowed_ops = IB_OPCODE_RC;
                break;
        case IB_QPT_UC:
-               qp->allowed_ops = IB_OPCODE_UC_SEND_ONLY & RVT_OPCODE_QP_MASK;
+               qp->allowed_ops = IB_OPCODE_UC;
                break;
        default:
                ret = ERR_PTR(-EINVAL);
@@ -857,6 +879,7 @@ bail_driver_priv:
        rdi->driver_f.qp_priv_free(rdi, qp);
 
 bail_qp:
+       kfree(qp->s_ack_queue);
        kfree(qp);
 
 bail_swq:
@@ -1284,6 +1307,7 @@ int rvt_destroy_qp(struct ib_qp *ibqp)
                vfree(qp->r_rq.wq);
        vfree(qp->s_wq);
        rdi->driver_f.qp_priv_free(rdi, qp);
+       kfree(qp->s_ack_queue);
        kfree(qp);
        return 0;
 }