diff options
Diffstat (limited to 'drivers/infiniband/hw/ehca/ehca_qp.c')
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_qp.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 4d54b9f64567..cadbf0cdd910 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
@@ -435,9 +435,13 @@ static void reset_queue_map(struct ehca_queue_map *qmap) | |||
435 | { | 435 | { |
436 | int i; | 436 | int i; |
437 | 437 | ||
438 | qmap->tail = 0; | 438 | qmap->tail = qmap->entries - 1; |
439 | for (i = 0; i < qmap->entries; i++) | 439 | qmap->left_to_poll = 0; |
440 | qmap->next_wqe_idx = 0; | ||
441 | for (i = 0; i < qmap->entries; i++) { | ||
440 | qmap->map[i].reported = 1; | 442 | qmap->map[i].reported = 1; |
443 | qmap->map[i].cqe_req = 0; | ||
444 | } | ||
441 | } | 445 | } |
442 | 446 | ||
443 | /* | 447 | /* |
@@ -860,6 +864,11 @@ static struct ehca_qp *internal_create_qp( | |||
860 | if (qp_type == IB_QPT_GSI) { | 864 | if (qp_type == IB_QPT_GSI) { |
861 | h_ret = ehca_define_sqp(shca, my_qp, init_attr); | 865 | h_ret = ehca_define_sqp(shca, my_qp, init_attr); |
862 | if (h_ret != H_SUCCESS) { | 866 | if (h_ret != H_SUCCESS) { |
867 | kfree(my_qp->mod_qp_parm); | ||
868 | my_qp->mod_qp_parm = NULL; | ||
869 | /* the QP pointer is no longer valid */ | ||
870 | shca->sport[init_attr->port_num - 1].ibqp_sqp[qp_type] = | ||
871 | NULL; | ||
863 | ret = ehca2ib_return_code(h_ret); | 872 | ret = ehca2ib_return_code(h_ret); |
864 | goto create_qp_exit6; | 873 | goto create_qp_exit6; |
865 | } | 874 | } |
@@ -1116,6 +1125,7 @@ static int calc_left_cqes(u64 wqe_p, struct ipz_queue *ipz_queue, | |||
1116 | void *wqe_v; | 1125 | void *wqe_v; |
1117 | u64 q_ofs; | 1126 | u64 q_ofs; |
1118 | u32 wqe_idx; | 1127 | u32 wqe_idx; |
1128 | unsigned int tail_idx; | ||
1119 | 1129 | ||
1120 | /* convert real to abs address */ | 1130 | /* convert real to abs address */ |
1121 | wqe_p = wqe_p & (~(1UL << 63)); | 1131 | wqe_p = wqe_p & (~(1UL << 63)); |
@@ -1128,12 +1138,17 @@ static int calc_left_cqes(u64 wqe_p, struct ipz_queue *ipz_queue, | |||
1128 | return -EFAULT; | 1138 | return -EFAULT; |
1129 | } | 1139 | } |
1130 | 1140 | ||
1141 | tail_idx = (qmap->tail + 1) % qmap->entries; | ||
1131 | wqe_idx = q_ofs / ipz_queue->qe_size; | 1142 | wqe_idx = q_ofs / ipz_queue->qe_size; |
1132 | if (wqe_idx < qmap->tail) | ||
1133 | qmap->left_to_poll = (qmap->entries - qmap->tail) + wqe_idx; | ||
1134 | else | ||
1135 | qmap->left_to_poll = wqe_idx - qmap->tail; | ||
1136 | 1143 | ||
1144 | /* check all processed wqes, whether a cqe is requested or not */ | ||
1145 | while (tail_idx != wqe_idx) { | ||
1146 | if (qmap->map[tail_idx].cqe_req) | ||
1147 | qmap->left_to_poll++; | ||
1148 | tail_idx = (tail_idx + 1) % qmap->entries; | ||
1149 | } | ||
1150 | /* save index in queue, where we have to start flushing */ | ||
1151 | qmap->next_wqe_idx = wqe_idx; | ||
1137 | return 0; | 1152 | return 0; |
1138 | } | 1153 | } |
1139 | 1154 | ||
@@ -1180,10 +1195,14 @@ static int check_for_left_cqes(struct ehca_qp *my_qp, struct ehca_shca *shca) | |||
1180 | } else { | 1195 | } else { |
1181 | spin_lock_irqsave(&my_qp->send_cq->spinlock, flags); | 1196 | spin_lock_irqsave(&my_qp->send_cq->spinlock, flags); |
1182 | my_qp->sq_map.left_to_poll = 0; | 1197 | my_qp->sq_map.left_to_poll = 0; |
1198 | my_qp->sq_map.next_wqe_idx = (my_qp->sq_map.tail + 1) % | ||
1199 | my_qp->sq_map.entries; | ||
1183 | spin_unlock_irqrestore(&my_qp->send_cq->spinlock, flags); | 1200 | spin_unlock_irqrestore(&my_qp->send_cq->spinlock, flags); |
1184 | 1201 | ||
1185 | spin_lock_irqsave(&my_qp->recv_cq->spinlock, flags); | 1202 | spin_lock_irqsave(&my_qp->recv_cq->spinlock, flags); |
1186 | my_qp->rq_map.left_to_poll = 0; | 1203 | my_qp->rq_map.left_to_poll = 0; |
1204 | my_qp->rq_map.next_wqe_idx = (my_qp->rq_map.tail + 1) % | ||
1205 | my_qp->rq_map.entries; | ||
1187 | spin_unlock_irqrestore(&my_qp->recv_cq->spinlock, flags); | 1206 | spin_unlock_irqrestore(&my_qp->recv_cq->spinlock, flags); |
1188 | } | 1207 | } |
1189 | 1208 | ||