public inbox for linux-rdma@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH for-next 0/3] RDMA/hns: Support congestion control algorithm parameter configuration by debugfs
@ 2026-02-06 10:31 Junxian Huang
  2026-02-06 10:31 ` [PATCH for-next 1/3] RDMA/hns: Initialize seqfile before creating file Junxian Huang
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Junxian Huang @ 2026-02-06 10:31 UTC (permalink / raw)
  To: jgg, leon; +Cc: linux-rdma, linuxarm, huangjunxian6, tangchengchang

This series adds support for congestion control algorithm parameter
configuration by debugfs.

Chengchang Tang (1):
  RDMA/hns: Support congestion control algorithm parameter configuration

Junxian Huang (2):
  RDMA/hns: Initialize seqfile before creating file
  RDMA/hns: Add write support to debugfs

 drivers/infiniband/hw/hns/hns_roce_debugfs.c | 318 ++++++++++++++++++-
 drivers/infiniband/hw/hns/hns_roce_debugfs.h |  26 ++
 drivers/infiniband/hw/hns/hns_roce_device.h  |  25 ++
 drivers/infiniband/hw/hns/hns_roce_hw_v2.c   |  66 ++++
 drivers/infiniband/hw/hns/hns_roce_hw_v2.h   | 140 ++++++++
 5 files changed, 570 insertions(+), 5 deletions(-)

--
2.33.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH for-next 1/3] RDMA/hns: Initialize seqfile before creating file
  2026-02-06 10:31 [PATCH for-next 0/3] RDMA/hns: Support congestion control algorithm parameter configuration by debugfs Junxian Huang
@ 2026-02-06 10:31 ` Junxian Huang
  2026-02-06 10:31 ` [PATCH for-next 2/3] RDMA/hns: Add write support to debugfs Junxian Huang
  2026-02-06 10:31 ` [PATCH for-next 3/3] RDMA/hns: Support congestion control algorithm parameter configuration Junxian Huang
  2 siblings, 0 replies; 10+ messages in thread
From: Junxian Huang @ 2026-02-06 10:31 UTC (permalink / raw)
  To: jgg, leon; +Cc: linux-rdma, linuxarm, huangjunxian6, tangchengchang

The debugfs file was created before seq->read and seq->data were set,
leaving a small window where userspace could access an uninitialized
seqfile. Move debugfs_create_file() after the assignments to avoid
this issue.

Fixes: ca7ad04cd5d2 ("RDMA/hns: Add debugfs to hns RoCE")
Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
---
 drivers/infiniband/hw/hns/hns_roce_debugfs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_debugfs.c b/drivers/infiniband/hw/hns/hns_roce_debugfs.c
index b869cdc54118..3f0a692e6ac7 100644
--- a/drivers/infiniband/hw/hns/hns_roce_debugfs.c
+++ b/drivers/infiniband/hw/hns/hns_roce_debugfs.c
@@ -31,10 +31,10 @@ static void init_debugfs_seqfile(struct hns_debugfs_seqfile *seq,
 				 int (*read_fn)(struct seq_file *, void *),
 				 void *data)
 {
-	debugfs_create_file(name, 0400, parent, seq, &hns_debugfs_seqfile_fops);
-
 	seq->read = read_fn;
 	seq->data = data;
+
+	debugfs_create_file(name, 0400, parent, seq, &hns_debugfs_seqfile_fops);
 }
 
 static const char * const sw_stat_info[] = {
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH for-next 2/3] RDMA/hns: Add write support to debugfs
  2026-02-06 10:31 [PATCH for-next 0/3] RDMA/hns: Support congestion control algorithm parameter configuration by debugfs Junxian Huang
  2026-02-06 10:31 ` [PATCH for-next 1/3] RDMA/hns: Initialize seqfile before creating file Junxian Huang
@ 2026-02-06 10:31 ` Junxian Huang
  2026-02-12 16:55   ` Leon Romanovsky
  2026-02-06 10:31 ` [PATCH for-next 3/3] RDMA/hns: Support congestion control algorithm parameter configuration Junxian Huang
  2 siblings, 1 reply; 10+ messages in thread
From: Junxian Huang @ 2026-02-06 10:31 UTC (permalink / raw)
  To: jgg, leon; +Cc: linux-rdma, linuxarm, huangjunxian6, tangchengchang

Add write support to debugfs.

Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
---
 drivers/infiniband/hw/hns/hns_roce_debugfs.c | 38 +++++++++++++++++---
 drivers/infiniband/hw/hns/hns_roce_debugfs.h |  1 +
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_debugfs.c b/drivers/infiniband/hw/hns/hns_roce_debugfs.c
index 3f0a692e6ac7..32773ffb6f6e 100644
--- a/drivers/infiniband/hw/hns/hns_roce_debugfs.c
+++ b/drivers/infiniband/hw/hns/hns_roce_debugfs.c
@@ -18,23 +18,50 @@ static int hns_debugfs_seqfile_open(struct inode *inode, struct file *f)
 	return single_open(f, seqfile->read, seqfile->data);
 }
 
+static ssize_t hns_debugfs_seqfile_write(struct file *file,
+					 const char __user *buffer,
+					 size_t count, loff_t *ppos)
+{
+	struct hns_debugfs_seqfile *seqfile = file_inode(file)->i_private;
+	char buf[16] = {};
+
+	if (!seqfile->write)
+		return -EOPNOTSUPP;
+
+	if (count >= sizeof(buf))
+		return -EINVAL;
+
+	if (copy_from_user(buf, buffer, count))
+		return -EFAULT;
+
+	return seqfile->write(buf, count, seqfile->data);
+}
+
 static const struct file_operations hns_debugfs_seqfile_fops = {
 	.owner = THIS_MODULE,
 	.open = hns_debugfs_seqfile_open,
 	.release = single_release,
 	.read = seq_read,
+	.write = hns_debugfs_seqfile_write,
 	.llseek = seq_lseek
 };
 
+struct hns_debugfs_rw_ops {
+	int (*read)(struct seq_file *seq, void *data);
+	ssize_t (*write)(char *buf, size_t count, void *data);
+};
+
 static void init_debugfs_seqfile(struct hns_debugfs_seqfile *seq,
 				 const char *name, struct dentry *parent,
-				 int (*read_fn)(struct seq_file *, void *),
+				 const struct hns_debugfs_rw_ops *ops,
 				 void *data)
 {
-	seq->read = read_fn;
+	seq->read = ops->read;
+	seq->write = ops->write;
 	seq->data = data;
 
-	debugfs_create_file(name, 0400, parent, seq, &hns_debugfs_seqfile_fops);
+	debugfs_create_file(name, ops->write ? 0600 : 0400, parent,
+			    seq, &hns_debugfs_seqfile_fops);
 }
 
 static const char * const sw_stat_info[] = {
@@ -75,11 +102,14 @@ static void create_sw_stat_debugfs(struct hns_roce_dev *hr_dev,
 				   struct dentry *parent)
 {
 	struct hns_sw_stat_debugfs *dbgfs = &hr_dev->dbgfs.sw_stat_root;
+	const struct hns_debugfs_rw_ops ops = {
+		.read = sw_stat_debugfs_show,
+	};
 
 	dbgfs->root = debugfs_create_dir("sw_stat", parent);
 
 	init_debugfs_seqfile(&dbgfs->sw_stat, "sw_stat", dbgfs->root,
-			     sw_stat_debugfs_show, hr_dev);
+			     &ops, hr_dev);
 }
 
 /* debugfs for device */
diff --git a/drivers/infiniband/hw/hns/hns_roce_debugfs.h b/drivers/infiniband/hw/hns/hns_roce_debugfs.h
index 98e87bd3161e..4e77dea0fbf6 100644
--- a/drivers/infiniband/hw/hns/hns_roce_debugfs.h
+++ b/drivers/infiniband/hw/hns/hns_roce_debugfs.h
@@ -9,6 +9,7 @@
 /* debugfs seqfile */
 struct hns_debugfs_seqfile {
 	int (*read)(struct seq_file *seq, void *data);
+	ssize_t (*write)(char *buf, size_t count, void *data);
 	void *data;
 };
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH for-next 3/3] RDMA/hns: Support congestion control algorithm parameter configuration
  2026-02-06 10:31 [PATCH for-next 0/3] RDMA/hns: Support congestion control algorithm parameter configuration by debugfs Junxian Huang
  2026-02-06 10:31 ` [PATCH for-next 1/3] RDMA/hns: Initialize seqfile before creating file Junxian Huang
  2026-02-06 10:31 ` [PATCH for-next 2/3] RDMA/hns: Add write support to debugfs Junxian Huang
@ 2026-02-06 10:31 ` Junxian Huang
  2026-02-12 16:57   ` Leon Romanovsky
  2 siblings, 1 reply; 10+ messages in thread
From: Junxian Huang @ 2026-02-06 10:31 UTC (permalink / raw)
  To: jgg, leon; +Cc: linux-rdma, linuxarm, huangjunxian6, tangchengchang

From: Chengchang Tang <tangchengchang@huawei.com>

hns RoCE supports 4 congestion control algorithms. Each algorihm
involves multiple parameters. Support configuring these parameters
by debugfs.

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
---
 drivers/infiniband/hw/hns/hns_roce_debugfs.c | 278 +++++++++++++++++++
 drivers/infiniband/hw/hns/hns_roce_debugfs.h |  25 ++
 drivers/infiniband/hw/hns/hns_roce_device.h  |  25 ++
 drivers/infiniband/hw/hns/hns_roce_hw_v2.c   |  66 +++++
 drivers/infiniband/hw/hns/hns_roce_hw_v2.h   | 140 ++++++++++
 5 files changed, 534 insertions(+)

diff --git a/drivers/infiniband/hw/hns/hns_roce_debugfs.c b/drivers/infiniband/hw/hns/hns_roce_debugfs.c
index 32773ffb6f6e..57bf639e730a 100644
--- a/drivers/infiniband/hw/hns/hns_roce_debugfs.c
+++ b/drivers/infiniband/hw/hns/hns_roce_debugfs.c
@@ -3,11 +3,13 @@
  * Copyright (c) 2023 Hisilicon Limited.
  */
 
+#include <linux/cleanup.h>
 #include <linux/debugfs.h>
 #include <linux/device.h>
 #include <linux/pci.h>
 
 #include "hns_roce_device.h"
+#include "hns_roce_hw_v2.h"
 
 static struct dentry *hns_roce_dbgfs_root;
 
@@ -112,6 +114,280 @@ static void create_sw_stat_debugfs(struct hns_roce_dev *hr_dev,
 			     &ops, hr_dev);
 }
 
+#define __HNS_SCC_ATTR(_name, _type, _offset, _size, _min, _max) {	\
+	.name = _name,							\
+	.algo_type = _type,						\
+	.offset = _offset,						\
+	.size = _size,							\
+	.min = _min,							\
+	.max = _max,							\
+}
+
+#define HNS_DCQCN_CC_ATTR_RW(_name, NAME)				\
+	__HNS_SCC_ATTR(_name, HNS_ROCE_SCC_ALGO_DCQCN,			\
+			HNS_ROCE_DCQCN_##NAME##_OFS,			\
+			HNS_ROCE_DCQCN_##NAME##_SZ,			\
+			0, HNS_ROCE_DCQCN_##NAME##_MAX)
+
+#define HNS_LDCP_CC_ATTR_RW(_name, NAME)				\
+	__HNS_SCC_ATTR(_name, HNS_ROCE_SCC_ALGO_LDCP,			\
+			HNS_ROCE_LDCP_##NAME##_OFS,			\
+			HNS_ROCE_LDCP_##NAME##_SZ,			\
+			0, HNS_ROCE_LDCP_##NAME##_MAX)
+
+#define HNS_HC3_CC_ATTR_RW(_name, NAME)				\
+	__HNS_SCC_ATTR(_name, HNS_ROCE_SCC_ALGO_HC3,			\
+			HNS_ROCE_HC3_##NAME##_OFS,			\
+			HNS_ROCE_HC3_##NAME##_SZ,			\
+			HNS_ROCE_HC3_##NAME##_MIN,			\
+			HNS_ROCE_HC3_##NAME##_MAX)
+
+#define HNS_DIP_CC_ATTR_RW(_name, NAME)				\
+	__HNS_SCC_ATTR(_name, HNS_ROCE_SCC_ALGO_DIP,			\
+			HNS_ROCE_DIP_##NAME##_OFS,			\
+			HNS_ROCE_DIP_##NAME##_SZ,			\
+			0, HNS_ROCE_DIP_##NAME##_MAX)
+
+static const struct hns_roce_cong_attr {
+	enum hns_roce_cong_type cong_type;
+	const char *name;
+	struct hns_roce_cc_param_attr params[HNS_ROCE_CC_PARAM_MAX_NUM];
+} cong_attrs[] = {
+	{ CONG_TYPE_DCQCN, "dcqcn_cc_param",
+		{
+			HNS_DCQCN_CC_ATTR_RW("ai", AI),
+			HNS_DCQCN_CC_ATTR_RW("f", F),
+			HNS_DCQCN_CC_ATTR_RW("tkp", TKP),
+			HNS_DCQCN_CC_ATTR_RW("tmp", TMP),
+			HNS_DCQCN_CC_ATTR_RW("alp", ALP),
+			HNS_DCQCN_CC_ATTR_RW("max_speed", MAX_SPEED),
+			HNS_DCQCN_CC_ATTR_RW("g", G),
+			HNS_DCQCN_CC_ATTR_RW("al", AL),
+			HNS_DCQCN_CC_ATTR_RW("cnp_time", CNP_TIME),
+			HNS_DCQCN_CC_ATTR_RW("ashift", ASHIFT),
+			HNS_DCQCN_CC_ATTR_RW("lifespan", LIFESPAN)
+		}
+	},
+	{ CONG_TYPE_LDCP, "ldcp_cc_param",
+		{
+			HNS_LDCP_CC_ATTR_RW("cwd0", CWD0),
+			HNS_LDCP_CC_ATTR_RW("alpha", ALPHA),
+			HNS_LDCP_CC_ATTR_RW("gamma", GAMMA),
+			HNS_LDCP_CC_ATTR_RW("beta", BETA),
+			HNS_LDCP_CC_ATTR_RW("eta", ETA),
+			HNS_LDCP_CC_ATTR_RW("lifespan", LIFESPAN),
+		}
+	},
+	{ CONG_TYPE_HC3, "hc3_cc_param",
+		{
+			HNS_HC3_CC_ATTR_RW("initial_window", INITIAL_WINDOW),
+			HNS_HC3_CC_ATTR_RW("bandwidth", BANDWIDTH),
+			HNS_HC3_CC_ATTR_RW("qlen_shift", QLEN_SHIFT),
+			HNS_HC3_CC_ATTR_RW("port_usage_shift", PORT_USAGE_SHIFT),
+			HNS_HC3_CC_ATTR_RW("over_period", OVER_PERIOD),
+			HNS_HC3_CC_ATTR_RW("max_stage", MAX_STAGE),
+			HNS_HC3_CC_ATTR_RW("gamma_shift", GAMMA_SHIFT),
+			HNS_HC3_CC_ATTR_RW("lifespan", LIFESPAN),
+		}
+	},
+	{ CONG_TYPE_DIP, "dip_cc_param",
+		{
+			HNS_DIP_CC_ATTR_RW("ai", AI),
+			HNS_DIP_CC_ATTR_RW("f", F),
+			HNS_DIP_CC_ATTR_RW("tkp", TKP),
+			HNS_DIP_CC_ATTR_RW("tmp", TMP),
+			HNS_DIP_CC_ATTR_RW("alp", ALP),
+			HNS_DIP_CC_ATTR_RW("max_speed", MAX_SPEED),
+			HNS_DIP_CC_ATTR_RW("g", G),
+			HNS_DIP_CC_ATTR_RW("al", AL),
+			HNS_DIP_CC_ATTR_RW("cnp_time", CNP_TIME),
+			HNS_DIP_CC_ATTR_RW("ashift", ASHIFT),
+			HNS_DIP_CC_ATTR_RW("lifespan", LIFESPAN),
+		}
+	}
+};
+
+static int cc_param_debugfs_show(struct seq_file *file, void *offset)
+{
+	struct hns_cc_param_seqfile *param_seqfile = file->private;
+	const struct hns_roce_cc_param_attr *param_attr = param_seqfile->param_attr;
+	int algo_type = param_attr->algo_type;
+	int index = param_seqfile->index;
+	struct hns_roce_dev *hr_dev =
+		container_of(param_seqfile, struct hns_roce_dev,
+			     dbgfs.cc_param_root[algo_type].params[index]);
+	struct hns_roce_scc_param *scc_param;
+	__le32 val = 0;
+
+	scc_param = &hr_dev->scc_param[algo_type];
+
+	scoped_guard(mutex, &scc_param->scc_mutex) {
+		if (param_attr->offset == offsetof(typeof(*scc_param), lifespan))
+			val = scc_param->lifespan;
+		else
+			memcpy(&val,
+			       (void *)scc_param->latest_param + param_attr->offset,
+			       param_attr->size);
+	}
+
+	seq_printf(file, "%u\n", le32_to_cpu(val));
+
+	return 0;
+}
+
+static ssize_t cc_param_debugfs_store(char *buf, size_t count, void *data)
+{
+	struct hns_cc_param_seqfile *param_seqfile = data;
+	const struct hns_roce_cc_param_attr *param_attr = param_seqfile->param_attr;
+	int algo_type = param_attr->algo_type;
+	int index = param_seqfile->index;
+	struct hns_roce_dev *hr_dev =
+		container_of(param_seqfile, struct hns_roce_dev,
+			     dbgfs.cc_param_root[algo_type].params[index]);
+	struct hns_roce_scc_param *scc_param;
+	unsigned long lifespan_jiffies;
+	unsigned long exp_time;
+	__le32 attr_val;
+	u32 val;
+
+	if (kstrtou32(buf, 0, &val))
+		return -EINVAL;
+
+	if (val > param_attr->max || val < param_attr->min)
+		return -EINVAL;
+
+	attr_val = cpu_to_le32(val);
+	scc_param = &hr_dev->scc_param[algo_type];
+	scoped_guard(mutex, &scc_param->scc_mutex) {
+		memcpy((void *)scc_param + param_attr->offset, &attr_val,
+		       param_attr->size);
+	}
+
+	/* lifespan is only used for driver */
+	if (param_attr->offset >= offsetof(typeof(*scc_param), lifespan))
+		return count;
+
+	lifespan_jiffies = msecs_to_jiffies(le32_to_cpu(scc_param->lifespan));
+	exp_time = scc_param->timestamp + lifespan_jiffies;
+
+	if (time_is_before_eq_jiffies(exp_time)) {
+		scc_param->timestamp = jiffies;
+		queue_delayed_work(hr_dev->irq_workq, &scc_param->scc_cfg_dwork,
+				   lifespan_jiffies);
+	}
+
+	return count;
+}
+
+static void scc_param_config_work(struct work_struct *work)
+{
+	struct hns_roce_scc_param *scc_param = container_of(work,
+			struct hns_roce_scc_param, scc_cfg_dwork.work);
+	struct hns_roce_dev *hr_dev = scc_param->hr_dev;
+
+	hr_dev->hw->config_scc_param(hr_dev, scc_param->algo_type);
+}
+
+static void get_default_scc_param(struct hns_roce_dev *hr_dev)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < HNS_ROCE_SCC_ALGO_TOTAL; i++) {
+		hr_dev->scc_param[i].timestamp = jiffies;
+		ret = hr_dev->hw->query_scc_param(hr_dev, i);
+		if (ret && ret != -EOPNOTSUPP)
+			ibdev_warn_ratelimited(&hr_dev->ib_dev,
+					       "failed to get default parameters of scc algo %d, ret = %d.\n",
+					       i, ret);
+	}
+}
+
+static int hns_roce_alloc_scc_param(struct hns_roce_dev *hr_dev)
+{
+	struct hns_roce_scc_param *scc_param;
+	int i;
+
+	scc_param = kvcalloc(HNS_ROCE_SCC_ALGO_TOTAL, sizeof(*scc_param),
+			     GFP_KERNEL);
+	if (!scc_param)
+		return -ENOMEM;
+
+	for (i = 0; i < HNS_ROCE_SCC_ALGO_TOTAL; i++) {
+		scc_param[i].algo_type = i;
+		scc_param[i].hr_dev = hr_dev;
+		mutex_init(&scc_param[i].scc_mutex);
+		INIT_DELAYED_WORK(&scc_param[i].scc_cfg_dwork,
+				  scc_param_config_work);
+	}
+
+	hr_dev->scc_param = scc_param;
+
+	get_default_scc_param(hr_dev);
+
+	return 0;
+}
+
+static void hns_roce_dealloc_scc_param(struct hns_roce_dev *hr_dev)
+{
+	int i;
+
+	if (!hr_dev->scc_param)
+		return;
+
+	for (i = 0; i < HNS_ROCE_SCC_ALGO_TOTAL; i++) {
+		cancel_delayed_work_sync(&hr_dev->scc_param[i].scc_cfg_dwork);
+		mutex_destroy(&hr_dev->scc_param[i].scc_mutex);
+	}
+
+	kvfree(hr_dev->scc_param);
+}
+
+static void create_cc_param_debugfs(struct hns_roce_dev *hr_dev,
+				    struct dentry *parent)
+{
+	const struct hns_roce_cong_attr *cong_attr;
+	struct hns_cc_param_debugfs *dbgfs;
+	const struct hns_debugfs_rw_ops ops = {
+		.read = cc_param_debugfs_show,
+		.write = cc_param_debugfs_store,
+	};
+	int i, j;
+	int ret;
+
+	if (hr_dev->pci_dev->revision <= PCI_REVISION_ID_HIP08 ||
+	    !(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL) ||
+	    hr_dev->is_vf)
+		return;
+
+	ret = hns_roce_alloc_scc_param(hr_dev);
+	if (ret) {
+		dev_err(hr_dev->dev, "alloc scc param failed, ret = %d!\n",
+			ret);
+		return;
+	}
+
+	for (i = 0; i < CONG_TYPE_MAX_NUM; i++) {
+		cong_attr = &cong_attrs[i];
+		if (!test_bit(cong_attr->cong_type,
+			      (unsigned long *)&hr_dev->caps.cong_cap))
+			continue;
+
+		dbgfs = &hr_dev->dbgfs.cc_param_root[i];
+		dbgfs->root = debugfs_create_dir(cong_attr->name, parent);
+		for (j = 0; j < HNS_ROCE_CC_PARAM_MAX_NUM; j++) {
+			if (!cong_attr->params[j].name)
+				break;
+			dbgfs->params[j].param_attr = &cong_attr->params[j];
+			dbgfs->params[j].index = j;
+			init_debugfs_seqfile(&dbgfs->params[j].seqfile,
+					     cong_attr->params[j].name,
+					     dbgfs->root, &ops,
+					     &dbgfs->params[j]);
+		}
+	}
+}
+
 /* debugfs for device */
 void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev)
 {
@@ -121,11 +397,13 @@ void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev)
 					 hns_roce_dbgfs_root);
 
 	create_sw_stat_debugfs(hr_dev, dbgfs->root);
+	create_cc_param_debugfs(hr_dev, dbgfs->root);
 }
 
 void hns_roce_unregister_debugfs(struct hns_roce_dev *hr_dev)
 {
 	debugfs_remove_recursive(hr_dev->dbgfs.root);
+	hns_roce_dealloc_scc_param(hr_dev);
 }
 
 /* debugfs for hns module */
diff --git a/drivers/infiniband/hw/hns/hns_roce_debugfs.h b/drivers/infiniband/hw/hns/hns_roce_debugfs.h
index 4e77dea0fbf6..116b1e8b6677 100644
--- a/drivers/infiniband/hw/hns/hns_roce_debugfs.h
+++ b/drivers/infiniband/hw/hns/hns_roce_debugfs.h
@@ -18,10 +18,35 @@ struct hns_sw_stat_debugfs {
 	struct hns_debugfs_seqfile sw_stat;
 };
 
+struct hns_roce_cc_param_attr {
+	const char *name;
+	int algo_type;
+	u32 offset;
+	u32 size;
+	u32 max;
+	u32 min;
+};
+
+struct hns_cc_param_seqfile {
+	struct hns_debugfs_seqfile seqfile;
+	const struct hns_roce_cc_param_attr *param_attr;
+	int index;
+};
+
+#define HNS_ROCE_CC_PARAM_MAX_NUM 11
+
+struct hns_cc_param_debugfs {
+	struct dentry *root;
+	struct hns_cc_param_seqfile params[HNS_ROCE_CC_PARAM_MAX_NUM];
+};
+
+#define CONG_TYPE_MAX_NUM 4
+
 /* Debugfs for device */
 struct hns_roce_dev_debugfs {
 	struct dentry *root;
 	struct hns_sw_stat_debugfs sw_stat_root;
+	struct hns_cc_param_debugfs cc_param_root[CONG_TYPE_MAX_NUM];
 };
 
 struct hns_roce_dev;
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
index 3f032b8038af..7b3326dfaa4a 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -726,6 +726,14 @@ struct hns_roce_eq_table {
 	struct hns_roce_eq	*eq;
 };
 
+enum hns_roce_scc_algo {
+	HNS_ROCE_SCC_ALGO_DCQCN = 0,
+	HNS_ROCE_SCC_ALGO_LDCP,
+	HNS_ROCE_SCC_ALGO_HC3,
+	HNS_ROCE_SCC_ALGO_DIP,
+	HNS_ROCE_SCC_ALGO_TOTAL,
+};
+
 struct hns_roce_caps {
 	u64		fw_ver;
 	u8		num_ports;
@@ -963,6 +971,22 @@ struct hns_roce_hw {
 			u8 *tc_mode, u8 *priority);
 	const struct ib_device_ops *hns_roce_dev_ops;
 	const struct ib_device_ops *hns_roce_dev_srq_ops;
+	int (*config_scc_param)(struct hns_roce_dev *hr_dev,
+				enum hns_roce_scc_algo algo);
+	int (*query_scc_param)(struct hns_roce_dev *hr_dev,
+			       enum hns_roce_scc_algo alog);
+};
+
+#define HNS_ROCE_SCC_PARAM_SIZE 4
+struct hns_roce_scc_param {
+	__le32 param[HNS_ROCE_SCC_PARAM_SIZE];
+	__le32 lifespan;
+	unsigned long timestamp;
+	enum hns_roce_scc_algo algo_type;
+	struct delayed_work scc_cfg_dwork;
+	struct hns_roce_dev *hr_dev;
+	__le32 latest_param[HNS_ROCE_SCC_PARAM_SIZE];
+	struct mutex scc_mutex; /* protect @param and @lastest_param */
 };
 
 struct hns_roce_dev {
@@ -1026,6 +1050,7 @@ struct hns_roce_dev {
 	u64 dwqe_page;
 	struct hns_roce_dev_debugfs dbgfs;
 	atomic64_t *dfx_cnt;
+	struct hns_roce_scc_param *scc_param;
 };
 
 enum hns_roce_trace_type {
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
index 5d0a8662249d..3f9b196a7964 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
@@ -31,6 +31,7 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/cleanup.h>
 #include <linux/etherdevice.h>
 #include <linux/interrupt.h>
 #include <linux/iopoll.h>
@@ -7196,6 +7197,69 @@ static void hns_roce_v2_cleanup_eq_table(struct hns_roce_dev *hr_dev)
 	kfree(eq_table->eq);
 }
 
+static const enum hns_roce_opcode_type scc_opcode[] = {
+	HNS_ROCE_OPC_CFG_DCQCN_PARAM,
+	HNS_ROCE_OPC_CFG_LDCP_PARAM,
+	HNS_ROCE_OPC_CFG_HC3_PARAM,
+	HNS_ROCE_OPC_CFG_DIP_PARAM,
+};
+
+static int hns_roce_v2_config_scc_param(struct hns_roce_dev *hr_dev,
+					enum hns_roce_scc_algo algo)
+{
+	struct hns_roce_scc_param *scc_param;
+	struct hns_roce_cmq_desc desc;
+	int ret;
+
+	hns_roce_cmq_setup_basic_desc(&desc, scc_opcode[algo], false);
+	scc_param = &hr_dev->scc_param[algo];
+
+	scoped_guard(mutex, &scc_param->scc_mutex) {
+		memcpy(&desc.data, scc_param, sizeof(scc_param->param));
+
+		ret = hns_roce_cmq_send(hr_dev, &desc, 1);
+		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);
+			memcpy(scc_param->param, scc_param->latest_param,
+			       sizeof(scc_param->param));
+			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,
+				       enum hns_roce_scc_algo algo)
+{
+	struct hns_roce_scc_param *scc_param;
+	struct hns_roce_cmq_desc desc;
+	int ret;
+
+	hns_roce_cmq_setup_basic_desc(&desc, scc_opcode[algo], true);
+	ret = hns_roce_cmq_send(hr_dev, &desc, 1);
+	if (ret) {
+		ibdev_err_ratelimited(&hr_dev->ib_dev,
+				      "failed to query scc param, opcode: 0x%x, ret = %d.\n",
+				      le16_to_cpu(desc.opcode), ret);
+		return ret;
+	}
+
+	scc_param = &hr_dev->scc_param[algo];
+	scoped_guard(mutex, &scc_param->scc_mutex) {
+		memcpy(scc_param->param, &desc.data, sizeof(scc_param->param));
+		memcpy(scc_param->latest_param, &desc.data,
+		       sizeof(scc_param->latest_param));
+	}
+
+	return 0;
+}
+
 static const struct ib_device_ops hns_roce_v2_dev_ops = {
 	.destroy_qp = hns_roce_v2_destroy_qp,
 	.modify_cq = hns_roce_v2_modify_cq,
@@ -7246,6 +7310,8 @@ static const struct hns_roce_hw hns_roce_hw_v2 = {
 	.get_dscp = hns_roce_hw_v2_get_dscp,
 	.hns_roce_dev_ops = &hns_roce_v2_dev_ops,
 	.hns_roce_dev_srq_ops = &hns_roce_v2_dev_srq_ops,
+	.config_scc_param = hns_roce_v2_config_scc_param,
+	.query_scc_param = hns_roce_v2_query_scc_param,
 };
 
 static const struct pci_device_id hns_roce_hw_v2_pci_tbl[] = {
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
index 285fe0875fac..5540ed315d9a 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
@@ -202,6 +202,10 @@ enum {
 /* CMQ command */
 enum hns_roce_opcode_type {
 	HNS_QUERY_FW_VER				= 0x0001,
+	HNS_ROCE_OPC_CFG_DCQCN_PARAM			= 0x1A80,
+	HNS_ROCE_OPC_CFG_LDCP_PARAM			= 0x1A81,
+	HNS_ROCE_OPC_CFG_HC3_PARAM			= 0x1A82,
+	HNS_ROCE_OPC_CFG_DIP_PARAM			= 0x1A83,
 	HNS_ROCE_OPC_QUERY_HW_VER			= 0x8000,
 	HNS_ROCE_OPC_CFG_GLOBAL_PARAM			= 0x8001,
 	HNS_ROCE_OPC_ALLOC_PF_RES			= 0x8004,
@@ -1459,6 +1463,142 @@ struct hns_roce_wqe_atomic_seg {
 	__le64          cmp_data;
 };
 
+#define HNS_ROCE_DCQCN_AI_OFS 0
+#define HNS_ROCE_DCQCN_AI_SZ sizeof(u16)
+#define HNS_ROCE_DCQCN_AI_MAX ((u16)(~0U))
+#define HNS_ROCE_DCQCN_F_OFS (HNS_ROCE_DCQCN_AI_OFS + HNS_ROCE_DCQCN_AI_SZ)
+#define HNS_ROCE_DCQCN_F_SZ sizeof(u8)
+#define HNS_ROCE_DCQCN_F_MAX ((u8)(~0U))
+#define HNS_ROCE_DCQCN_TKP_OFS (HNS_ROCE_DCQCN_F_OFS + HNS_ROCE_DCQCN_F_SZ)
+#define HNS_ROCE_DCQCN_TKP_SZ sizeof(u8)
+#define HNS_ROCE_DCQCN_TKP_MAX 10
+#define HNS_ROCE_DCQCN_TMP_OFS (HNS_ROCE_DCQCN_TKP_OFS + HNS_ROCE_DCQCN_TKP_SZ)
+#define HNS_ROCE_DCQCN_TMP_SZ sizeof(u16)
+#define HNS_ROCE_DCQCN_TMP_MAX 15
+#define HNS_ROCE_DCQCN_ALP_OFS (HNS_ROCE_DCQCN_TMP_OFS + HNS_ROCE_DCQCN_TMP_SZ)
+#define HNS_ROCE_DCQCN_ALP_SZ sizeof(u16)
+#define HNS_ROCE_DCQCN_ALP_MAX ((u16)(~0U))
+#define HNS_ROCE_DCQCN_MAX_SPEED_OFS (HNS_ROCE_DCQCN_ALP_OFS + \
+					HNS_ROCE_DCQCN_ALP_SZ)
+#define HNS_ROCE_DCQCN_MAX_SPEED_SZ sizeof(u32)
+#define HNS_ROCE_DCQCN_MAX_SPEED_MAX ((u32)(~0U))
+#define HNS_ROCE_DCQCN_G_OFS (HNS_ROCE_DCQCN_MAX_SPEED_OFS + \
+					HNS_ROCE_DCQCN_MAX_SPEED_SZ)
+#define HNS_ROCE_DCQCN_G_SZ sizeof(u8)
+#define HNS_ROCE_DCQCN_G_MAX 15
+#define HNS_ROCE_DCQCN_AL_OFS (HNS_ROCE_DCQCN_G_OFS + HNS_ROCE_DCQCN_G_SZ)
+#define HNS_ROCE_DCQCN_AL_SZ sizeof(u8)
+#define HNS_ROCE_DCQCN_AL_MAX ((u8)(~0U))
+#define HNS_ROCE_DCQCN_CNP_TIME_OFS (HNS_ROCE_DCQCN_AL_OFS + \
+					HNS_ROCE_DCQCN_AL_SZ)
+#define HNS_ROCE_DCQCN_CNP_TIME_SZ sizeof(u8)
+#define HNS_ROCE_DCQCN_CNP_TIME_MAX ((u8)(~0U))
+#define HNS_ROCE_DCQCN_ASHIFT_OFS (HNS_ROCE_DCQCN_CNP_TIME_OFS + \
+					HNS_ROCE_DCQCN_CNP_TIME_SZ)
+#define HNS_ROCE_DCQCN_ASHIFT_SZ sizeof(u8)
+#define HNS_ROCE_DCQCN_ASHIFT_MAX 15
+#define HNS_ROCE_DCQCN_LIFESPAN_OFS (HNS_ROCE_DCQCN_ASHIFT_OFS + \
+					HNS_ROCE_DCQCN_ASHIFT_SZ)
+#define HNS_ROCE_DCQCN_LIFESPAN_SZ sizeof(u32)
+#define HNS_ROCE_DCQCN_LIFESPAN_MAX 1000
+
+#define HNS_ROCE_LDCP_CWD0_OFS 0
+#define HNS_ROCE_LDCP_CWD0_SZ sizeof(u32)
+#define HNS_ROCE_LDCP_CWD0_MAX ((u32)(~0U))
+#define HNS_ROCE_LDCP_ALPHA_OFS (HNS_ROCE_LDCP_CWD0_OFS + HNS_ROCE_LDCP_CWD0_SZ)
+#define HNS_ROCE_LDCP_ALPHA_SZ sizeof(u8)
+#define HNS_ROCE_LDCP_ALPHA_MAX ((u8)(~0U))
+#define HNS_ROCE_LDCP_GAMMA_OFS (HNS_ROCE_LDCP_ALPHA_OFS + \
+					HNS_ROCE_LDCP_ALPHA_SZ)
+#define HNS_ROCE_LDCP_GAMMA_SZ sizeof(u8)
+#define HNS_ROCE_LDCP_GAMMA_MAX 7
+#define HNS_ROCE_LDCP_BETA_OFS (HNS_ROCE_LDCP_GAMMA_OFS + \
+					HNS_ROCE_LDCP_GAMMA_SZ)
+#define HNS_ROCE_LDCP_BETA_SZ sizeof(u8)
+#define HNS_ROCE_LDCP_BETA_MAX 7
+#define HNS_ROCE_LDCP_ETA_OFS (HNS_ROCE_LDCP_BETA_OFS + HNS_ROCE_LDCP_BETA_SZ)
+#define HNS_ROCE_LDCP_ETA_SZ sizeof(u8)
+#define HNS_ROCE_LDCP_ETA_MAX 7
+#define HNS_ROCE_LDCP_LIFESPAN_OFS (4 * sizeof(u32))
+#define HNS_ROCE_LDCP_LIFESPAN_SZ sizeof(u32)
+#define HNS_ROCE_LDCP_LIFESPAN_MAX 1000
+
+#define HNS_ROCE_HC3_INITIAL_WINDOW_OFS 0
+#define HNS_ROCE_HC3_INITIAL_WINDOW_SZ sizeof(u32)
+#define HNS_ROCE_HC3_INITIAL_WINDOW_MIN 0
+#define HNS_ROCE_HC3_INITIAL_WINDOW_MAX ((u32)(~0U))
+#define HNS_ROCE_HC3_BANDWIDTH_OFS (HNS_ROCE_HC3_INITIAL_WINDOW_OFS + \
+					HNS_ROCE_HC3_INITIAL_WINDOW_SZ)
+#define HNS_ROCE_HC3_BANDWIDTH_SZ sizeof(u32)
+#define HNS_ROCE_HC3_BANDWIDTH_MIN 1000
+#define HNS_ROCE_HC3_BANDWIDTH_MAX ((u32)(~0U))
+#define HNS_ROCE_HC3_QLEN_SHIFT_OFS (HNS_ROCE_HC3_BANDWIDTH_OFS + \
+					HNS_ROCE_HC3_BANDWIDTH_SZ)
+#define HNS_ROCE_HC3_QLEN_SHIFT_SZ sizeof(u8)
+#define HNS_ROCE_HC3_QLEN_SHIFT_MIN 0
+#define HNS_ROCE_HC3_QLEN_SHIFT_MAX 31
+#define HNS_ROCE_HC3_PORT_USAGE_SHIFT_OFS (HNS_ROCE_HC3_QLEN_SHIFT_OFS + \
+						HNS_ROCE_HC3_QLEN_SHIFT_SZ)
+#define HNS_ROCE_HC3_PORT_USAGE_SHIFT_SZ sizeof(u8)
+#define HNS_ROCE_HC3_PORT_USAGE_SHIFT_MIN 0
+#define HNS_ROCE_HC3_PORT_USAGE_SHIFT_MAX 100
+#define HNS_ROCE_HC3_OVER_PERIOD_OFS (HNS_ROCE_HC3_PORT_USAGE_SHIFT_OFS + \
+					HNS_ROCE_HC3_PORT_USAGE_SHIFT_SZ)
+#define HNS_ROCE_HC3_OVER_PERIOD_SZ sizeof(u8)
+#define HNS_ROCE_HC3_OVER_PERIOD_MIN 0
+#define HNS_ROCE_HC3_OVER_PERIOD_MAX ((u8)(~0U))
+#define HNS_ROCE_HC3_MAX_STAGE_OFS (HNS_ROCE_HC3_OVER_PERIOD_OFS + \
+					HNS_ROCE_HC3_OVER_PERIOD_SZ)
+#define HNS_ROCE_HC3_MAX_STAGE_SZ sizeof(u8)
+#define HNS_ROCE_HC3_MAX_STAGE_MIN 0
+#define HNS_ROCE_HC3_MAX_STAGE_MAX ((u8)(~0U))
+#define HNS_ROCE_HC3_GAMMA_SHIFT_OFS (HNS_ROCE_HC3_MAX_STAGE_OFS + \
+					HNS_ROCE_HC3_MAX_STAGE_SZ)
+#define HNS_ROCE_HC3_GAMMA_SHIFT_SZ sizeof(u8)
+#define HNS_ROCE_HC3_GAMMA_SHIFT_MIN 0
+#define HNS_ROCE_HC3_GAMMA_SHIFT_MAX 15
+#define HNS_ROCE_HC3_LIFESPAN_OFS (4 * sizeof(u32))
+#define HNS_ROCE_HC3_LIFESPAN_SZ sizeof(u32)
+#define HNS_ROCE_HC3_LIFESPAN_MIN 0
+#define HNS_ROCE_HC3_LIFESPAN_MAX 1000
+
+#define HNS_ROCE_DIP_AI_OFS 0
+#define HNS_ROCE_DIP_AI_SZ sizeof(u16)
+#define HNS_ROCE_DIP_AI_MAX ((u16)(~0U))
+#define HNS_ROCE_DIP_F_OFS (HNS_ROCE_DIP_AI_OFS + HNS_ROCE_DIP_AI_SZ)
+#define HNS_ROCE_DIP_F_SZ sizeof(u8)
+#define HNS_ROCE_DIP_F_MAX ((u8)(~0U))
+#define HNS_ROCE_DIP_TKP_OFS (HNS_ROCE_DIP_F_OFS + HNS_ROCE_DIP_F_SZ)
+#define HNS_ROCE_DIP_TKP_SZ sizeof(u8)
+#define HNS_ROCE_DIP_TKP_MAX 10
+#define HNS_ROCE_DIP_TMP_OFS (HNS_ROCE_DIP_TKP_OFS + HNS_ROCE_DIP_TKP_SZ)
+#define HNS_ROCE_DIP_TMP_SZ sizeof(u16)
+#define HNS_ROCE_DIP_TMP_MAX 15
+#define HNS_ROCE_DIP_ALP_OFS (HNS_ROCE_DIP_TMP_OFS + HNS_ROCE_DIP_TMP_SZ)
+#define HNS_ROCE_DIP_ALP_SZ sizeof(u16)
+#define HNS_ROCE_DIP_ALP_MAX ((u16)(~0U))
+#define HNS_ROCE_DIP_MAX_SPEED_OFS (HNS_ROCE_DIP_ALP_OFS + HNS_ROCE_DIP_ALP_SZ)
+#define HNS_ROCE_DIP_MAX_SPEED_SZ sizeof(u32)
+#define HNS_ROCE_DIP_MAX_SPEED_MAX ((u32)(~0U))
+#define HNS_ROCE_DIP_G_OFS (HNS_ROCE_DIP_MAX_SPEED_OFS + \
+				HNS_ROCE_DIP_MAX_SPEED_SZ)
+#define HNS_ROCE_DIP_G_SZ sizeof(u8)
+#define HNS_ROCE_DIP_G_MAX 15
+#define HNS_ROCE_DIP_AL_OFS (HNS_ROCE_DIP_G_OFS + HNS_ROCE_DIP_G_SZ)
+#define HNS_ROCE_DIP_AL_SZ sizeof(u8)
+#define HNS_ROCE_DIP_AL_MAX ((u8)(~0U))
+#define HNS_ROCE_DIP_CNP_TIME_OFS (HNS_ROCE_DIP_AL_OFS + HNS_ROCE_DIP_AL_SZ)
+#define HNS_ROCE_DIP_CNP_TIME_SZ sizeof(u8)
+#define HNS_ROCE_DIP_CNP_TIME_MAX ((u8)(~0U))
+#define HNS_ROCE_DIP_ASHIFT_OFS (HNS_ROCE_DIP_CNP_TIME_OFS + \
+					HNS_ROCE_DIP_CNP_TIME_SZ)
+#define HNS_ROCE_DIP_ASHIFT_SZ sizeof(u8)
+#define HNS_ROCE_DIP_ASHIFT_MAX 15
+#define HNS_ROCE_DIP_LIFESPAN_OFS (HNS_ROCE_DIP_ASHIFT_OFS + \
+					HNS_ROCE_DIP_ASHIFT_SZ)
+#define HNS_ROCE_DIP_LIFESPAN_SZ sizeof(u32)
+#define HNS_ROCE_DIP_LIFESPAN_MAX 1000
+
 struct hns_roce_sccc_clr {
 	__le32 qpn;
 	__le32 rsv[5];
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH for-next 2/3] RDMA/hns: Add write support to debugfs
  2026-02-06 10:31 ` [PATCH for-next 2/3] RDMA/hns: Add write support to debugfs Junxian Huang
@ 2026-02-12 16:55   ` Leon Romanovsky
  2026-02-13  7:52     ` Junxian Huang
  0 siblings, 1 reply; 10+ messages in thread
From: Leon Romanovsky @ 2026-02-12 16:55 UTC (permalink / raw)
  To: Junxian Huang; +Cc: jgg, linux-rdma, linuxarm, tangchengchang

On Fri, Feb 06, 2026 at 06:31:09PM +0800, Junxian Huang wrote:
> Add write support to debugfs.
> 
> Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
> ---
>  drivers/infiniband/hw/hns/hns_roce_debugfs.c | 38 +++++++++++++++++---
>  drivers/infiniband/hw/hns/hns_roce_debugfs.h |  1 +
>  2 files changed, 35 insertions(+), 4 deletions(-)

<...>

>  static const struct file_operations hns_debugfs_seqfile_fops = {
>  	.owner = THIS_MODULE,
>  	.open = hns_debugfs_seqfile_open,
>  	.release = single_release,
>  	.read = seq_read,
> +	.write = hns_debugfs_seqfile_write,
>  	.llseek = seq_lseek
>  };
>  

<...>

> -	debugfs_create_file(name, 0400, parent, seq, &hns_debugfs_seqfile_fops);
> +	debugfs_create_file(name, ops->write ? 0600 : 0400, parent,
> +			    seq, &hns_debugfs_seqfile_fops);

What is this "ops->write ?" check? You added write callback in this
exactly patch. It is always true.

Thanks

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH for-next 3/3] RDMA/hns: Support congestion control algorithm parameter configuration
  2026-02-06 10:31 ` [PATCH for-next 3/3] RDMA/hns: Support congestion control algorithm parameter configuration Junxian Huang
@ 2026-02-12 16:57   ` Leon Romanovsky
  2026-02-13  8:36     ` Junxian Huang
  0 siblings, 1 reply; 10+ messages in thread
From: Leon Romanovsky @ 2026-02-12 16:57 UTC (permalink / raw)
  To: Junxian Huang; +Cc: jgg, linux-rdma, linuxarm, tangchengchang

On Fri, Feb 06, 2026 at 06:31:10PM +0800, Junxian Huang wrote:
> From: Chengchang Tang <tangchengchang@huawei.com>
> 
> hns RoCE supports 4 congestion control algorithms. Each algorihm
> involves multiple parameters. Support configuring these parameters
> by debugfs.
> 
> Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
> Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
> ---
>  drivers/infiniband/hw/hns/hns_roce_debugfs.c | 278 +++++++++++++++++++
>  drivers/infiniband/hw/hns/hns_roce_debugfs.h |  25 ++
>  drivers/infiniband/hw/hns/hns_roce_device.h  |  25 ++
>  drivers/infiniband/hw/hns/hns_roce_hw_v2.c   |  66 +++++
>  drivers/infiniband/hw/hns/hns_roce_hw_v2.h   | 140 ++++++++++
>  5 files changed, 534 insertions(+)

Please remove all these complexity, delayed work, multiple configuration options in one file,
provide one directory with multiple files. Each file is a key, which can accept multiple
values and not like it is implemented now.

Also, please add examples to this commit message.

Thanks

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH for-next 2/3] RDMA/hns: Add write support to debugfs
  2026-02-12 16:55   ` Leon Romanovsky
@ 2026-02-13  7:52     ` Junxian Huang
  2026-02-13 16:07       ` Leon Romanovsky
  0 siblings, 1 reply; 10+ messages in thread
From: Junxian Huang @ 2026-02-13  7:52 UTC (permalink / raw)
  To: Leon Romanovsky; +Cc: jgg, linux-rdma, linuxarm, tangchengchang



On 2026/2/13 0:55, Leon Romanovsky wrote:
> On Fri, Feb 06, 2026 at 06:31:09PM +0800, Junxian Huang wrote:
>> Add write support to debugfs.
>>
>> Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
>> ---
>>  drivers/infiniband/hw/hns/hns_roce_debugfs.c | 38 +++++++++++++++++---
>>  drivers/infiniband/hw/hns/hns_roce_debugfs.h |  1 +
>>  2 files changed, 35 insertions(+), 4 deletions(-)
> 
> <...>
> 
>>  static const struct file_operations hns_debugfs_seqfile_fops = {
>>  	.owner = THIS_MODULE,
>>  	.open = hns_debugfs_seqfile_open,
>>  	.release = single_release,
>>  	.read = seq_read,
>> +	.write = hns_debugfs_seqfile_write,
>>  	.llseek = seq_lseek
>>  };
>>  
> 
> <...>
> 
>> -	debugfs_create_file(name, 0400, parent, seq, &hns_debugfs_seqfile_fops);
>> +	debugfs_create_file(name, ops->write ? 0600 : 0400, parent,
>> +			    seq, &hns_debugfs_seqfile_fops);
> 
> What is this "ops->write ?" check? You added write callback in this
> exactly patch. It is always true.
> 

This ops is the function argument "const struct hns_debugfs_rw_ops *ops", not
the file_operations hns_debugfs_seqfile_fops. This ops->write can be NULL when
the file is read-only, such as the change in create_sw_stat_debugfs() in this
patch.

Junxian

> Thanks
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH for-next 3/3] RDMA/hns: Support congestion control algorithm parameter configuration
  2026-02-12 16:57   ` Leon Romanovsky
@ 2026-02-13  8:36     ` Junxian Huang
  2026-02-13 16:12       ` Leon Romanovsky
  0 siblings, 1 reply; 10+ messages in thread
From: Junxian Huang @ 2026-02-13  8:36 UTC (permalink / raw)
  To: Leon Romanovsky; +Cc: jgg, linux-rdma, linuxarm, tangchengchang



On 2026/2/13 0:57, Leon Romanovsky wrote:
> On Fri, Feb 06, 2026 at 06:31:10PM +0800, Junxian Huang wrote:
>> From: Chengchang Tang <tangchengchang@huawei.com>
>>
>> hns RoCE supports 4 congestion control algorithms. Each algorihm
>> involves multiple parameters. Support configuring these parameters
>> by debugfs.
>>
>> Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
>> Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
>> ---
>>  drivers/infiniband/hw/hns/hns_roce_debugfs.c | 278 +++++++++++++++++++
>>  drivers/infiniband/hw/hns/hns_roce_debugfs.h |  25 ++
>>  drivers/infiniband/hw/hns/hns_roce_device.h  |  25 ++
>>  drivers/infiniband/hw/hns/hns_roce_hw_v2.c   |  66 +++++
>>  drivers/infiniband/hw/hns/hns_roce_hw_v2.h   | 140 ++++++++++
>>  5 files changed, 534 insertions(+)
> 
> Please remove all these complexity, delayed work, 

Sure. Then we'll update HW immediately each time the user write a new value
to the param file.

> multiple configuration options in one file, provide one directory with multiple files> Each file is a key, which can accept multiple values and not like it is implemented now.

If I understand your comment correctly, our current implementation already
follows the structure you described. We don't have multiple configuration
options in one file. We provide one directory with multiple files for each
algorithm. Each file corresponds to one param.

* The directory structure:
# ls /sys/kernel/debug/hns_roce/0000\:35\:00.0/
dcqcn_cc_param  dip_cc_param  hc3_cc_param  ldcp_cc_param
# ls /sys/kernel/debug/hns_roce/0000\:35\:00.0/dcqcn_cc_param/
ai  al  alp  ashift  cnp_time  f  g  lifespan  max_speed  tkp  tmp

* Read the value of a param:
# cat /sys/kernel/debug/hns_roce/0000\:35\:00.0/dcqcn_cc_param/ai
1

* Set a new value for a param:
# echo 2 > /sys/kernel/debug/hns_roce/0000\:35\:00.0/dcqcn_cc_param/ai

> 
> Also, please add examples to this commit message.

Will add the examples above.

Junxian

> 
> Thanks
> 
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH for-next 2/3] RDMA/hns: Add write support to debugfs
  2026-02-13  7:52     ` Junxian Huang
@ 2026-02-13 16:07       ` Leon Romanovsky
  0 siblings, 0 replies; 10+ messages in thread
From: Leon Romanovsky @ 2026-02-13 16:07 UTC (permalink / raw)
  To: Junxian Huang; +Cc: jgg, linux-rdma, linuxarm, tangchengchang

On Fri, Feb 13, 2026 at 03:52:50PM +0800, Junxian Huang wrote:
> 
> 
> On 2026/2/13 0:55, Leon Romanovsky wrote:
> > On Fri, Feb 06, 2026 at 06:31:09PM +0800, Junxian Huang wrote:
> >> Add write support to debugfs.
> >>
> >> Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
> >> ---
> >>  drivers/infiniband/hw/hns/hns_roce_debugfs.c | 38 +++++++++++++++++---
> >>  drivers/infiniband/hw/hns/hns_roce_debugfs.h |  1 +
> >>  2 files changed, 35 insertions(+), 4 deletions(-)
> > 
> > <...>
> > 
> >>  static const struct file_operations hns_debugfs_seqfile_fops = {
> >>  	.owner = THIS_MODULE,
> >>  	.open = hns_debugfs_seqfile_open,
> >>  	.release = single_release,
> >>  	.read = seq_read,
> >> +	.write = hns_debugfs_seqfile_write,
> >>  	.llseek = seq_lseek
> >>  };
> >>  
> > 
> > <...>
> > 
> >> -	debugfs_create_file(name, 0400, parent, seq, &hns_debugfs_seqfile_fops);
> >> +	debugfs_create_file(name, ops->write ? 0600 : 0400, parent,
> >> +			    seq, &hns_debugfs_seqfile_fops);
> > 
> > What is this "ops->write ?" check? You added write callback in this
> > exactly patch. It is always true.
> > 
> 
> This ops is the function argument "const struct hns_debugfs_rw_ops *ops", not
> the file_operations hns_debugfs_seqfile_fops. This ops->write can be NULL when
> the file is read-only, such as the change in create_sw_stat_debugfs() in this
> patch.

Excellent, inline your init_debugfs_seqfile().

Thanks

> 
> Junxian
> 
> > Thanks
> > 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH for-next 3/3] RDMA/hns: Support congestion control algorithm parameter configuration
  2026-02-13  8:36     ` Junxian Huang
@ 2026-02-13 16:12       ` Leon Romanovsky
  0 siblings, 0 replies; 10+ messages in thread
From: Leon Romanovsky @ 2026-02-13 16:12 UTC (permalink / raw)
  To: Junxian Huang; +Cc: jgg, linux-rdma, linuxarm, tangchengchang

On Fri, Feb 13, 2026 at 04:36:44PM +0800, Junxian Huang wrote:
> 
> 
> On 2026/2/13 0:57, Leon Romanovsky wrote:
> > On Fri, Feb 06, 2026 at 06:31:10PM +0800, Junxian Huang wrote:
> >> From: Chengchang Tang <tangchengchang@huawei.com>
> >>
> >> hns RoCE supports 4 congestion control algorithms. Each algorihm
> >> involves multiple parameters. Support configuring these parameters
> >> by debugfs.
> >>
> >> Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
> >> Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
> >> ---
> >>  drivers/infiniband/hw/hns/hns_roce_debugfs.c | 278 +++++++++++++++++++
> >>  drivers/infiniband/hw/hns/hns_roce_debugfs.h |  25 ++
> >>  drivers/infiniband/hw/hns/hns_roce_device.h  |  25 ++
> >>  drivers/infiniband/hw/hns/hns_roce_hw_v2.c   |  66 +++++
> >>  drivers/infiniband/hw/hns/hns_roce_hw_v2.h   | 140 ++++++++++
> >>  5 files changed, 534 insertions(+)
> > 
> > Please remove all these complexity, delayed work, 
> 
> Sure. Then we'll update HW immediately each time the user write a new value
> to the param file.
> 
> > multiple configuration options in one file, provide one directory with multiple files> Each file is a key, which can accept multiple values and not like it is implemented now.
> 
> If I understand your comment correctly, our current implementation already
> follows the structure you described. We don't have multiple configuration
> options in one file. We provide one directory with multiple files for each
> algorithm. Each file corresponds to one param.

I probably misread your patch, so let's simplify it and it will be more
clear.

Thanks

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-02-13 16:12 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-06 10:31 [PATCH for-next 0/3] RDMA/hns: Support congestion control algorithm parameter configuration by debugfs Junxian Huang
2026-02-06 10:31 ` [PATCH for-next 1/3] RDMA/hns: Initialize seqfile before creating file Junxian Huang
2026-02-06 10:31 ` [PATCH for-next 2/3] RDMA/hns: Add write support to debugfs Junxian Huang
2026-02-12 16:55   ` Leon Romanovsky
2026-02-13  7:52     ` Junxian Huang
2026-02-13 16:07       ` Leon Romanovsky
2026-02-06 10:31 ` [PATCH for-next 3/3] RDMA/hns: Support congestion control algorithm parameter configuration Junxian Huang
2026-02-12 16:57   ` Leon Romanovsky
2026-02-13  8:36     ` Junxian Huang
2026-02-13 16:12       ` Leon Romanovsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox