[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