diff options
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_qp.c')
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_qp.c | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 16c387d8170c..2e8f6f36e0a5 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c | |||
@@ -99,6 +99,10 @@ enum { | |||
99 | MTHCA_QP_BIT_RSC = 1 << 3 | 99 | MTHCA_QP_BIT_RSC = 1 << 3 |
100 | }; | 100 | }; |
101 | 101 | ||
102 | enum { | ||
103 | MTHCA_SEND_DOORBELL_FENCE = 1 << 5 | ||
104 | }; | ||
105 | |||
102 | struct mthca_qp_path { | 106 | struct mthca_qp_path { |
103 | __be32 port_pkey; | 107 | __be32 port_pkey; |
104 | u8 rnr_retry; | 108 | u8 rnr_retry; |
@@ -222,9 +226,8 @@ static void *get_send_wqe(struct mthca_qp *qp, int n) | |||
222 | (PAGE_SIZE - 1)); | 226 | (PAGE_SIZE - 1)); |
223 | } | 227 | } |
224 | 228 | ||
225 | static void mthca_wq_init(struct mthca_wq *wq) | 229 | static void mthca_wq_reset(struct mthca_wq *wq) |
226 | { | 230 | { |
227 | spin_lock_init(&wq->lock); | ||
228 | wq->next_ind = 0; | 231 | wq->next_ind = 0; |
229 | wq->last_comp = wq->max - 1; | 232 | wq->last_comp = wq->max - 1; |
230 | wq->head = 0; | 233 | wq->head = 0; |
@@ -845,10 +848,10 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
845 | mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn, | 848 | mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn, |
846 | qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL); | 849 | qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL); |
847 | 850 | ||
848 | mthca_wq_init(&qp->sq); | 851 | mthca_wq_reset(&qp->sq); |
849 | qp->sq.last = get_send_wqe(qp, qp->sq.max - 1); | 852 | qp->sq.last = get_send_wqe(qp, qp->sq.max - 1); |
850 | 853 | ||
851 | mthca_wq_init(&qp->rq); | 854 | mthca_wq_reset(&qp->rq); |
852 | qp->rq.last = get_recv_wqe(qp, qp->rq.max - 1); | 855 | qp->rq.last = get_recv_wqe(qp, qp->rq.max - 1); |
853 | 856 | ||
854 | if (mthca_is_memfree(dev)) { | 857 | if (mthca_is_memfree(dev)) { |
@@ -1112,8 +1115,11 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev, | |||
1112 | qp->atomic_rd_en = 0; | 1115 | qp->atomic_rd_en = 0; |
1113 | qp->resp_depth = 0; | 1116 | qp->resp_depth = 0; |
1114 | qp->sq_policy = send_policy; | 1117 | qp->sq_policy = send_policy; |
1115 | mthca_wq_init(&qp->sq); | 1118 | mthca_wq_reset(&qp->sq); |
1116 | mthca_wq_init(&qp->rq); | 1119 | mthca_wq_reset(&qp->rq); |
1120 | |||
1121 | spin_lock_init(&qp->sq.lock); | ||
1122 | spin_lock_init(&qp->rq.lock); | ||
1117 | 1123 | ||
1118 | ret = mthca_map_memfree(dev, qp); | 1124 | ret = mthca_map_memfree(dev, qp); |
1119 | if (ret) | 1125 | if (ret) |
@@ -1257,6 +1263,32 @@ int mthca_alloc_qp(struct mthca_dev *dev, | |||
1257 | return 0; | 1263 | return 0; |
1258 | } | 1264 | } |
1259 | 1265 | ||
1266 | static void mthca_lock_cqs(struct mthca_cq *send_cq, struct mthca_cq *recv_cq) | ||
1267 | { | ||
1268 | if (send_cq == recv_cq) | ||
1269 | spin_lock_irq(&send_cq->lock); | ||
1270 | else if (send_cq->cqn < recv_cq->cqn) { | ||
1271 | spin_lock_irq(&send_cq->lock); | ||
1272 | spin_lock_nested(&recv_cq->lock, SINGLE_DEPTH_NESTING); | ||
1273 | } else { | ||
1274 | spin_lock_irq(&recv_cq->lock); | ||
1275 | spin_lock_nested(&send_cq->lock, SINGLE_DEPTH_NESTING); | ||
1276 | } | ||
1277 | } | ||
1278 | |||
1279 | static void mthca_unlock_cqs(struct mthca_cq *send_cq, struct mthca_cq *recv_cq) | ||
1280 | { | ||
1281 | if (send_cq == recv_cq) | ||
1282 | spin_unlock_irq(&send_cq->lock); | ||
1283 | else if (send_cq->cqn < recv_cq->cqn) { | ||
1284 | spin_unlock(&recv_cq->lock); | ||
1285 | spin_unlock_irq(&send_cq->lock); | ||
1286 | } else { | ||
1287 | spin_unlock(&send_cq->lock); | ||
1288 | spin_unlock_irq(&recv_cq->lock); | ||
1289 | } | ||
1290 | } | ||
1291 | |||
1260 | int mthca_alloc_sqp(struct mthca_dev *dev, | 1292 | int mthca_alloc_sqp(struct mthca_dev *dev, |
1261 | struct mthca_pd *pd, | 1293 | struct mthca_pd *pd, |
1262 | struct mthca_cq *send_cq, | 1294 | struct mthca_cq *send_cq, |
@@ -1309,17 +1341,13 @@ int mthca_alloc_sqp(struct mthca_dev *dev, | |||
1309 | * Lock CQs here, so that CQ polling code can do QP lookup | 1341 | * Lock CQs here, so that CQ polling code can do QP lookup |
1310 | * without taking a lock. | 1342 | * without taking a lock. |
1311 | */ | 1343 | */ |
1312 | spin_lock_irq(&send_cq->lock); | 1344 | mthca_lock_cqs(send_cq, recv_cq); |
1313 | if (send_cq != recv_cq) | ||
1314 | spin_lock(&recv_cq->lock); | ||
1315 | 1345 | ||
1316 | spin_lock(&dev->qp_table.lock); | 1346 | spin_lock(&dev->qp_table.lock); |
1317 | mthca_array_clear(&dev->qp_table.qp, mqpn); | 1347 | mthca_array_clear(&dev->qp_table.qp, mqpn); |
1318 | spin_unlock(&dev->qp_table.lock); | 1348 | spin_unlock(&dev->qp_table.lock); |
1319 | 1349 | ||
1320 | if (send_cq != recv_cq) | 1350 | mthca_unlock_cqs(send_cq, recv_cq); |
1321 | spin_unlock(&recv_cq->lock); | ||
1322 | spin_unlock_irq(&send_cq->lock); | ||
1323 | 1351 | ||
1324 | err_out: | 1352 | err_out: |
1325 | dma_free_coherent(&dev->pdev->dev, sqp->header_buf_size, | 1353 | dma_free_coherent(&dev->pdev->dev, sqp->header_buf_size, |
@@ -1353,9 +1381,7 @@ void mthca_free_qp(struct mthca_dev *dev, | |||
1353 | * Lock CQs here, so that CQ polling code can do QP lookup | 1381 | * Lock CQs here, so that CQ polling code can do QP lookup |
1354 | * without taking a lock. | 1382 | * without taking a lock. |
1355 | */ | 1383 | */ |
1356 | spin_lock_irq(&send_cq->lock); | 1384 | mthca_lock_cqs(send_cq, recv_cq); |
1357 | if (send_cq != recv_cq) | ||
1358 | spin_lock(&recv_cq->lock); | ||
1359 | 1385 | ||
1360 | spin_lock(&dev->qp_table.lock); | 1386 | spin_lock(&dev->qp_table.lock); |
1361 | mthca_array_clear(&dev->qp_table.qp, | 1387 | mthca_array_clear(&dev->qp_table.qp, |
@@ -1363,9 +1389,7 @@ void mthca_free_qp(struct mthca_dev *dev, | |||
1363 | --qp->refcount; | 1389 | --qp->refcount; |
1364 | spin_unlock(&dev->qp_table.lock); | 1390 | spin_unlock(&dev->qp_table.lock); |
1365 | 1391 | ||
1366 | if (send_cq != recv_cq) | 1392 | mthca_unlock_cqs(send_cq, recv_cq); |
1367 | spin_unlock(&recv_cq->lock); | ||
1368 | spin_unlock_irq(&send_cq->lock); | ||
1369 | 1393 | ||
1370 | wait_event(qp->wait, !get_qp_refcount(dev, qp)); | 1394 | wait_event(qp->wait, !get_qp_refcount(dev, qp)); |
1371 | 1395 | ||
@@ -1500,7 +1524,7 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1500 | int i; | 1524 | int i; |
1501 | int size; | 1525 | int size; |
1502 | int size0 = 0; | 1526 | int size0 = 0; |
1503 | u32 f0 = 0; | 1527 | u32 f0; |
1504 | int ind; | 1528 | int ind; |
1505 | u8 op0 = 0; | 1529 | u8 op0 = 0; |
1506 | 1530 | ||
@@ -1684,6 +1708,8 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1684 | if (!size0) { | 1708 | if (!size0) { |
1685 | size0 = size; | 1709 | size0 = size; |
1686 | op0 = mthca_opcode[wr->opcode]; | 1710 | op0 = mthca_opcode[wr->opcode]; |
1711 | f0 = wr->send_flags & IB_SEND_FENCE ? | ||
1712 | MTHCA_SEND_DOORBELL_FENCE : 0; | ||
1687 | } | 1713 | } |
1688 | 1714 | ||
1689 | ++ind; | 1715 | ++ind; |
@@ -1841,7 +1867,7 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1841 | int i; | 1867 | int i; |
1842 | int size; | 1868 | int size; |
1843 | int size0 = 0; | 1869 | int size0 = 0; |
1844 | u32 f0 = 0; | 1870 | u32 f0; |
1845 | int ind; | 1871 | int ind; |
1846 | u8 op0 = 0; | 1872 | u8 op0 = 0; |
1847 | 1873 | ||
@@ -2049,6 +2075,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
2049 | if (!size0) { | 2075 | if (!size0) { |
2050 | size0 = size; | 2076 | size0 = size; |
2051 | op0 = mthca_opcode[wr->opcode]; | 2077 | op0 = mthca_opcode[wr->opcode]; |
2078 | f0 = wr->send_flags & IB_SEND_FENCE ? | ||
2079 | MTHCA_SEND_DOORBELL_FENCE : 0; | ||
2052 | } | 2080 | } |
2053 | 2081 | ||
2054 | ++ind; | 2082 | ++ind; |