drm/amdgpu: add mem_reserved_info sysfs attribute

Expose the cached MEM_RESERVED_INFO discovery table via a per-device
sysfs file:

    /sys/class/drm/cardX/device/mem_reserved_info

The file is read-only and dumps every region as:

    list_num=<N>
    [<i>] id=<id> (<name>) size=0x<size> start=0x<start>

Only created when the table was successfully resolved at discovery
init time.

Suggested-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Feifei Xu <Feifei.Xu@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Feifei Xu 2026-05-12 09:04:46 +08:00 committed by Alex Deucher
parent 1380b7be58
commit e59206f393
3 changed files with 64 additions and 0 deletions

View File

@ -247,6 +247,9 @@ static int amdgpu_device_attr_sysfs_init(struct amdgpu_device *adev)
ret = sysfs_create_file(&adev->dev->kobj,
&dev_attr_pcie_replay_count.attr);
if (!ret)
ret = amdgpu_discovery_mem_reserved_info_sysfs_init(adev);
return ret;
}
@ -255,6 +258,8 @@ static void amdgpu_device_attr_sysfs_fini(struct amdgpu_device *adev)
if (amdgpu_nbio_is_replay_cnt_supported(adev))
sysfs_remove_file(&adev->dev->kobj,
&dev_attr_pcie_replay_count.attr);
amdgpu_discovery_mem_reserved_info_sysfs_fini(adev);
}
static ssize_t amdgpu_sysfs_reg_state_get(struct file *f, struct kobject *kobj,

View File

@ -2433,6 +2433,62 @@ static void amdgpu_discovery_dump_mem_reserved_info_table(struct amdgpu_device *
}
}
/**
* Add READ-ONLY mem_reserved_info sysfs entry.
* MEM_RESERVED_INFO table is parsed from the IP discovery binary.
* The file mem_reserved_info dumps every entry as:
* list_num=<N>
* [<i>] id=<id> (<name>) size=<size> start=<start>
*/
static ssize_t mem_reserved_info_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev);
struct mem_reserved_info_table_v1_0 *table;
u32 list_num, id, i;
ssize_t len = 0;
if (amdgpu_discovery_get_mem_reserved_info_table(adev))
return sysfs_emit(buf, "MEM_RESERVED_INFO table not available\n");
table = adev->discovery.mem_reserved_table;
list_num = min_t(u32, le32_to_cpu(table->list_num), MAX_MEM_REGION_NUM);
len += sysfs_emit_at(buf, len, "list_num=%u\n", list_num);
for (i = 0; i < list_num; i++) {
id = le32_to_cpu(table->list[i].reserved_region_id);
len += sysfs_emit_at(buf, len,
"[%u] id=%u (%s) size=0x%llx start=0x%llx\n",
i, id,
amdgpu_discovery_mem_reserved_region_name(id),
le64_to_cpu(table->list[i].reserved_region_size),
le64_to_cpu(table->list[i].reserved_region_start));
}
return len;
}
static DEVICE_ATTR_RO(mem_reserved_info);
int amdgpu_discovery_mem_reserved_info_sysfs_init(struct amdgpu_device *adev)
{
if (!adev->discovery.mem_reserved_table)
return 0;
return sysfs_create_file(&adev->dev->kobj,
&dev_attr_mem_reserved_info.attr);
}
void amdgpu_discovery_mem_reserved_info_sysfs_fini(struct amdgpu_device *adev)
{
if (!adev->discovery.mem_reserved_table)
return;
sysfs_remove_file(&adev->dev->kobj,
&dev_attr_mem_reserved_info.attr);
}
/*
* Resolve the MEM_RESERVED_INFO table from the IP discovery binary and
* cache it in adev->discovery.mem_reserved_table.

View File

@ -67,4 +67,7 @@ int amdgpu_discovery_get_mem_reserved_region_by_id(struct amdgpu_device *adev,
u32 reserved_region_id,
struct mem_reserved_info *info);
int amdgpu_discovery_mem_reserved_info_sysfs_init(struct amdgpu_device *adev);
void amdgpu_discovery_mem_reserved_info_sysfs_fini(struct amdgpu_device *adev);
#endif /* __AMDGPU_DISCOVERY__ */