IB/mlx4: Add debug prints
[deliverable/linux.git] / drivers / infiniband / hw / mlx4 / qp.c
index ceb33327091a8244a8d16d73766c5c2eab3840c1..84b26963c8d4ae04cbfafe9e66d5f4e5da7d9ce3 100644 (file)
@@ -310,8 +310,8 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
                       int is_user, int has_rq, struct mlx4_ib_qp *qp)
 {
        /* Sanity check RQ size before proceeding */
-       if (cap->max_recv_wr  > dev->dev->caps.max_wqes  ||
-           cap->max_recv_sge > dev->dev->caps.max_rq_sg)
+       if (cap->max_recv_wr > dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE ||
+           cap->max_recv_sge > min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg))
                return -EINVAL;
 
        if (!has_rq) {
@@ -329,8 +329,17 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
                qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg));
        }
 
-       cap->max_recv_wr  = qp->rq.max_post = qp->rq.wqe_cnt;
-       cap->max_recv_sge = qp->rq.max_gs;
+       /* leave userspace return values as they were, so as not to break ABI */
+       if (is_user) {
+               cap->max_recv_wr  = qp->rq.max_post = qp->rq.wqe_cnt;
+               cap->max_recv_sge = qp->rq.max_gs;
+       } else {
+               cap->max_recv_wr  = qp->rq.max_post =
+                       min(dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE, qp->rq.wqe_cnt);
+               cap->max_recv_sge = min(qp->rq.max_gs,
+                                       min(dev->dev->caps.max_sq_sg,
+                                           dev->dev->caps.max_rq_sg));
+       }
 
        return 0;
 }
@@ -341,8 +350,8 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
        int s;
 
        /* Sanity check SQ size before proceeding */
-       if (cap->max_send_wr     > dev->dev->caps.max_wqes  ||
-           cap->max_send_sge    > dev->dev->caps.max_sq_sg ||
+       if (cap->max_send_wr  > (dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE) ||
+           cap->max_send_sge > min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg) ||
            cap->max_inline_data + send_wqe_overhead(type, qp->flags) +
            sizeof (struct mlx4_wqe_inline_seg) > dev->dev->caps.max_sq_desc_sz)
                return -EINVAL;
@@ -1326,11 +1335,21 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
        cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state;
        new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
 
-       if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask))
+       if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask)) {
+               pr_debug("qpn 0x%x: invalid attribute mask specified "
+                        "for transition %d to %d. qp_type %d,"
+                        " attr_mask 0x%x\n",
+                        ibqp->qp_num, cur_state, new_state,
+                        ibqp->qp_type, attr_mask);
                goto out;
+       }
 
        if ((attr_mask & IB_QP_PORT) &&
            (attr->port_num == 0 || attr->port_num > dev->dev->caps.num_ports)) {
+               pr_debug("qpn 0x%x: invalid port number (%d) specified "
+                        "for transition %d to %d. qp_type %d\n",
+                        ibqp->qp_num, attr->port_num, cur_state,
+                        new_state, ibqp->qp_type);
                goto out;
        }
 
@@ -1341,17 +1360,30 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
 
        if (attr_mask & IB_QP_PKEY_INDEX) {
                int p = attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
-               if (attr->pkey_index >= dev->dev->caps.pkey_table_len[p])
+               if (attr->pkey_index >= dev->dev->caps.pkey_table_len[p]) {
+                       pr_debug("qpn 0x%x: invalid pkey index (%d) specified "
+                                "for transition %d to %d. qp_type %d\n",
+                                ibqp->qp_num, attr->pkey_index, cur_state,
+                                new_state, ibqp->qp_type);
                        goto out;
+               }
        }
 
        if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
            attr->max_rd_atomic > dev->dev->caps.max_qp_init_rdma) {
+               pr_debug("qpn 0x%x: max_rd_atomic (%d) too large. "
+                        "Transition %d to %d. qp_type %d\n",
+                        ibqp->qp_num, attr->max_rd_atomic, cur_state,
+                        new_state, ibqp->qp_type);
                goto out;
        }
 
        if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
            attr->max_dest_rd_atomic > dev->dev->caps.max_qp_dest_rdma) {
+               pr_debug("qpn 0x%x: max_dest_rd_atomic (%d) too large. "
+                        "Transition %d to %d. qp_type %d\n",
+                        ibqp->qp_num, attr->max_dest_rd_atomic, cur_state,
+                        new_state, ibqp->qp_type);
                goto out;
        }
 
This page took 0.040046 seconds and 5 git commands to generate.