summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_cq.c12
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_device.h6
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_main.c5
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_qp.c49
4 files changed, 60 insertions, 12 deletions
diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c
index 6aa82fe9dd3d..857a913326cd 100644
--- a/drivers/infiniband/hw/hns/hns_roce_cq.c
+++ b/drivers/infiniband/hw/hns/hns_roce_cq.c
@@ -55,7 +55,7 @@ void hns_roce_get_cq_bankid_for_uctx(struct hns_roce_ucontext *uctx)
{
struct hns_roce_dev *hr_dev = to_hr_dev(uctx->ibucontext.device);
struct hns_roce_cq_table *cq_table = &hr_dev->cq_table;
- u32 least_load = cq_table->ctx_num[0];
+ u32 least_load = U32_MAX;
u8 bankid = 0;
u8 i;
@@ -63,7 +63,10 @@ void hns_roce_get_cq_bankid_for_uctx(struct hns_roce_ucontext *uctx)
return;
mutex_lock(&cq_table->bank_mutex);
- for (i = 1; i < HNS_ROCE_CQ_BANK_NUM; i++) {
+ for (i = 0; i < HNS_ROCE_CQ_BANK_NUM; i++) {
+ if (!(cq_table->valid_cq_bank_mask & BIT(i)))
+ continue;
+
if (cq_table->ctx_num[i] < least_load) {
least_load = cq_table->ctx_num[i];
bankid = i;
@@ -581,6 +584,11 @@ void hns_roce_init_cq_table(struct hns_roce_dev *hr_dev)
cq_table->bank[i].max = hr_dev->caps.num_cqs /
HNS_ROCE_CQ_BANK_NUM - 1;
}
+
+ if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_LIMIT_BANK)
+ cq_table->valid_cq_bank_mask = VALID_CQ_BANK_MASK_LIMIT;
+ else
+ cq_table->valid_cq_bank_mask = VALID_CQ_BANK_MASK_DEFAULT;
}
void hns_roce_cleanup_cq_table(struct hns_roce_dev *hr_dev)
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
index 318f18cf37aa..3f032b8038af 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -103,6 +103,10 @@
#define CQ_BANKID_SHIFT 2
#define CQ_BANKID_MASK GENMASK(1, 0)
+#define VALID_CQ_BANK_MASK_DEFAULT 0xF
+#define VALID_CQ_BANK_MASK_LIMIT 0x9
+
+#define VALID_EXT_SGE_QP_BANK_MASK_LIMIT 0x42
#define HNS_ROCE_MAX_CQ_COUNT 0xFFFF
#define HNS_ROCE_MAX_CQ_PERIOD 0xFFFF
@@ -156,6 +160,7 @@ enum {
HNS_ROCE_CAP_FLAG_CQE_INLINE = BIT(19),
HNS_ROCE_CAP_FLAG_BOND = BIT(21),
HNS_ROCE_CAP_FLAG_SRQ_RECORD_DB = BIT(22),
+ HNS_ROCE_CAP_FLAG_LIMIT_BANK = BIT(23),
};
#define HNS_ROCE_DB_TYPE_COUNT 2
@@ -500,6 +505,7 @@ struct hns_roce_cq_table {
struct hns_roce_bank bank[HNS_ROCE_CQ_BANK_NUM];
struct mutex bank_mutex;
u32 ctx_num[HNS_ROCE_CQ_BANK_NUM];
+ u8 valid_cq_bank_mask;
};
struct hns_roce_srq_table {
diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
index 2f4864ab7d4e..a3490bab297a 100644
--- a/drivers/infiniband/hw/hns/hns_roce_main.c
+++ b/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -259,6 +259,11 @@ static int hns_roce_query_device(struct ib_device *ib_dev,
props->max_srq_sge = hr_dev->caps.max_srq_sges;
}
+ if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_LIMIT_BANK) {
+ props->max_cq >>= 1;
+ props->max_qp >>= 1;
+ }
+
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_FRMR &&
hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) {
props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS;
diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
index d1640c5fbaab..5f7ea6c16644 100644
--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
+++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
@@ -197,22 +197,16 @@ static u8 get_affinity_cq_bank(u8 qp_bank)
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)
+static u8 get_least_load_bankid_for_qp(struct hns_roce_bank *bank, u8 valid_qp_bank_mask)
{
#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;
- 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)))
+ if (!(valid_qp_bank_mask & BIT(i)))
continue;
bankcnt = bank[i].inuse;
@@ -246,6 +240,42 @@ static int alloc_qpn_with_bankid(struct hns_roce_bank *bank, u8 bankid,
return 0;
}
+
+static bool use_ext_sge(struct ib_qp_init_attr *init_attr)
+{
+ return init_attr->cap.max_send_sge > HNS_ROCE_SGE_IN_WQE ||
+ init_attr->qp_type == IB_QPT_UD ||
+ init_attr->qp_type == IB_QPT_GSI;
+}
+
+static u8 select_qp_bankid(struct hns_roce_dev *hr_dev,
+ struct ib_qp_init_attr *init_attr)
+{
+ struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
+ struct hns_roce_bank *bank = qp_table->bank;
+ struct ib_cq *scq = init_attr->send_cq;
+ u8 valid_qp_bank_mask = 0;
+ unsigned long cqn = 0;
+ u8 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;
+
+ if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_LIMIT_BANK) &&
+ use_ext_sge(init_attr) &&
+ !(VALID_EXT_SGE_QP_BANK_MASK_LIMIT & BIT(i)))
+ continue;
+
+ valid_qp_bank_mask |= BIT(i);
+ }
+
+ return get_least_load_bankid_for_qp(bank, valid_qp_bank_mask);
+}
+
static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
struct ib_qp_init_attr *init_attr)
{
@@ -258,8 +288,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(init_attr, qp_table->bank);
-
+ bankid = select_qp_bankid(hr_dev, init_attr);
ret = alloc_qpn_with_bankid(&qp_table->bank[bankid], bankid,
&num);
if (ret) {