aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mthca/mthca_qp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_qp.c')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c68
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
102enum {
103 MTHCA_SEND_DOORBELL_FENCE = 1 << 5
104};
105
102struct mthca_qp_path { 106struct 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
225static void mthca_wq_init(struct mthca_wq *wq) 229static 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
1266static 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
1279static 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
1260int mthca_alloc_sqp(struct mthca_dev *dev, 1292int 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;