From: Junxian Huang huangjunxian6@hisilicon.com
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: 523f34d81ea7 ("RDMA/hns: Support congestion control algorithm parameter configuration") Signed-off-by: Junxian Huang huangjunxian6@hisilicon.com Signed-off-by: Xinghai Cen cenxinghai@h-partners.com --- drivers/infiniband/hw/hns/hns_roce_device.h | 1 + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 13 ++++++++++--- drivers/infiniband/hw/hns/hns_roce_sysfs.c | 6 +++++- 3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 031279e5c539..13b69b74be85 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -1115,6 +1115,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 { diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index e3afac18f442..c084f9305668 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -7461,11 +7461,16 @@ 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; + 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, @@ -7501,7 +7506,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; } diff --git a/drivers/infiniband/hw/hns/hns_roce_sysfs.c b/drivers/infiniband/hw/hns/hns_roce_sysfs.c index 3a2b1aceddd8..4a87741addba 100644 --- a/drivers/infiniband/hw/hns/hns_roce_sysfs.c +++ b/drivers/infiniband/hw/hns/hns_roce_sysfs.c @@ -102,7 +102,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)); }