RE: [PATCH] drm/amdgpu: Add sysfs file for PCIe usage v3
> -Original Message- > From: Alex Deucher > Sent: Tuesday, January 08, 2019 11:26 AM > To: Kuehling, Felix > Cc: Russell, Kent ; amd-gfx@lists.freedesktop.org; > Deucher, Alexander > Subject: Re: [PATCH] drm/amdgpu: Add sysfs file for PCIe usage v3 > > On Tue, Jan 8, 2019 at 11:02 AM Kuehling, Felix > wrote: > > > > > > On 2019-01-08 6:28 a.m., Russell, Kent wrote: > > > 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 > > > > I think you only updated the code comment, but not the output in sysfs. > > > > More generally, most amdgpu sysfs files report a single value, or a > > set of values separated by spaces. That makes it easier to parse by > > external tools. It's also supposed to be a stable API. They don't > > usually include human readable text such as "bytes received:". It > > would be up to a tool such as rocm-smi to turn this into human-readable > text. > > > > In keeping with that convention I'd suggest reporting the PCIe > > bandwidth as three numbers: > > > > > > > > Then let the tool calculate the bytes estimate with the appropriate > > warnings about how accurate that is. > > > > Alex does this match your understanding regarding sysfs conventions? > > Yes, agreed. > > Alex That works for me. I always let the sclk/mclk sysfs file with their multi-line outputs get into my head. I'll make the appropriate change, which will also make it easier for the SMI to communicate how the values are established. Kent > > > > > Regards, > > Felix > > > > > v3: Don't make the file on APUs > > > > > > Signed-off-by: Kent Russell > > > --- > > > drivers/gpu/drm/amd/amdgpu/amdgpu.h| 4 > > > drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 38 > + > > > drivers/gpu/drm/amd/amdgpu/cik.c | 41 > +++ > > > drivers/gpu/drm/amd/amdgpu/si.c| 41 > +++ > > > drivers/gpu/drm/amd/amdgpu/soc15.c | 44 > ++ > > > drivers/gpu/drm/amd/amdgpu/vi.c| 41 > +++ > > > 6 files changed, 209 insertions(+) > > > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > > > index e1b2c64..512b124 100644 > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > > > @@ -542,6 +542,9 @@ struct amdgpu_asic_funcs { > > > bool (*need_full_reset)(struct amdgpu_device *adev); > > > /* initialize doorbell layout for specific asic*/ > > > void (*init_doorbell_index)(struct amdgpu_device *adev); > > > + /* PCIe bandwidth usage */ > > > + void (*get_pcie_usage)(struct amdgpu_device *adev, uint64_t > *count0, > > > +uint64_t *count1); > > > }; > > > > > > /* > > > @@ -1045,6 +1048,7 @@ int emu_soc_asic_init(struct amdgpu_device > > > *adev); #define amdgpu_asic_invalidate_hdp(adev, r) > > > (adev)->asic_funcs->invalidate_hdp((adev), (r)) #define > > > amdgpu_asic_need_full_reset(adev) > > > (adev)->asic_funcs->need_full_reset((adev)) > > > #define amdgpu_asic_init_doorbell_index(adev) > > > (adev)->asic_funcs->init_doorbell_index((adev)) > > > +#define amdgpu_asic_get_pcie_usage(adev, cnt0, cnt1) > > > +((adev)->asic_funcs->get_pcie_usage((adev), (cnt0), (cnt1))) > > > > > > /* Common functions */ > > > bool amdgpu_device_should_recover_gpu(struct amdgpu_device > *adev); > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > > > index 6896dec..d2b29fd 100644 > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > > > @@ -990,6 +990,33 @@ static ssize_t amdgpu_get_busy_percent(struct > device *dev, > > > return snprintf(buf, PAGE_SIZE, "%d\n", value); } > > > > > > +/** > > > + * DOC: pcie_bw > > > + * > > > + * The amdgpu driver provides a sysfs API for reading how much data > > > + * has been sent and received by the GPU in the last seco
Re: [PATCH] drm/amdgpu: Add sysfs file for PCIe usage v3
On Tue, Jan 8, 2019 at 6:28 AM Russell, Kent wrote: > > 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 > > Signed-off-by: Kent Russell > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h| 4 > drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 38 + > drivers/gpu/drm/amd/amdgpu/cik.c | 41 +++ > drivers/gpu/drm/amd/amdgpu/si.c| 41 +++ > drivers/gpu/drm/amd/amdgpu/soc15.c | 44 > ++ > drivers/gpu/drm/amd/amdgpu/vi.c| 41 +++ > 6 files changed, 209 insertions(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index e1b2c64..512b124 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -542,6 +542,9 @@ struct amdgpu_asic_funcs { > bool (*need_full_reset)(struct amdgpu_device *adev); > /* initialize doorbell layout for specific asic*/ > void (*init_doorbell_index)(struct amdgpu_device *adev); > + /* PCIe bandwidth usage */ > + void (*get_pcie_usage)(struct amdgpu_device *adev, uint64_t *count0, > + uint64_t *count1); > }; > > /* > @@ -1045,6 +1048,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev); > #define amdgpu_asic_invalidate_hdp(adev, r) > (adev)->asic_funcs->invalidate_hdp((adev), (r)) > #define amdgpu_asic_need_full_reset(adev) > (adev)->asic_funcs->need_full_reset((adev)) > #define amdgpu_asic_init_doorbell_index(adev) > (adev)->asic_funcs->init_doorbell_index((adev)) > +#define amdgpu_asic_get_pcie_usage(adev, cnt0, cnt1) > ((adev)->asic_funcs->get_pcie_usage((adev), (cnt0), (cnt1))) > > /* Common functions */ > bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev); > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > index 6896dec..d2b29fd 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > @@ -990,6 +990,33 @@ static ssize_t amdgpu_get_busy_percent(struct device > *dev, > return snprintf(buf, PAGE_SIZE, "%d\n", value); > } > > +/** > + * DOC: pcie_bw > + * > + * The amdgpu driver provides a sysfs API for reading how much data > + * has been sent and received by the GPU in the last second through PCIe. > + * The file pcie_bw is used for this. > + * The Perf counters calculate this and return the number of sent and > received > + * messages, which we multiply by the maxsize of our PCIe packets (mps). > + * Note that it is not possible to easily and quickly obtain the size of each > + * packet transmitted, so we use the max payload size (mps) to estimate the > + * PCIe bandwidth usage > + */ > +static ssize_t amdgpu_get_pcie_bw(struct device *dev, > + struct device_attribute *attr, > + char *buf) > +{ > + struct drm_device *ddev = dev_get_drvdata(dev); > + struct amdgpu_device *adev = ddev->dev_private; > + uint64_t mps = pcie_get_mps(adev->pdev); > + uint64_t count0, count1; > + > + amdgpu_asic_get_pcie_usage(adev, , ); > + return snprintf(buf, PAGE_SIZE, > + "Bytes received: %llu\nBytes sent: %llu\n", > + count0 * mps, count1 * mps); > +} > + > static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, > amdgpu_set_dpm_state); > static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, >amdgpu_get_dpm_forced_performance_level, > @@ -1025,6 +1052,7 @@ static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR, > amdgpu_set_pp_od_clk_voltage); > static DEVICE_ATTR(gpu_busy_percent, S_IRUGO, > amdgpu_get_busy_percent, NULL); > +static DEVICE_ATTR(pcie_bw, S_IRUGO, amdgpu_get_pcie_bw, NULL); > > static ssize_t amdgpu_hwmon_show_temp(struct device *dev, > struct device_attribute *attr, > @@ -2108,6 +2136,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) > "gpu_busy_level\n"); > return ret; > } > + /* PCIe Perf counters won't work on APU nodes */ > + if (adev->flags & !AMD_IS_APU) { > + ret = device_create_file(adev->dev, _attr_pcie_bw); > + if (ret) { > + DRM_ERROR("failed to create device file pcie_bw\n"); > + return ret; > + } > + } > ret = amdgpu_debugfs_pm_init(adev); > if (ret) { > DRM_ERROR("Failed to register debugfs file for dpm!\n"); > @@ -2147,6 +2183,8 @@ void amdgpu_pm_sysfs_fini(struct
Re: [PATCH] drm/amdgpu: Add sysfs file for PCIe usage v3
On Tue, Jan 8, 2019 at 11:02 AM Kuehling, Felix wrote: > > > On 2019-01-08 6:28 a.m., Russell, Kent wrote: > > 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 > > I think you only updated the code comment, but not the output in sysfs. > > More generally, most amdgpu sysfs files report a single value, or a set > of values separated by spaces. That makes it easier to parse by external > tools. It's also supposed to be a stable API. They don't usually include > human readable text such as "bytes received:". It would be up to a tool > such as rocm-smi to turn this into human-readable text. > > In keeping with that convention I'd suggest reporting the PCIe bandwidth > as three numbers: > > > > Then let the tool calculate the bytes estimate with the appropriate > warnings about how accurate that is. > > Alex does this match your understanding regarding sysfs conventions? Yes, agreed. Alex > > Regards, > Felix > > > v3: Don't make the file on APUs > > > > Signed-off-by: Kent Russell > > --- > > drivers/gpu/drm/amd/amdgpu/amdgpu.h| 4 > > drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 38 + > > drivers/gpu/drm/amd/amdgpu/cik.c | 41 +++ > > drivers/gpu/drm/amd/amdgpu/si.c| 41 +++ > > drivers/gpu/drm/amd/amdgpu/soc15.c | 44 > > ++ > > drivers/gpu/drm/amd/amdgpu/vi.c| 41 +++ > > 6 files changed, 209 insertions(+) > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > > index e1b2c64..512b124 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > > @@ -542,6 +542,9 @@ struct amdgpu_asic_funcs { > > bool (*need_full_reset)(struct amdgpu_device *adev); > > /* initialize doorbell layout for specific asic*/ > > void (*init_doorbell_index)(struct amdgpu_device *adev); > > + /* PCIe bandwidth usage */ > > + void (*get_pcie_usage)(struct amdgpu_device *adev, uint64_t *count0, > > +uint64_t *count1); > > }; > > > > /* > > @@ -1045,6 +1048,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev); > > #define amdgpu_asic_invalidate_hdp(adev, r) > > (adev)->asic_funcs->invalidate_hdp((adev), (r)) > > #define amdgpu_asic_need_full_reset(adev) > > (adev)->asic_funcs->need_full_reset((adev)) > > #define amdgpu_asic_init_doorbell_index(adev) > > (adev)->asic_funcs->init_doorbell_index((adev)) > > +#define amdgpu_asic_get_pcie_usage(adev, cnt0, cnt1) > > ((adev)->asic_funcs->get_pcie_usage((adev), (cnt0), (cnt1))) > > > > /* Common functions */ > > bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev); > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > > index 6896dec..d2b29fd 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > > @@ -990,6 +990,33 @@ static ssize_t amdgpu_get_busy_percent(struct device > > *dev, > > return snprintf(buf, PAGE_SIZE, "%d\n", value); > > } > > > > +/** > > + * DOC: pcie_bw > > + * > > + * The amdgpu driver provides a sysfs API for reading how much data > > + * has been sent and received by the GPU in the last second through PCIe. > > + * The file pcie_bw is used for this. > > + * The Perf counters calculate this and return the number of sent and > > received > > + * messages, which we multiply by the maxsize of our PCIe packets (mps). > > + * Note that it is not possible to easily and quickly obtain the size of > > each > > + * packet transmitted, so we use the max payload size (mps) to estimate the > > + * PCIe bandwidth usage > > + */ > > +static ssize_t amdgpu_get_pcie_bw(struct device *dev, > > + struct device_attribute *attr, > > + char *buf) > > +{ > > + struct drm_device *ddev = dev_get_drvdata(dev); > > + struct amdgpu_device *adev = ddev->dev_private; > > + uint64_t mps = pcie_get_mps(adev->pdev); > > + uint64_t count0, count1; > > + > > + amdgpu_asic_get_pcie_usage(adev, , ); > > + return snprintf(buf, PAGE_SIZE, > > + "Bytes received: %llu\nBytes sent: %llu\n", > > + count0 * mps, count1 * mps); > > +} > > + > > static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, > > amdgpu_get_dpm_state, amdgpu_set_dpm_state); > > static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, > > amdgpu_get_dpm_forced_performance_level, > > @@ -1025,6 +1052,7 @@ static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | > > S_IWUSR, > > amdgpu_set_pp_od_clk_voltage); > > static DEVICE_ATTR(gpu_busy_percent, S_IRUGO, > >
Re: [PATCH] drm/amdgpu: Add sysfs file for PCIe usage v3
On 2019-01-08 6:28 a.m., Russell, Kent wrote: > 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 I think you only updated the code comment, but not the output in sysfs. More generally, most amdgpu sysfs files report a single value, or a set of values separated by spaces. That makes it easier to parse by external tools. It's also supposed to be a stable API. They don't usually include human readable text such as "bytes received:". It would be up to a tool such as rocm-smi to turn this into human-readable text. In keeping with that convention I'd suggest reporting the PCIe bandwidth as three numbers: Then let the tool calculate the bytes estimate with the appropriate warnings about how accurate that is. Alex does this match your understanding regarding sysfs conventions? Regards, Felix > v3: Don't make the file on APUs > > Signed-off-by: Kent Russell > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h| 4 > drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 38 + > drivers/gpu/drm/amd/amdgpu/cik.c | 41 +++ > drivers/gpu/drm/amd/amdgpu/si.c| 41 +++ > drivers/gpu/drm/amd/amdgpu/soc15.c | 44 > ++ > drivers/gpu/drm/amd/amdgpu/vi.c| 41 +++ > 6 files changed, 209 insertions(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index e1b2c64..512b124 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -542,6 +542,9 @@ struct amdgpu_asic_funcs { > bool (*need_full_reset)(struct amdgpu_device *adev); > /* initialize doorbell layout for specific asic*/ > void (*init_doorbell_index)(struct amdgpu_device *adev); > + /* PCIe bandwidth usage */ > + void (*get_pcie_usage)(struct amdgpu_device *adev, uint64_t *count0, > +uint64_t *count1); > }; > > /* > @@ -1045,6 +1048,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev); > #define amdgpu_asic_invalidate_hdp(adev, r) > (adev)->asic_funcs->invalidate_hdp((adev), (r)) > #define amdgpu_asic_need_full_reset(adev) > (adev)->asic_funcs->need_full_reset((adev)) > #define amdgpu_asic_init_doorbell_index(adev) > (adev)->asic_funcs->init_doorbell_index((adev)) > +#define amdgpu_asic_get_pcie_usage(adev, cnt0, cnt1) > ((adev)->asic_funcs->get_pcie_usage((adev), (cnt0), (cnt1))) > > /* Common functions */ > bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev); > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > index 6896dec..d2b29fd 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c > @@ -990,6 +990,33 @@ static ssize_t amdgpu_get_busy_percent(struct device > *dev, > return snprintf(buf, PAGE_SIZE, "%d\n", value); > } > > +/** > + * DOC: pcie_bw > + * > + * The amdgpu driver provides a sysfs API for reading how much data > + * has been sent and received by the GPU in the last second through PCIe. > + * The file pcie_bw is used for this. > + * The Perf counters calculate this and return the number of sent and > received > + * messages, which we multiply by the maxsize of our PCIe packets (mps). > + * Note that it is not possible to easily and quickly obtain the size of each > + * packet transmitted, so we use the max payload size (mps) to estimate the > + * PCIe bandwidth usage > + */ > +static ssize_t amdgpu_get_pcie_bw(struct device *dev, > + struct device_attribute *attr, > + char *buf) > +{ > + struct drm_device *ddev = dev_get_drvdata(dev); > + struct amdgpu_device *adev = ddev->dev_private; > + uint64_t mps = pcie_get_mps(adev->pdev); > + uint64_t count0, count1; > + > + amdgpu_asic_get_pcie_usage(adev, , ); > + return snprintf(buf, PAGE_SIZE, > + "Bytes received: %llu\nBytes sent: %llu\n", > + count0 * mps, count1 * mps); > +} > + > static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, > amdgpu_set_dpm_state); > static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, > amdgpu_get_dpm_forced_performance_level, > @@ -1025,6 +1052,7 @@ static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR, > amdgpu_set_pp_od_clk_voltage); > static DEVICE_ATTR(gpu_busy_percent, S_IRUGO, > amdgpu_get_busy_percent, NULL); > +static DEVICE_ATTR(pcie_bw, S_IRUGO, amdgpu_get_pcie_bw, NULL); > > static ssize_t amdgpu_hwmon_show_temp(struct device *dev, > struct device_attribute *attr, > @@ -2108,6 +2136,14 @@ int amdgpu_pm_sysfs_init(struct
[PATCH] drm/amdgpu: Add sysfs file for PCIe usage v3
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 Signed-off-by: Kent Russell --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 4 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 38 + drivers/gpu/drm/amd/amdgpu/cik.c | 41 +++ drivers/gpu/drm/amd/amdgpu/si.c| 41 +++ drivers/gpu/drm/amd/amdgpu/soc15.c | 44 ++ drivers/gpu/drm/amd/amdgpu/vi.c| 41 +++ 6 files changed, 209 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index e1b2c64..512b124 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -542,6 +542,9 @@ struct amdgpu_asic_funcs { bool (*need_full_reset)(struct amdgpu_device *adev); /* initialize doorbell layout for specific asic*/ void (*init_doorbell_index)(struct amdgpu_device *adev); + /* PCIe bandwidth usage */ + void (*get_pcie_usage)(struct amdgpu_device *adev, uint64_t *count0, + uint64_t *count1); }; /* @@ -1045,6 +1048,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev); #define amdgpu_asic_invalidate_hdp(adev, r) (adev)->asic_funcs->invalidate_hdp((adev), (r)) #define amdgpu_asic_need_full_reset(adev) (adev)->asic_funcs->need_full_reset((adev)) #define amdgpu_asic_init_doorbell_index(adev) (adev)->asic_funcs->init_doorbell_index((adev)) +#define amdgpu_asic_get_pcie_usage(adev, cnt0, cnt1) ((adev)->asic_funcs->get_pcie_usage((adev), (cnt0), (cnt1))) /* Common functions */ bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 6896dec..d2b29fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -990,6 +990,33 @@ static ssize_t amdgpu_get_busy_percent(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", value); } +/** + * DOC: pcie_bw + * + * The amdgpu driver provides a sysfs API for reading how much data + * has been sent and received by the GPU in the last second through PCIe. + * The file pcie_bw is used for this. + * The Perf counters calculate this and return the number of sent and received + * messages, which we multiply by the maxsize of our PCIe packets (mps). + * Note that it is not possible to easily and quickly obtain the size of each + * packet transmitted, so we use the max payload size (mps) to estimate the + * PCIe bandwidth usage + */ +static ssize_t amdgpu_get_pcie_bw(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + uint64_t mps = pcie_get_mps(adev->pdev); + uint64_t count0, count1; + + amdgpu_asic_get_pcie_usage(adev, , ); + return snprintf(buf, PAGE_SIZE, + "Bytes received: %llu\nBytes sent: %llu\n", + count0 * mps, count1 * mps); +} + static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state); static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, amdgpu_get_dpm_forced_performance_level, @@ -1025,6 +1052,7 @@ static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR, amdgpu_set_pp_od_clk_voltage); static DEVICE_ATTR(gpu_busy_percent, S_IRUGO, amdgpu_get_busy_percent, NULL); +static DEVICE_ATTR(pcie_bw, S_IRUGO, amdgpu_get_pcie_bw, NULL); static ssize_t amdgpu_hwmon_show_temp(struct device *dev, struct device_attribute *attr, @@ -2108,6 +2136,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) "gpu_busy_level\n"); return ret; } + /* PCIe Perf counters won't work on APU nodes */ + if (adev->flags & !AMD_IS_APU) { + ret = device_create_file(adev->dev, _attr_pcie_bw); + if (ret) { + DRM_ERROR("failed to create device file pcie_bw\n"); + return ret; + } + } ret = amdgpu_debugfs_pm_init(adev); if (ret) { DRM_ERROR("Failed to register debugfs file for dpm!\n"); @@ -2147,6 +2183,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) device_remove_file(adev->dev, _attr_pp_od_clk_voltage); device_remove_file(adev->dev, _attr_gpu_busy_percent); + if (adev->flags & !AMD_IS_APU) + device_remove_file(adev->dev,