Re: [PATCH v7 5/5] Add debugfs based statistical counter support in DWC
From: Fan Ni <hidden>
Date: 2025-03-03 18:02:41
Also in:
linux-pci, linux-perf-users, lkml
On Fri, Feb 21, 2025 at 06:45:48PM +0530, Shradha Todi wrote:
Add support to provide statistical counter interface to userspace. This set of debug registers are part of the RASDES feature present in DesignWare PCIe controllers.
One comment inline.
quoted hunk ↗ jump to hunk
Signed-off-by: Shradha Todi <redacted> --- Documentation/ABI/testing/debugfs-dwc-pcie | 61 +++++ .../controller/dwc/pcie-designware-debugfs.c | 229 +++++++++++++++++- 2 files changed, 289 insertions(+), 1 deletion(-)diff --git a/Documentation/ABI/testing/debugfs-dwc-pcie b/Documentation/ABI/testing/debugfs-dwc-pcie index 6ee0897fe753..650a89b0511e 100644 --- a/Documentation/ABI/testing/debugfs-dwc-pcie +++ b/Documentation/ABI/testing/debugfs-dwc-pcie@@ -81,3 +81,64 @@ Description: rasdes_err_inj is the directory which can be used to inject errors <count> Number of errors to be injected
...
+
+static ssize_t counter_value_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+{
+ struct dwc_pcie_rasdes_priv *pdata = file->private_data;
+ struct dw_pcie *pci = pdata->pci;
+ struct dwc_pcie_rasdes_info *rinfo = pci->debugfs->rasdes_info;
+ char debugfs_buf[DWC_DEBUGFS_BUF_MAX];
+ ssize_t pos;
+ u32 val;
+
+ mutex_lock(&rinfo->reg_event_lock);
+ set_event_number(pdata, pci, rinfo);
+ val = dw_pcie_readl_dbi(pci, rinfo->ras_cap_offset + RAS_DES_EVENT_COUNTER_DATA_REG);
+ mutex_unlock(&rinfo->reg_event_lock);
+ pos = scnprintf(debugfs_buf, DWC_DEBUGFS_BUF_MAX, "Counter value: %d\n", val);
+
+ return simple_read_from_buffer(buf, count, ppos, debugfs_buf, pos);
+}Do we need to check whether the counter is enabled or not for the event before retrieving the counter value? Fan
quoted hunk ↗ jump to hunk
+ #define dwc_debugfs_create(name) \ debugfs_create_file(#name, 0644, rasdes_debug, pci, \ &dbg_ ## name ## _fops)@@ -249,6 +436,23 @@ static const struct file_operations dwc_pcie_err_inj_ops = { .write = err_inj_write, }; +static const struct file_operations dwc_pcie_counter_enable_ops = { + .open = simple_open, + .read = counter_enable_read, + .write = counter_enable_write, +}; + +static const struct file_operations dwc_pcie_counter_lane_ops = { + .open = simple_open, + .read = counter_lane_read, + .write = counter_lane_write, +}; + +static const struct file_operations dwc_pcie_counter_value_ops = { + .open = simple_open, + .read = counter_value_read, +}; + static void dwc_pcie_rasdes_debugfs_deinit(struct dw_pcie *pci) { struct dwc_pcie_rasdes_info *rinfo = pci->debugfs->rasdes_info;@@ -258,7 +462,7 @@ static void dwc_pcie_rasdes_debugfs_deinit(struct dw_pcie *pci) static int dwc_pcie_rasdes_debugfs_init(struct dw_pcie *pci, struct dentry *dir) { - struct dentry *rasdes_debug, *rasdes_err_inj; + struct dentry *rasdes_debug, *rasdes_err_inj, *rasdes_event_counter, *rasdes_events; struct dwc_pcie_rasdes_info *rasdes_info; struct dwc_pcie_rasdes_priv *priv_tmp; struct device *dev = pci->dev;@@ -277,6 +481,7 @@ static int dwc_pcie_rasdes_debugfs_init(struct dw_pcie *pci, struct dentry *dir) /* Create subdirectories for Debug, Error injection, Statistics */ rasdes_debug = debugfs_create_dir("rasdes_debug", dir); rasdes_err_inj = debugfs_create_dir("rasdes_err_inj", dir); + rasdes_event_counter = debugfs_create_dir("rasdes_event_counter", dir); mutex_init(&rasdes_info->reg_event_lock); rasdes_info->ras_cap_offset = ras_cap;@@ -299,6 +504,28 @@ static int dwc_pcie_rasdes_debugfs_init(struct dw_pcie *pci, struct dentry *dir) debugfs_create_file(err_inj_list[i].name, 0200, rasdes_err_inj, priv_tmp, &dwc_pcie_err_inj_ops); } + + /* Create debugfs files for Statistical counter subdirectory */ + for (i = 0; i < ARRAY_SIZE(event_list); i++) { + priv_tmp = devm_kzalloc(dev, sizeof(*priv_tmp), GFP_KERNEL); + if (!priv_tmp) { + ret = -ENOMEM; + goto err_deinit; + } + + priv_tmp->idx = i; + priv_tmp->pci = pci; + rasdes_events = debugfs_create_dir(event_list[i].name, rasdes_event_counter); + if (event_list[i].group_no == 0 || event_list[i].group_no == 4) { + debugfs_create_file("lane_select", 0644, rasdes_events, + priv_tmp, &dwc_pcie_counter_lane_ops); + } + debugfs_create_file("counter_value", 0444, rasdes_events, priv_tmp, + &dwc_pcie_counter_value_ops); + debugfs_create_file("counter_enable", 0644, rasdes_events, priv_tmp, + &dwc_pcie_counter_enable_ops); + } + return 0; err_deinit:-- 2.17.1