diff options
author | Kent Russell <kent.russell@amd.com> | 2019-01-03 08:12:39 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-01-14 15:04:54 -0500 |
commit | b45e18acd394954c24943762ada5d8dada75f2b9 (patch) | |
tree | 40ffc68e9c4e6c4449edf17d4401d4dcc5a54503 /drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |
parent | a0bb79e2559c9330c82080d6e4f8c762d72ed0f1 (diff) |
drm/amdgpu: Add sysfs file for PCIe usage v5
Add a sysfs file that reports the number of bytes transmitted and
received in the last second. This can be used to approximate the PCIe
bandwidth usage over the last second.
v2: Clarify use of mps as estimation of bandwidth
v3: Don't make the file on APUs
v4: Early exit for APUs in the read function, change output to
display "packets-received packets-sent mps"
v5: fix missing header for si (Alex)
Signed-off-by: Kent Russell <kent.russell@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 6896dec97fc7..b38c06f0196e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |||
@@ -990,6 +990,31 @@ static ssize_t amdgpu_get_busy_percent(struct device *dev, | |||
990 | return snprintf(buf, PAGE_SIZE, "%d\n", value); | 990 | return snprintf(buf, PAGE_SIZE, "%d\n", value); |
991 | } | 991 | } |
992 | 992 | ||
993 | /** | ||
994 | * DOC: pcie_bw | ||
995 | * | ||
996 | * The amdgpu driver provides a sysfs API for estimating how much data | ||
997 | * has been received and sent by the GPU in the last second through PCIe. | ||
998 | * The file pcie_bw is used for this. | ||
999 | * The Perf counters count the number of received and sent messages and return | ||
1000 | * those values, as well as the maximum payload size of a PCIe packet (mps). | ||
1001 | * Note that it is not possible to easily and quickly obtain the size of each | ||
1002 | * packet transmitted, so we output the max payload size (mps) to allow for | ||
1003 | * quick estimation of the PCIe bandwidth usage | ||
1004 | */ | ||
1005 | static ssize_t amdgpu_get_pcie_bw(struct device *dev, | ||
1006 | struct device_attribute *attr, | ||
1007 | char *buf) | ||
1008 | { | ||
1009 | struct drm_device *ddev = dev_get_drvdata(dev); | ||
1010 | struct amdgpu_device *adev = ddev->dev_private; | ||
1011 | uint64_t count0, count1; | ||
1012 | |||
1013 | amdgpu_asic_get_pcie_usage(adev, &count0, &count1); | ||
1014 | return snprintf(buf, PAGE_SIZE, "%llu %llu %i\n", | ||
1015 | count0, count1, pcie_get_mps(adev->pdev)); | ||
1016 | } | ||
1017 | |||
993 | static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state); | 1018 | static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state); |
994 | static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, | 1019 | static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, |
995 | amdgpu_get_dpm_forced_performance_level, | 1020 | amdgpu_get_dpm_forced_performance_level, |
@@ -1025,6 +1050,7 @@ static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR, | |||
1025 | amdgpu_set_pp_od_clk_voltage); | 1050 | amdgpu_set_pp_od_clk_voltage); |
1026 | static DEVICE_ATTR(gpu_busy_percent, S_IRUGO, | 1051 | static DEVICE_ATTR(gpu_busy_percent, S_IRUGO, |
1027 | amdgpu_get_busy_percent, NULL); | 1052 | amdgpu_get_busy_percent, NULL); |
1053 | static DEVICE_ATTR(pcie_bw, S_IRUGO, amdgpu_get_pcie_bw, NULL); | ||
1028 | 1054 | ||
1029 | static ssize_t amdgpu_hwmon_show_temp(struct device *dev, | 1055 | static ssize_t amdgpu_hwmon_show_temp(struct device *dev, |
1030 | struct device_attribute *attr, | 1056 | struct device_attribute *attr, |
@@ -2108,6 +2134,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) | |||
2108 | "gpu_busy_level\n"); | 2134 | "gpu_busy_level\n"); |
2109 | return ret; | 2135 | return ret; |
2110 | } | 2136 | } |
2137 | /* PCIe Perf counters won't work on APU nodes */ | ||
2138 | if (adev->flags & !AMD_IS_APU) { | ||
2139 | ret = device_create_file(adev->dev, &dev_attr_pcie_bw); | ||
2140 | if (ret) { | ||
2141 | DRM_ERROR("failed to create device file pcie_bw\n"); | ||
2142 | return ret; | ||
2143 | } | ||
2144 | } | ||
2111 | ret = amdgpu_debugfs_pm_init(adev); | 2145 | ret = amdgpu_debugfs_pm_init(adev); |
2112 | if (ret) { | 2146 | if (ret) { |
2113 | DRM_ERROR("Failed to register debugfs file for dpm!\n"); | 2147 | DRM_ERROR("Failed to register debugfs file for dpm!\n"); |
@@ -2147,6 +2181,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) | |||
2147 | device_remove_file(adev->dev, | 2181 | device_remove_file(adev->dev, |
2148 | &dev_attr_pp_od_clk_voltage); | 2182 | &dev_attr_pp_od_clk_voltage); |
2149 | device_remove_file(adev->dev, &dev_attr_gpu_busy_percent); | 2183 | device_remove_file(adev->dev, &dev_attr_gpu_busy_percent); |
2184 | if (adev->flags & !AMD_IS_APU) | ||
2185 | device_remove_file(adev->dev, &dev_attr_pcie_bw); | ||
2150 | } | 2186 | } |
2151 | 2187 | ||
2152 | void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) | 2188 | void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) |