[PATCH V3 3/3] drm/amdgpu/smu15: set up metrics DRAM mapping and prev buffer once
Shubhankar Milind Sardeshpande <[email protected]> Fri, 24 Jul 2026 17:33:44 +0530
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
The metrics path re-resolved and ioremap()'d the firmware log DRAM address on every read, and kzalloc()/kfree()'d a previous-sample scratch buffer on every sensor query. Set both up once at table init and tear them down at fini: - Add cpu_addr and prev_metrics to SMU_15_0_0_MetricsInfo_t. - Add smu_v15_0_0_get_metrics_table_dram_addr() to query the address and ioremap_wc() it from init_smc_tables(); allocate prev_metrics there too, extending the error-unwind ladder. - get_metrics_table() reuses the persistent cpu_addr. - get_smu_metrics_data() reuses the persistent prev_metrics buffer. - fini_smc_tables() iounmap()s cpu_addr and frees prev_metrics. Signed-off-by: Shubhankar Milind Sardeshpande <[email protected]> --- .../drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c | 99 +++++++++++-------- .../drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h | 2 + 2 files changed, 62 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c index 1d268a02992e..31cf538246fa 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c @@ -165,10 +165,37 @@ static struct cmn2asic_mapping smu_v15_0_0_table_map[SMU_TABLE_COUNT] = { TAB_MAP_VALID(DPMCLOCKS), }; +static int smu_v15_0_0_get_metrics_table_dram_addr(struct smu_context *smu, + SMU_15_0_0_MetricsInfo_t *metrics_info) +{ + struct smu_msg_ctl *ctl = &smu->msg_ctl; + struct smu_msg_args args = { + .msg = SMU_MSG_GetMetricsTableLogDramAddr, + .num_args = 0, + .num_out_args = 3, + }; + int ret; + + ret = ctl->ops->send_msg(ctl, &args); + if (ret) + return ret; + + metrics_info->addr = ((uint64_t)args.out_args[1] << 32) | args.out_args[0]; + metrics_info->table_size = args.out_args[2]; + + metrics_info->cpu_addr = ioremap_wc(metrics_info->addr, + metrics_info->table_size); + if (!metrics_info->cpu_addr) + return -ENOMEM; + + return 0; +} + static int smu_v15_0_0_init_smc_tables(struct smu_context *smu) { struct smu_table_context *smu_table = &smu->smu_table; struct smu_table *tables = smu_table->tables; + SMU_15_0_0_MetricsInfo_t *metrics_info; int ret; SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t), @@ -197,8 +224,24 @@ static int smu_v15_0_0_init_smc_tables(struct smu_context *smu) if (ret) goto err3_out; + metrics_info = (SMU_15_0_0_MetricsInfo_t *)smu_table->metrics_table; + + metrics_info->prev_metrics = kzalloc_obj(SMU_15_0_0_MetricsInfo_t); + if (!metrics_info->prev_metrics) + goto err4_out; + + if (metrics_info->addr == 0) { + ret = smu_v15_0_0_get_metrics_table_dram_addr(smu, metrics_info); + if (ret) + goto err5_out; + } + return 0; +err5_out: + kfree(metrics_info->prev_metrics); +err4_out: + smu_driver_table_fini(smu, SMU_DRIVER_TABLE_GPU_METRICS); err3_out: kfree(smu_table->watermarks_table); err2_out: @@ -212,6 +255,16 @@ static int smu_v15_0_0_init_smc_tables(struct smu_context *smu) static int smu_v15_0_0_fini_smc_tables(struct smu_context *smu) { struct smu_table_context *smu_table = &smu->smu_table; + SMU_15_0_0_MetricsInfo_t *metrics_info = smu_table->metrics_table; + + if (metrics_info) { + if (metrics_info->cpu_addr) { + iounmap(metrics_info->cpu_addr); + metrics_info->cpu_addr = NULL; + } + kfree(metrics_info->prev_metrics); + metrics_info->prev_metrics = NULL; + } kfree(smu_table->clocks_table); smu_table->clocks_table = NULL; @@ -334,41 +387,20 @@ static int smu_v15_0_0_get_gpu_metrics_table(struct smu_context *smu, return 0; } - static int smu_v15_0_0_get_metrics_table(struct smu_context *smu, SMU_15_0_0_MetricsInfo_t *metrics_info) { struct smu_table_context *smu_table = &smu->smu_table; - void __iomem *cpu_addr = NULL; + void __iomem *cpu_addr = metrics_info->cpu_addr; struct smu_msg_ctl *ctl = &smu->msg_ctl; struct smu_msg_args args = {0}; int table_size = metrics_info->table_size; - uint64_t addr = metrics_info->addr; int ret; if (smu_table->metrics_time && !time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(1))) return 0; - if (addr == 0) { - struct smu_msg_args args = { - .msg = SMU_MSG_GetMetricsTableLogDramAddr, - .num_args = 0, - .num_out_args = 3, - }; - - ret = ctl->ops->send_msg(ctl, &args); - - if (ret) - return ret; - - addr = ((uint64_t)args.out_args[1] << 32) | args.out_args[0]; - table_size = args.out_args[2]; - metrics_info->addr = addr; - metrics_info->table_size = table_size; - } - - cpu_addr = ioremap_wc(addr, table_size); if (!cpu_addr) return -ENOMEM; @@ -384,7 +416,6 @@ static int smu_v15_0_0_get_metrics_table(struct smu_context *smu, else memcpy(&metrics_info->metrics, cpu_addr, sizeof(MetricsTable_t)); } - iounmap(cpu_addr); return ret; } @@ -455,25 +486,16 @@ static int smu_v15_0_0_get_smu_metrics_data(struct smu_context *smu, uint32_t *value) { struct smu_table_context *smu_table = &smu->smu_table; - - SMU_15_0_0_MetricsInfo_t *prev_metrics; - SMU_15_0_0_MetricsInfo_t *curr_metrics; + SMU_15_0_0_MetricsInfo_t *curr_metrics = + (SMU_15_0_0_MetricsInfo_t *)smu_table->metrics_table; + SMU_15_0_0_MetricsInfo_t *prev_metrics = curr_metrics->prev_metrics; int ret; - prev_metrics = kzalloc_obj(SMU_15_0_0_MetricsInfo_t); - if (!prev_metrics) - return -ENOMEM; - - memcpy(prev_metrics, smu_table->metrics_table, + memcpy(prev_metrics, curr_metrics, sizeof(SMU_15_0_0_MetricsInfo_t)); - ret = smu_v15_0_0_get_metrics_table(smu, - (SMU_15_0_0_MetricsInfo_t *)smu_table->metrics_table); - if (ret) { - kfree(prev_metrics); + ret = smu_v15_0_0_get_metrics_table(smu, curr_metrics); + if (ret) return ret; - } - - curr_metrics = (SMU_15_0_0_MetricsInfo_t *)smu_table->metrics_table; if (prev_metrics->metrics.IOD.AccumulationCounter != curr_metrics->metrics.IOD.AccumulationCounter) { @@ -483,7 +505,6 @@ static int smu_v15_0_0_get_smu_metrics_data(struct smu_context *smu, *value = curr_metrics->avg_metric[member]; - kfree(prev_metrics); return 0; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h index 8ee45591e9a6..27e7c60be15c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h @@ -31,6 +31,8 @@ typedef struct { MetricsTable_t metrics; uint32_t table_size; uint64_t addr; + void __iomem *cpu_addr; + void *prev_metrics; uint32_t avg_metric[METRICS_AVERAGE_NPUCLK+1]; } SMU_15_0_0_MetricsInfo_t; -- 2.43.0