]> www.infradead.org Git - users/hch/misc.git/commitdiff
drm/amd/pm: Add caching for SystemMetrics table
authorLijo Lazar <lijo.lazar@amd.com>
Thu, 28 Aug 2025 04:32:35 +0000 (10:02 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 5 Sep 2025 21:38:40 +0000 (17:38 -0400)
Implement caching separately for SystemMetrics table from PMFW. The same
table could be used for multiple interfaces. Hence, cache it internally
to avoid multiple queries to the firmware. For SystemMetrics table, 5ms
cache interval is sufficient.

Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Asad Kamal <asad.kamal@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h

index 5dd49eca598d68d25b81efadf7f331d8c8c7d3fd..5976eda8003578ed2d8350a2a6621d9dc4fedd58 100644 (file)
@@ -333,6 +333,7 @@ enum smu_table_id {
        SMU_TABLE_WIFIBAND,
        SMU_TABLE_GPUBOARD_TEMP_METRICS,
        SMU_TABLE_BASEBOARD_TEMP_METRICS,
+       SMU_TABLE_PMFW_SYSTEM_METRICS,
        SMU_TABLE_COUNT,
 };
 
index 32fd0be05cffb7f58e6e8ce0f916a9f8b4922097..0bec12b348cedf3fb58897a338464766169fabb5 100644 (file)
@@ -149,6 +149,12 @@ int smu_v13_0_12_tables_init(struct smu_context *smu)
        struct smu_table_cache *cache;
        int ret;
 
+       ret = smu_table_cache_init(smu, SMU_TABLE_PMFW_SYSTEM_METRICS,
+                                  smu_v13_0_12_get_system_metrics_size(), 5);
+
+       if (ret)
+               return ret;
+
        ret = smu_table_cache_init(smu, SMU_TABLE_BASEBOARD_TEMP_METRICS,
                                   sizeof(*baseboard_temp_metrics), 50);
        if (ret)
@@ -162,6 +168,7 @@ int smu_v13_0_12_tables_init(struct smu_context *smu)
        ret = smu_table_cache_init(smu, SMU_TABLE_GPUBOARD_TEMP_METRICS,
                                   sizeof(*gpuboard_temp_metrics), 50);
        if (ret) {
+               smu_table_cache_fini(smu, SMU_TABLE_PMFW_SYSTEM_METRICS);
                smu_table_cache_fini(smu, SMU_TABLE_BASEBOARD_TEMP_METRICS);
                return ret;
        }
@@ -176,6 +183,7 @@ void smu_v13_0_12_tables_fini(struct smu_context *smu)
 {
        smu_table_cache_fini(smu, SMU_TABLE_BASEBOARD_TEMP_METRICS);
        smu_table_cache_fini(smu, SMU_TABLE_GPUBOARD_TEMP_METRICS);
+       smu_table_cache_fini(smu, SMU_TABLE_PMFW_SYSTEM_METRICS);
 }
 
 static int smu_v13_0_12_get_enabled_mask(struct smu_context *smu,
@@ -222,8 +230,12 @@ static int smu_v13_0_12_fru_get_product_info(struct smu_context *smu,
 
 int smu_v13_0_12_get_max_metrics_size(void)
 {
-       return max3(sizeof(StaticMetricsTable_t), sizeof(MetricsTable_t),
-                  sizeof(SystemMetricsTable_t));
+       return max(sizeof(StaticMetricsTable_t), sizeof(MetricsTable_t));
+}
+
+size_t smu_v13_0_12_get_system_metrics_size(void)
+{
+       return sizeof(SystemMetricsTable_t);
 }
 
 static void smu_v13_0_12_init_xgmi_data(struct smu_context *smu,
@@ -414,14 +426,18 @@ int smu_v13_0_12_get_smu_metrics_data(struct smu_context *smu,
        return 0;
 }
 
-static int smu_v13_0_12_get_system_metrics_table(struct smu_context *smu,
-                                                void *metrics_table)
+static int smu_v13_0_12_get_system_metrics_table(struct smu_context *smu)
 {
        struct smu_table_context *smu_table = &smu->smu_table;
-       uint32_t table_size = smu_table->tables[SMU_TABLE_SMU_METRICS].size;
        struct smu_table *table = &smu_table->driver_table;
+       struct smu_table *tables = smu_table->tables;
+       struct smu_table *sys_table;
        int ret;
 
+       sys_table = &tables[SMU_TABLE_PMFW_SYSTEM_METRICS];
+       if (smu_table_cache_is_valid(sys_table))
+               return 0;
+
        ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetSystemMetricsTable, NULL);
        if (ret) {
                dev_info(smu->adev->dev,
@@ -430,10 +446,9 @@ static int smu_v13_0_12_get_system_metrics_table(struct smu_context *smu,
        }
 
        amdgpu_asic_invalidate_hdp(smu->adev, NULL);
-       memcpy(smu_table->metrics_table, table->cpu_addr, table_size);
-
-       if (metrics_table)
-               memcpy(metrics_table, smu_table->metrics_table, sizeof(SystemMetricsTable_t));
+       smu_table_cache_update_time(sys_table, jiffies);
+       memcpy(sys_table->cache.buffer, table->cpu_addr,
+              smu_v13_0_12_get_system_metrics_size());
 
        return 0;
 }
@@ -571,10 +586,10 @@ static ssize_t smu_v13_0_12_get_temp_metrics(struct smu_context *smu,
        struct amdgpu_baseboard_temp_metrics_v1_0 *baseboard_temp_metrics;
        struct amdgpu_gpuboard_temp_metrics_v1_0 *gpuboard_temp_metrics;
        struct smu_table_context *smu_table = &smu->smu_table;
-       SystemMetricsTable_t *metrics =
-               (SystemMetricsTable_t *)smu_table->metrics_table;
-
+       struct smu_table *tables = smu_table->tables;
+       SystemMetricsTable_t *metrics;
        struct smu_table *data_table;
+       struct smu_table *sys_table;
        int ret, sensor_type;
        u32 idx, sensors;
        ssize_t size;
@@ -596,10 +611,12 @@ static ssize_t smu_v13_0_12_get_temp_metrics(struct smu_context *smu,
                size = sizeof(*baseboard_temp_metrics);
        }
 
-       ret = smu_v13_0_12_get_system_metrics_table(smu, NULL);
+       ret = smu_v13_0_12_get_system_metrics_table(smu);
        if (ret)
                return ret;
 
+       sys_table = &tables[SMU_TABLE_PMFW_SYSTEM_METRICS];
+       metrics = (SystemMetricsTable_t *)sys_table->cache.buffer;
        smu_table_cache_update_time(data_table, jiffies);
 
        if (type == SMU_TEMP_METRIC_GPUBOARD) {
index e37b7b5358ea2ec1fdd016ee1ce73e3d2e421343..ebee659f8a1c557cda370e906523c3d70d0babaf 100644 (file)
@@ -559,6 +559,10 @@ static int smu_v13_0_6_tables_init(struct smu_context *smu)
                       PAGE_SIZE,
                       AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT);
 
+       SMU_TABLE_INIT(tables, SMU_TABLE_PMFW_SYSTEM_METRICS,
+                      smu_v13_0_12_get_system_metrics_size(), PAGE_SIZE,
+                      AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT);
+
        metrics_table = kzalloc(METRICS_TABLE_SIZE, GFP_KERNEL);
        if (!metrics_table)
                return -ENOMEM;
index bcb8246c080425c239d5afb0bc902c1e1956acb4..aae9a546a67e805dbd72950f86e9f9f34b6347bd 100644 (file)
@@ -82,6 +82,7 @@ int smu_v13_0_6_get_metrics_table(struct smu_context *smu, void *metrics_table,
 
 bool smu_v13_0_12_is_dpm_running(struct smu_context *smu);
 int smu_v13_0_12_get_max_metrics_size(void);
+size_t smu_v13_0_12_get_system_metrics_size(void);
 int smu_v13_0_12_setup_driver_pptable(struct smu_context *smu);
 int smu_v13_0_12_get_smu_metrics_data(struct smu_context *smu,
                                      MetricsMember_t member, uint32_t *value);