mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-10-26 10:57:38 +08:00
accel/amdxdna: Expose NPU device busy time via DRM fdinfo
Expose NPU device engine busy time through DRM fdinfo to enable standardized userspace monitoring and profiling. Add support for reporting per-engine busy time in nanoseconds via fdinfo using the "drm-engine-npu" key. The value reflects the accumulated NPU device execution time for a given process, allowing userspace tools to observe NPU device utilization without driver-specific ioctls. Signed-off-by: Max Zhen <max.zhen@amd.com> Reviewed-by: Lizhi Hou <lizhi.hou@amd.com> Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> Link: https://patch.msgid.link/20261012180808.2548697-1-max.zhen@amd.com
This commit is contained in:
1 parent
91f52e9982
commit
489a8539ca
6 files changed
+65
No files matched your search
@@ -289,6 +289,7 @@ Example of the output showing the implemented key value pairs:
|
||||
drm-driver: amdxdna_accel_driver
|
||||
drm-client-id: 3219
|
||||
drm-pdev: 0000:c5:00.1
|
||||
drm-engine-npu: 14003870 ns
|
||||
amdxdna_accel_driver-heap-alloc: 60 KiB
|
||||
amdxdna_accel_driver-internal-alloc: 67588 KiB
|
||||
amdxdna_accel_driver-external-alloc: 0
|
||||
|
||||
@@ -118,6 +118,45 @@ void amdxdna_vbnv_init(struct amdxdna_dev *xdna)
|
||||
amdxdna_update_vbnv(xdna, info->rev_vbnv_tbl, rev);
|
||||
}
|
||||
|
||||
void amdxdna_io_stats_job_start(struct amdxdna_client *client)
|
||||
{
|
||||
int depth;
|
||||
|
||||
guard(spinlock)(&client->io_stats.lock);
|
||||
|
||||
depth = client->io_stats.job_depth++;
|
||||
if (!depth)
|
||||
client->io_stats.start_time = ktime_get_ns();
|
||||
}
|
||||
|
||||
void amdxdna_io_stats_job_done(struct amdxdna_client *client)
|
||||
{
|
||||
u64 busy_ns;
|
||||
int depth;
|
||||
|
||||
guard(spinlock)(&client->io_stats.lock);
|
||||
|
||||
depth = --client->io_stats.job_depth;
|
||||
if (!depth) {
|
||||
busy_ns = ktime_get_ns() - client->io_stats.start_time;
|
||||
client->io_stats.start_time = 0;
|
||||
client->io_stats.busy_time += busy_ns;
|
||||
}
|
||||
}
|
||||
|
||||
u64 amdxdna_io_stats_busy_time_ns(struct amdxdna_client *client)
|
||||
{
|
||||
u64 busy_ns;
|
||||
|
||||
guard(spinlock)(&client->io_stats.lock);
|
||||
|
||||
busy_ns = client->io_stats.busy_time;
|
||||
if (client->io_stats.job_depth)
|
||||
busy_ns += ktime_get_ns() - client->io_stats.start_time;
|
||||
|
||||
return busy_ns;
|
||||
}
|
||||
|
||||
int amdxdna_get_metadata(struct aie_device *aie,
|
||||
struct amdxdna_client *client,
|
||||
struct amdxdna_drm_get_info *args)
|
||||
|
||||
@@ -117,4 +117,8 @@ void aie_smu_fini(struct smu_device *smu);
|
||||
int aie_smu_set_clocks(struct smu_device *smu, u32 *npuclk, u32 *hclk);
|
||||
int aie_smu_set_dpm(struct smu_device *smu, u32 dpm_level);
|
||||
|
||||
void amdxdna_io_stats_job_start(struct amdxdna_client *client);
|
||||
void amdxdna_io_stats_job_done(struct amdxdna_client *client);
|
||||
u64 amdxdna_io_stats_busy_time_ns(struct amdxdna_client *client);
|
||||
|
||||
#endif /* _AIE_H_ */
|
||||
@@ -290,6 +290,7 @@ aie2_sched_resp_handler(void *handle, void __iomem *data, size_t size)
|
||||
int ret = 0;
|
||||
u32 status;
|
||||
|
||||
amdxdna_io_stats_job_done(job->hwctx->client);
|
||||
cmd_abo = job->cmd_bo;
|
||||
|
||||
if (unlikely(job->job_timeout)) {
|
||||
@@ -322,6 +323,8 @@ aie2_sched_drvcmd_resp_handler(void *handle, void __iomem *data, size_t size)
|
||||
struct amdxdna_sched_job *job = handle;
|
||||
int ret = 0;
|
||||
|
||||
amdxdna_io_stats_job_done(job->hwctx->client);
|
||||
|
||||
if (unlikely(!data || size != sizeof(u32))) {
|
||||
job->drv_cmd->result = U32_MAX;
|
||||
ret = -EINVAL;
|
||||
@@ -344,6 +347,7 @@ aie2_sched_cmdlist_resp_handler(void *handle, void __iomem *data, size_t size)
|
||||
u32 cmd_status;
|
||||
int ret = 0;
|
||||
|
||||
amdxdna_io_stats_job_done(job->hwctx->client);
|
||||
cmd_abo = job->cmd_bo;
|
||||
|
||||
if (unlikely(job->job_timeout)) {
|
||||
@@ -405,6 +409,7 @@ aie2_sched_job_run(struct drm_sched_job *sched_job)
|
||||
kref_get(&job->refcnt);
|
||||
fence = dma_fence_get(job->fence);
|
||||
|
||||
amdxdna_io_stats_job_start(job->hwctx->client);
|
||||
if (job->drv_cmd) {
|
||||
switch (job->drv_cmd->opcode) {
|
||||
case SYNC_DEBUG_BO:
|
||||
@@ -432,6 +437,7 @@ aie2_sched_job_run(struct drm_sched_job *sched_job)
|
||||
|
||||
out:
|
||||
if (ret) {
|
||||
amdxdna_io_stats_job_done(job->hwctx->client);
|
||||
dma_fence_put(job->fence);
|
||||
aie2_job_put(job);
|
||||
mmput(job->mm);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "aie.h"
|
||||
#include "amdxdna_cbuf.h"
|
||||
#include "amdxdna_ctx.h"
|
||||
#include "amdxdna_debugfs.h"
|
||||
@@ -151,6 +152,8 @@ static int amdxdna_drm_open(struct drm_device *ddev, struct drm_file *filp)
|
||||
filp->driver_priv = client;
|
||||
client->filp = filp;
|
||||
|
||||
spin_lock_init(&client->io_stats.lock);
|
||||
|
||||
XDNA_DBG(xdna, "pid %d opened", client->pid);
|
||||
return 0;
|
||||
|
||||
@@ -287,6 +290,9 @@ static void amdxdna_show_fdinfo(struct drm_printer *p, struct drm_file *filp)
|
||||
size_t heap_usage, external_usage, internal_usage;
|
||||
char *drv_name = filp->minor->dev->driver->name;
|
||||
|
||||
drm_printf(p, "drm-engine-npu:\t%llu ns\n",
|
||||
amdxdna_io_stats_busy_time_ns(client));
|
||||
|
||||
mutex_lock(&client->mm_lock);
|
||||
|
||||
heap_usage = client->heap_usage;
|
||||
|
||||
@@ -143,6 +143,13 @@ struct amdxdna_device_id {
|
||||
const struct amdxdna_dev_info *dev_info;
|
||||
};
|
||||
|
||||
struct amdxdna_io_stats {
|
||||
spinlock_t lock; /* protect io stats */
|
||||
int job_depth;
|
||||
u64 start_time;
|
||||
u64 busy_time;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct amdxdna_client - amdxdna client
|
||||
* A per fd data structure for managing context and other user process stuffs.
|
||||
@@ -169,6 +176,8 @@ struct amdxdna_client {
|
||||
size_t heap_usage;
|
||||
size_t total_bo_usage;
|
||||
size_t total_int_bo_usage;
|
||||
|
||||
struct amdxdna_io_stats io_stats;
|
||||
};
|
||||
|
||||
#define amdxdna_for_each_hwctx(client, hwctx_id, entry) \
|
||||
|
||||
Reference in new issue
Block a user