Commit 6dfd6623 authored by Junxian Huang's avatar Junxian Huang Committed by Chengchang Tang
Browse files

RDMA/hns: Fix wrong output of sysfs scc pram when configuration failed

driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAL7SX



----------------------------------------------------------------------

param[] in struct hns_roce_scc_param is used to store and show scc
params both. But when the configuration to HW fails, the params
stored in this array will become different from the ones in HW.

Add an member latest_param[] to struct hns_roce_scc_param to store
the latest configured value of scc params. It will be modified only
after the configuration has succeeded to ensure the shown result
from sysfs is always the correct param in HW even if the previous
configuration failed. The original member param[] is only used to
store the temporary value of sysfs input now.

Fixes: 523f34d8 ("RDMA/hns: Support congestion control algorithm parameter configuration")
Signed-off-by: default avatarJunxian Huang <huangjunxian6@hisilicon.com>
Signed-off-by: default avatarXinghai Cen <cenxinghai@h-partners.com>
parent 91496e88
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1130,6 +1130,7 @@ struct hns_roce_scc_param {
	struct delayed_work scc_cfg_dwork;
	struct hns_roce_dev *hr_dev;
	u8 port_num;
	__le32 latest_param[HNS_ROCE_SCC_PARAM_SIZE];
};

struct hns_roce_port {
+10 −3
Original line number Diff line number Diff line
@@ -7600,13 +7600,18 @@ static int hns_roce_v2_config_scc_param(struct hns_roce_dev *hr_dev,
	memcpy(&desc.data, scc_param, sizeof(scc_param->param));

	ret = hns_roce_cmq_send(hr_dev, &desc, 1);
	if (ret)
	if (ret) {
		ibdev_err_ratelimited(&hr_dev->ib_dev,
				      "failed to configure scc param, opcode: 0x%x, ret = %d.\n",
			le16_to_cpu(desc.opcode), ret);
		return ret;
	}

	memcpy(scc_param->latest_param, &desc.data,
	       sizeof(scc_param->latest_param));
	return 0;
}

static int hns_roce_v2_query_scc_param(struct hns_roce_dev *hr_dev,
				       u8 port_num, enum hns_roce_scc_algo algo)
{
@@ -7640,7 +7645,9 @@ static int hns_roce_v2_query_scc_param(struct hns_roce_dev *hr_dev,

	pdata = &hr_dev->port_data[port_num - 1];
	scc_param = &pdata->scc_param[algo];
	memcpy(scc_param, &desc.data, sizeof(scc_param->param));
	memcpy(scc_param->param, &desc.data, sizeof(scc_param->param));
	memcpy(scc_param->latest_param, &desc.data,
	       sizeof(scc_param->latest_param));

	return 0;
}
+5 −1
Original line number Diff line number Diff line
@@ -202,7 +202,11 @@ static ssize_t scc_attr_show(struct hns_roce_port *pdata,

	scc_param = &pdata->scc_param[scc_attr->algo_type];

	memcpy(&val, (void *)scc_param + scc_attr->offset, scc_attr->size);
	if (scc_attr->offset == offsetof(typeof(*scc_param), lifespan))
		val = scc_param->lifespan;
	else
		memcpy(&val, (void *)scc_param->latest_param + scc_attr->offset,
		       scc_attr->size);

	return sysfs_emit(buf, "%u\n", le32_to_cpu(val));
}