RDMA/hns: Fix CQ and QP cache affinity
[linux-2.6-microblaze.git] / drivers / infiniband / hw / hns / hns_roce_qp.c
index d855a91..cdc1c6d 100644 (file)
@@ -170,14 +170,29 @@ static void hns_roce_ib_qp_event(struct hns_roce_qp *hr_qp,
        }
 }
 
-static u8 get_least_load_bankid_for_qp(struct hns_roce_bank *bank)
+static u8 get_affinity_cq_bank(u8 qp_bank)
 {
-       u32 least_load = bank[0].inuse;
+       return (qp_bank >> 1) & CQ_BANKID_MASK;
+}
+
+static u8 get_least_load_bankid_for_qp(struct ib_qp_init_attr *init_attr,
+                                       struct hns_roce_bank *bank)
+{
+#define INVALID_LOAD_QPNUM 0xFFFFFFFF
+       struct ib_cq *scq = init_attr->send_cq;
+       u32 least_load = INVALID_LOAD_QPNUM;
+       unsigned long cqn = 0;
        u8 bankid = 0;
        u32 bankcnt;
        u8 i;
 
-       for (i = 1; i < HNS_ROCE_QP_BANK_NUM; i++) {
+       if (scq)
+               cqn = to_hr_cq(scq)->cqn;
+
+       for (i = 0; i < HNS_ROCE_QP_BANK_NUM; i++) {
+               if (scq && (get_affinity_cq_bank(i) != (cqn & CQ_BANKID_MASK)))
+                       continue;
+
                bankcnt = bank[i].inuse;
                if (bankcnt < least_load) {
                        least_load = bankcnt;
@@ -209,7 +224,8 @@ static int alloc_qpn_with_bankid(struct hns_roce_bank *bank, u8 bankid,
 
        return 0;
 }
-static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
+static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
+                    struct ib_qp_init_attr *init_attr)
 {
        struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
        unsigned long num = 0;
@@ -220,7 +236,7 @@ static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
                num = 1;
        } else {
                mutex_lock(&qp_table->bank_mutex);
-               bankid = get_least_load_bankid_for_qp(qp_table->bank);
+               bankid = get_least_load_bankid_for_qp(init_attr, qp_table->bank);
 
                ret = alloc_qpn_with_bankid(&qp_table->bank[bankid], bankid,
                                            &num);
@@ -1082,7 +1098,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
                goto err_buf;
        }
 
-       ret = alloc_qpn(hr_dev, hr_qp);
+       ret = alloc_qpn(hr_dev, hr_qp, init_attr);
        if (ret) {
                ibdev_err(ibdev, "failed to alloc QPN, ret = %d.\n", ret);
                goto err_qpn;