|
@@ -412,6 +412,7 @@ static struct ehca_qp *internal_create_qp(
|
|
|
struct ehca_shca *shca = container_of(pd->device, struct ehca_shca,
|
|
struct ehca_shca *shca = container_of(pd->device, struct ehca_shca,
|
|
|
ib_device);
|
|
ib_device);
|
|
|
struct ib_ucontext *context = NULL;
|
|
struct ib_ucontext *context = NULL;
|
|
|
|
|
+ u32 nr_qes;
|
|
|
u64 h_ret;
|
|
u64 h_ret;
|
|
|
int is_llqp = 0, has_srq = 0;
|
|
int is_llqp = 0, has_srq = 0;
|
|
|
int qp_type, max_send_sge, max_recv_sge, ret;
|
|
int qp_type, max_send_sge, max_recv_sge, ret;
|
|
@@ -715,6 +716,15 @@ static struct ehca_qp *internal_create_qp(
|
|
|
"and pages ret=%i", ret);
|
|
"and pages ret=%i", ret);
|
|
|
goto create_qp_exit2;
|
|
goto create_qp_exit2;
|
|
|
}
|
|
}
|
|
|
|
|
+ nr_qes = my_qp->ipz_squeue.queue_length /
|
|
|
|
|
+ my_qp->ipz_squeue.qe_size;
|
|
|
|
|
+ my_qp->sq_map = vmalloc(nr_qes *
|
|
|
|
|
+ sizeof(struct ehca_qmap_entry));
|
|
|
|
|
+ if (!my_qp->sq_map) {
|
|
|
|
|
+ ehca_err(pd->device, "Couldn't allocate squeue "
|
|
|
|
|
+ "map ret=%i", ret);
|
|
|
|
|
+ goto create_qp_exit3;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (HAS_RQ(my_qp)) {
|
|
if (HAS_RQ(my_qp)) {
|
|
@@ -724,7 +734,7 @@ static struct ehca_qp *internal_create_qp(
|
|
|
if (ret) {
|
|
if (ret) {
|
|
|
ehca_err(pd->device, "Couldn't initialize rqueue "
|
|
ehca_err(pd->device, "Couldn't initialize rqueue "
|
|
|
"and pages ret=%i", ret);
|
|
"and pages ret=%i", ret);
|
|
|
- goto create_qp_exit3;
|
|
|
|
|
|
|
+ goto create_qp_exit4;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -770,7 +780,7 @@ static struct ehca_qp *internal_create_qp(
|
|
|
if (!my_qp->mod_qp_parm) {
|
|
if (!my_qp->mod_qp_parm) {
|
|
|
ehca_err(pd->device,
|
|
ehca_err(pd->device,
|
|
|
"Could not alloc mod_qp_parm");
|
|
"Could not alloc mod_qp_parm");
|
|
|
- goto create_qp_exit4;
|
|
|
|
|
|
|
+ goto create_qp_exit5;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -780,7 +790,7 @@ static struct ehca_qp *internal_create_qp(
|
|
|
h_ret = ehca_define_sqp(shca, my_qp, init_attr);
|
|
h_ret = ehca_define_sqp(shca, my_qp, init_attr);
|
|
|
if (h_ret != H_SUCCESS) {
|
|
if (h_ret != H_SUCCESS) {
|
|
|
ret = ehca2ib_return_code(h_ret);
|
|
ret = ehca2ib_return_code(h_ret);
|
|
|
- goto create_qp_exit5;
|
|
|
|
|
|
|
+ goto create_qp_exit6;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -789,7 +799,7 @@ static struct ehca_qp *internal_create_qp(
|
|
|
if (ret) {
|
|
if (ret) {
|
|
|
ehca_err(pd->device,
|
|
ehca_err(pd->device,
|
|
|
"Couldn't assign qp to send_cq ret=%i", ret);
|
|
"Couldn't assign qp to send_cq ret=%i", ret);
|
|
|
- goto create_qp_exit5;
|
|
|
|
|
|
|
+ goto create_qp_exit6;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -815,22 +825,26 @@ static struct ehca_qp *internal_create_qp(
|
|
|
if (ib_copy_to_udata(udata, &resp, sizeof resp)) {
|
|
if (ib_copy_to_udata(udata, &resp, sizeof resp)) {
|
|
|
ehca_err(pd->device, "Copy to udata failed");
|
|
ehca_err(pd->device, "Copy to udata failed");
|
|
|
ret = -EINVAL;
|
|
ret = -EINVAL;
|
|
|
- goto create_qp_exit6;
|
|
|
|
|
|
|
+ goto create_qp_exit7;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return my_qp;
|
|
return my_qp;
|
|
|
|
|
|
|
|
-create_qp_exit6:
|
|
|
|
|
|
|
+create_qp_exit7:
|
|
|
ehca_cq_unassign_qp(my_qp->send_cq, my_qp->real_qp_num);
|
|
ehca_cq_unassign_qp(my_qp->send_cq, my_qp->real_qp_num);
|
|
|
|
|
|
|
|
-create_qp_exit5:
|
|
|
|
|
|
|
+create_qp_exit6:
|
|
|
kfree(my_qp->mod_qp_parm);
|
|
kfree(my_qp->mod_qp_parm);
|
|
|
|
|
|
|
|
-create_qp_exit4:
|
|
|
|
|
|
|
+create_qp_exit5:
|
|
|
if (HAS_RQ(my_qp))
|
|
if (HAS_RQ(my_qp))
|
|
|
ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue);
|
|
ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue);
|
|
|
|
|
|
|
|
|
|
+create_qp_exit4:
|
|
|
|
|
+ if (HAS_SQ(my_qp))
|
|
|
|
|
+ vfree(my_qp->sq_map);
|
|
|
|
|
+
|
|
|
create_qp_exit3:
|
|
create_qp_exit3:
|
|
|
if (HAS_SQ(my_qp))
|
|
if (HAS_SQ(my_qp))
|
|
|
ipz_queue_dtor(my_pd, &my_qp->ipz_squeue);
|
|
ipz_queue_dtor(my_pd, &my_qp->ipz_squeue);
|
|
@@ -1534,8 +1548,6 @@ static int internal_modify_qp(struct ib_qp *ibqp,
|
|
|
if (attr_mask & IB_QP_QKEY)
|
|
if (attr_mask & IB_QP_QKEY)
|
|
|
my_qp->qkey = attr->qkey;
|
|
my_qp->qkey = attr->qkey;
|
|
|
|
|
|
|
|
- my_qp->state = qp_new_state;
|
|
|
|
|
-
|
|
|
|
|
modify_qp_exit2:
|
|
modify_qp_exit2:
|
|
|
if (squeue_locked) { /* this means: sqe -> rts */
|
|
if (squeue_locked) { /* this means: sqe -> rts */
|
|
|
spin_unlock_irqrestore(&my_qp->spinlock_s, flags);
|
|
spin_unlock_irqrestore(&my_qp->spinlock_s, flags);
|
|
@@ -1551,6 +1563,8 @@ static int internal_modify_qp(struct ib_qp *ibqp,
|
|
|
int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
|
|
int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
|
|
|
struct ib_udata *udata)
|
|
struct ib_udata *udata)
|
|
|
{
|
|
{
|
|
|
|
|
+ int ret = 0;
|
|
|
|
|
+
|
|
|
struct ehca_shca *shca = container_of(ibqp->device, struct ehca_shca,
|
|
struct ehca_shca *shca = container_of(ibqp->device, struct ehca_shca,
|
|
|
ib_device);
|
|
ib_device);
|
|
|
struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
|
|
struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
|
|
@@ -1597,12 +1611,18 @@ int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
|
|
|
attr->qp_state, my_qp->init_attr.port_num,
|
|
attr->qp_state, my_qp->init_attr.port_num,
|
|
|
ibqp->qp_type);
|
|
ibqp->qp_type);
|
|
|
spin_unlock_irqrestore(&sport->mod_sqp_lock, flags);
|
|
spin_unlock_irqrestore(&sport->mod_sqp_lock, flags);
|
|
|
- return 0;
|
|
|
|
|
|
|
+ goto out;
|
|
|
}
|
|
}
|
|
|
spin_unlock_irqrestore(&sport->mod_sqp_lock, flags);
|
|
spin_unlock_irqrestore(&sport->mod_sqp_lock, flags);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return internal_modify_qp(ibqp, attr, attr_mask, 0);
|
|
|
|
|
|
|
+ ret = internal_modify_qp(ibqp, attr, attr_mask, 0);
|
|
|
|
|
+
|
|
|
|
|
+out:
|
|
|
|
|
+ if ((ret == 0) && (attr_mask & IB_QP_STATE))
|
|
|
|
|
+ my_qp->state = attr->qp_state;
|
|
|
|
|
+
|
|
|
|
|
+ return ret;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void ehca_recover_sqp(struct ib_qp *sqp)
|
|
void ehca_recover_sqp(struct ib_qp *sqp)
|
|
@@ -1973,8 +1993,10 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
|
|
|
|
|
|
|
|
if (HAS_RQ(my_qp))
|
|
if (HAS_RQ(my_qp))
|
|
|
ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue);
|
|
ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue);
|
|
|
- if (HAS_SQ(my_qp))
|
|
|
|
|
|
|
+ if (HAS_SQ(my_qp)) {
|
|
|
ipz_queue_dtor(my_pd, &my_qp->ipz_squeue);
|
|
ipz_queue_dtor(my_pd, &my_qp->ipz_squeue);
|
|
|
|
|
+ vfree(my_qp->sq_map);
|
|
|
|
|
+ }
|
|
|
kmem_cache_free(qp_cache, my_qp);
|
|
kmem_cache_free(qp_cache, my_qp);
|
|
|
atomic_dec(&shca->num_qps);
|
|
atomic_dec(&shca->num_qps);
|
|
|
return 0;
|
|
return 0;
|