On Wed, 30 Jul 2025 16:47:15 -0500 Ben Cheatham <Benjamin.Cheatham@xxxxxxx> wrote: > Add functions to enable programming the CXL.mem transaction timeout > range, if supported. Add a sysfs attribute to the "cxl_isolation" group > to allow programming the timeout from userspace. > > The attribute can take either the CXL spec-defined hex value for the > associated timeout range (CXL 3.2 8.2.4.24.2 field 3:0) or a > string with the range. The range string is formatted as the range letter > in uppercase or lowercase, with an optional "2" to specify the second > range in the aforementioned spec ref. > > For example, to program the port with a timeout of 65ms to 210ms (range B) > the following strings could be specified: "b2"/"B2". Picking the first > portion of range B (16ms to 55ms) would be: "b"/"B". > > Signed-off-by: Ben Cheatham <Benjamin.Cheatham@xxxxxxx> This needs some ABI Docs. The spec is exceedingly weird, so working out a sensible way to present it to userspace will be a challenge. I vaguely recall the weird timing description is from some other spec. Any idea where and if there is existing ABI for that? > diff --git a/drivers/pci/pcie/cxl_isolation.c b/drivers/pci/pcie/cxl_isolation.c > index 9d2ad14810e8..107201b5843f 100644 > --- a/drivers/pci/pcie/cxl_isolation.c > +++ b/drivers/pci/pcie/cxl_isolation.c > +static ssize_t timeout_range_show(struct device *dev, > + struct device_attribute *attr, char * buf) > +{ > + struct pci_dev *pdev = to_pci_dev(dev); > + struct cxl_port *port; > + u32 ctrl, val; > + > + struct cxl_dport **dport __free(kfree) = > + kzalloc(sizeof(*dport), GFP_KERNEL); > + if (!dport) > + return -ENOMEM; > + > + port = cxl_find_pcie_rp(pdev, dport); > + if (!port || !(*dport)) > + return -ENODEV; > + > + if (!(*dport)->regs.isolation) Same issue with reference leak as in previous patch. > + return -ENXIO; > + > + ctrl = readl((*dport)->regs.isolation + CXL_ISOLATION_CTRL_OFFSET); > + put_device(&port->dev); > + > + val = FIELD_GET(CXL_ISOLATION_CTRL_MEM_TIME_MASK, ctrl); > + for (int i = 0; i < ARRAY_SIZE(ranges); i++) > + if (ranges[i].val == val) > + return sysfs_emit(buf, "%s\n", ranges[i].str); > + > + return -ENXIO; > +} > +DEVICE_ATTR_RW(timeout_range);