[RFC PATCH 4/5] iommu/arm-smmu-v3: Add stream table directory structure to debugfs
Qinxin Xia
xiaqinxin at huawei.com
Mon Mar 16 07:57:56 PDT 2026
On 2026/3/14 04:44:49, Nicolin Chen <nicolinc at nvidia.com> wrote:
> On Fri, Mar 13, 2026 at 06:43:50PM +0800, Qinxin Xia wrote:
>> * The capabilities file provides detailed information about:
>> * - Architecture version and translation stage support (Stage1/Stage2)
>> @@ -324,5 +327,78 @@ static int smmu_debugfs_ste_show(struct seq_file *seq, void *v)
>> smmu_debug_dump_ste(seq, dev);
>> return 0;
>> }
>> -
>> DEFINE_SHOW_ATTRIBUTE(smmu_debugfs_ste);
>
> nit: let's not add that line in the first place
>
>> +
>> +/**
>> + * smmu_debugfs_create_stream_table() - Create debugfs entries for stream table
>> + * @dev: device to create entries for
>> + * @smmu: SMMU device
>> + *
>> + * Return: 0 on success, negative error code on failure
>> + */
>> +int smmu_debugfs_create_stream_table(struct device *dev,
>> + struct arm_smmu_device *smmu)
>> +{
>> + struct dentry *stream_dir, *cd_dir, *dev_dir;
>> + struct dentry *ste_file, *all_cds_file;
>> + struct iommu_fwspec *fwspec;
>> + char name[64];
>> + int i, ret = 0;
>> +
>> + if (!smmu->debugfs->stream_dir) {
>> + stream_dir = debugfs_create_dir("stream_table",
>> + smmu->debugfs->smmu_dir);
>> + if (!stream_dir)
>> + return -ENOMEM;
>> + smmu->debugfs->stream_dir = stream_dir;
>> + } else {
>> + stream_dir = smmu->debugfs->stream_dir;
>> + }
>> +
>> + fwspec = dev_iommu_fwspec_get(dev);
>> + if (!fwspec)
>> + return -ENODEV;
>> +
>> + for (i = 0; i < fwspec->num_ids; i++) {
>> + u32 sid = fwspec->ids[i];
>> +
>> + if (dev_is_pci(dev)) {
>> + struct pci_dev *pdev = to_pci_dev(dev);
>> +
>> + snprintf(name, sizeof(name), "%04x:%02x:%02x.%d:%u",
>> + pci_domain_nr(pdev->bus), pdev->bus->number,
>> + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
>> + sid);
>
> Doesn't dev_name(dev) print the BDF numbers as well?
>
>> + } else {
>> + snprintf(name, sizeof(name), "%s:%u", dev_name(dev),
>> + sid);
>> + }
>> +
>> + dev_dir = debugfs_create_dir(name, stream_dir);
>> + if (!dev_dir) {
>> + ret = -ENOMEM;
>> + goto cleanup;
>> + }
>
> A device can have multiple streams. So, dev_dir should be the
> parent directory?
>
dev_dir is a parent directory and it contains ste info and CD info
for all streams of this device.
[root at localhost stream_table]# ls
0000:34:00.0:13312 0000:34:01.0:13320 0000:35:00.0:13568
0000:35:00.1:13569 0000:35:00.2:13570 0000:35:00.3:13571
[root at localhost stream_table]# cd 0000\:34\:00.0\:13312/
[root at localhost 0000:34:00.0:13312]# ls
context_descriptors ste
[root at localhost 0000:34:00.0:13312]#
>> +
>> + /* Success for this stream ID, continue to next */
>> + continue;
>> +
>> +cleanup_dev:
>> + debugfs_remove_recursive(dev_dir);
>> +cleanup:
>> + if (ret) {
>> + debugfs_remove_recursive(stream_dir);
>
> One is the other's parent directory. So it should be good enough
> with a single debugfs_remove_recursive()?
>
>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> index 211a0c87507a..c57897e5f644 100644
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> @@ -3133,6 +3133,9 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev,
>>
>> arm_smmu_attach_commit(&state);
>> mutex_unlock(&arm_smmu_asid_lock);
>> +#ifdef CONFIG_ARM_SMMU_V3_DEBUGFS
>> + smmu_debugfs_create_stream_table(dev, smmu);
>> +#endif
>
> Calling in attach_dev doesn't seem correct to me. And device/master
> can be unplugged. So, we would need to unwind those dev/stream_dir.
>
> Maybe probe_device/release_device are the places to go?
>
> Nicolin
>
Thanks for your review,
I will fix these bugs in the next RFC version.
--
Thanks,
Qinxin
More information about the linux-arm-kernel
mailing list