mirror of
https://github.com/torvalds/linux.git
synced 2024-12-22 02:52:56 +00:00
RDMA/hns: Optimize mhop put flow for multi-hop addressing
Optimizes hns_roce_table_mhop_get() by encapsulating code about clearing hem into clear_mhop_hem(), which will make the code flow clearer. Link: https://lore.kernel.org/r/1584417324-2255-3-git-send-email-liweihang@huawei.com Signed-off-by: Xi Wang <wangxi11@huawei.com> Signed-off-by: Weihang Li <liweihang@huawei.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
2f49de21f3
commit
38dcb35048
@ -94,25 +94,27 @@ bool hns_roce_check_whether_mhop(struct hns_roce_dev *hr_dev, u32 type)
|
|||||||
return hop_num ? true : false;
|
return hop_num ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hns_roce_check_hem_null(struct hns_roce_hem **hem, u64 start_idx,
|
static bool hns_roce_check_hem_null(struct hns_roce_hem **hem, u64 hem_idx,
|
||||||
u32 bt_chunk_num, u64 hem_max_num)
|
u32 bt_chunk_num, u64 hem_max_num)
|
||||||
{
|
{
|
||||||
|
u64 start_idx = round_down(hem_idx, bt_chunk_num);
|
||||||
u64 check_max_num = start_idx + bt_chunk_num;
|
u64 check_max_num = start_idx + bt_chunk_num;
|
||||||
u64 i;
|
u64 i;
|
||||||
|
|
||||||
for (i = start_idx; (i < check_max_num) && (i < hem_max_num); i++)
|
for (i = start_idx; (i < check_max_num) && (i < hem_max_num); i++)
|
||||||
if (hem[i])
|
if (i != hem_idx && hem[i])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hns_roce_check_bt_null(u64 **bt, u64 start_idx, u32 bt_chunk_num)
|
static bool hns_roce_check_bt_null(u64 **bt, u64 ba_idx, u32 bt_chunk_num)
|
||||||
{
|
{
|
||||||
|
u64 start_idx = round_down(ba_idx, bt_chunk_num);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < bt_chunk_num; i++)
|
for (i = 0; i < bt_chunk_num; i++)
|
||||||
if (bt[start_idx + i])
|
if (i != ba_idx && bt[start_idx + i])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -723,116 +725,75 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clear_mhop_hem(struct hns_roce_dev *hr_dev,
|
||||||
|
struct hns_roce_hem_table *table, unsigned long obj,
|
||||||
|
struct hns_roce_hem_mhop *mhop,
|
||||||
|
struct hns_roce_hem_index *index)
|
||||||
|
{
|
||||||
|
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||||
|
u32 hop_num = mhop->hop_num;
|
||||||
|
u32 chunk_ba_num;
|
||||||
|
int step_idx;
|
||||||
|
|
||||||
|
index->inited = HEM_INDEX_BUF;
|
||||||
|
chunk_ba_num = mhop->bt_chunk_size / BA_BYTE_LEN;
|
||||||
|
if (check_whether_bt_num_2(table->type, hop_num)) {
|
||||||
|
if (hns_roce_check_hem_null(table->hem, index->buf,
|
||||||
|
chunk_ba_num, table->num_hem))
|
||||||
|
index->inited |= HEM_INDEX_L0;
|
||||||
|
} else if (check_whether_bt_num_3(table->type, hop_num)) {
|
||||||
|
if (hns_roce_check_hem_null(table->hem, index->buf,
|
||||||
|
chunk_ba_num, table->num_hem)) {
|
||||||
|
index->inited |= HEM_INDEX_L1;
|
||||||
|
if (hns_roce_check_bt_null(table->bt_l1, index->l1,
|
||||||
|
chunk_ba_num))
|
||||||
|
index->inited |= HEM_INDEX_L0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table->type < HEM_TYPE_MTT) {
|
||||||
|
if (hop_num == HNS_ROCE_HOP_NUM_0)
|
||||||
|
step_idx = 0;
|
||||||
|
else
|
||||||
|
step_idx = hop_num;
|
||||||
|
|
||||||
|
if (hr_dev->hw->clear_hem(hr_dev, table, obj, step_idx))
|
||||||
|
ibdev_warn(ibdev, "Clear hop%d HEM failed.\n", hop_num);
|
||||||
|
|
||||||
|
if (index->inited & HEM_INDEX_L1)
|
||||||
|
if (hr_dev->hw->clear_hem(hr_dev, table, obj, 1))
|
||||||
|
ibdev_warn(ibdev, "Clear HEM step 1 failed.\n");
|
||||||
|
|
||||||
|
if (index->inited & HEM_INDEX_L0)
|
||||||
|
if (hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
|
||||||
|
ibdev_warn(ibdev, "Clear HEM step 0 failed.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev,
|
static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev,
|
||||||
struct hns_roce_hem_table *table,
|
struct hns_roce_hem_table *table,
|
||||||
unsigned long obj,
|
unsigned long obj,
|
||||||
int check_refcount)
|
int check_refcount)
|
||||||
{
|
{
|
||||||
struct device *dev = hr_dev->dev;
|
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||||
struct hns_roce_hem_mhop mhop;
|
struct hns_roce_hem_index index = {};
|
||||||
unsigned long mhop_obj = obj;
|
struct hns_roce_hem_mhop mhop = {};
|
||||||
u32 bt_chunk_size;
|
|
||||||
u32 chunk_ba_num;
|
|
||||||
u32 hop_num;
|
|
||||||
u32 start_idx;
|
|
||||||
u32 bt_num;
|
|
||||||
u64 hem_idx;
|
|
||||||
u64 bt_l1_idx = 0;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = hns_roce_calc_hem_mhop(hr_dev, table, &mhop_obj, &mhop);
|
ret = calc_hem_config(hr_dev, table, obj, &mhop, &index);
|
||||||
if (ret)
|
if (ret) {
|
||||||
return;
|
ibdev_err(ibdev, "calc hem config failed!\n");
|
||||||
|
|
||||||
bt_chunk_size = mhop.bt_chunk_size;
|
|
||||||
hop_num = mhop.hop_num;
|
|
||||||
chunk_ba_num = bt_chunk_size / BA_BYTE_LEN;
|
|
||||||
|
|
||||||
bt_num = hns_roce_get_bt_num(table->type, hop_num);
|
|
||||||
switch (bt_num) {
|
|
||||||
case 3:
|
|
||||||
hem_idx = mhop.l0_idx * chunk_ba_num * chunk_ba_num +
|
|
||||||
mhop.l1_idx * chunk_ba_num + mhop.l2_idx;
|
|
||||||
bt_l1_idx = mhop.l0_idx * chunk_ba_num + mhop.l1_idx;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
hem_idx = mhop.l0_idx * chunk_ba_num + mhop.l1_idx;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
hem_idx = mhop.l0_idx;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dev_err(dev, "Table %d not support hop_num = %d!\n",
|
|
||||||
table->type, hop_num);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&table->mutex);
|
mutex_lock(&table->mutex);
|
||||||
|
if (check_refcount && (--table->hem[index.buf]->refcount > 0)) {
|
||||||
if (check_refcount && (--table->hem[hem_idx]->refcount > 0)) {
|
|
||||||
mutex_unlock(&table->mutex);
|
mutex_unlock(&table->mutex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table->type < HEM_TYPE_MTT && hop_num == 1) {
|
clear_mhop_hem(hr_dev, table, obj, &mhop, &index);
|
||||||
if (hr_dev->hw->clear_hem(hr_dev, table, obj, 1))
|
free_mhop_hem(hr_dev, table, &mhop, &index);
|
||||||
dev_warn(dev, "Clear HEM base address failed.\n");
|
|
||||||
} else if (table->type < HEM_TYPE_MTT && hop_num == 2) {
|
|
||||||
if (hr_dev->hw->clear_hem(hr_dev, table, obj, 2))
|
|
||||||
dev_warn(dev, "Clear HEM base address failed.\n");
|
|
||||||
} else if (table->type < HEM_TYPE_MTT &&
|
|
||||||
hop_num == HNS_ROCE_HOP_NUM_0) {
|
|
||||||
if (hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
|
|
||||||
dev_warn(dev, "Clear HEM base address failed.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* free buffer space chunk for QPC/MTPT/CQC/SRQC/SCCC.
|
|
||||||
* free bt space chunk for MTT/CQE.
|
|
||||||
*/
|
|
||||||
hns_roce_free_hem(hr_dev, table->hem[hem_idx]);
|
|
||||||
table->hem[hem_idx] = NULL;
|
|
||||||
|
|
||||||
if (check_whether_bt_num_2(table->type, hop_num)) {
|
|
||||||
start_idx = mhop.l0_idx * chunk_ba_num;
|
|
||||||
if (hns_roce_check_hem_null(table->hem, start_idx,
|
|
||||||
chunk_ba_num, table->num_hem)) {
|
|
||||||
if (table->type < HEM_TYPE_MTT &&
|
|
||||||
hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
|
|
||||||
dev_warn(dev, "Clear HEM base address failed.\n");
|
|
||||||
|
|
||||||
dma_free_coherent(dev, bt_chunk_size,
|
|
||||||
table->bt_l0[mhop.l0_idx],
|
|
||||||
table->bt_l0_dma_addr[mhop.l0_idx]);
|
|
||||||
table->bt_l0[mhop.l0_idx] = NULL;
|
|
||||||
}
|
|
||||||
} else if (check_whether_bt_num_3(table->type, hop_num)) {
|
|
||||||
start_idx = mhop.l0_idx * chunk_ba_num * chunk_ba_num +
|
|
||||||
mhop.l1_idx * chunk_ba_num;
|
|
||||||
if (hns_roce_check_hem_null(table->hem, start_idx,
|
|
||||||
chunk_ba_num, table->num_hem)) {
|
|
||||||
if (hr_dev->hw->clear_hem(hr_dev, table, obj, 1))
|
|
||||||
dev_warn(dev, "Clear HEM base address failed.\n");
|
|
||||||
|
|
||||||
dma_free_coherent(dev, bt_chunk_size,
|
|
||||||
table->bt_l1[bt_l1_idx],
|
|
||||||
table->bt_l1_dma_addr[bt_l1_idx]);
|
|
||||||
table->bt_l1[bt_l1_idx] = NULL;
|
|
||||||
|
|
||||||
start_idx = mhop.l0_idx * chunk_ba_num;
|
|
||||||
if (hns_roce_check_bt_null(table->bt_l1, start_idx,
|
|
||||||
chunk_ba_num)) {
|
|
||||||
if (hr_dev->hw->clear_hem(hr_dev, table, obj,
|
|
||||||
0))
|
|
||||||
dev_warn(dev, "Clear HEM base address failed.\n");
|
|
||||||
|
|
||||||
dma_free_coherent(dev, bt_chunk_size,
|
|
||||||
table->bt_l0[mhop.l0_idx],
|
|
||||||
table->bt_l0_dma_addr[mhop.l0_idx]);
|
|
||||||
table->bt_l0[mhop.l0_idx] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&table->mutex);
|
mutex_unlock(&table->mutex);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user