]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amdgpu: Use active umc info from discovery
authorLijo Lazar <lijo.lazar@amd.com>
Wed, 1 Jan 2025 08:53:31 +0000 (14:23 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 13 Feb 2025 02:02:56 +0000 (21:02 -0500)
There could be configs where some UMC instances are harvested. This
information is obtained through discovery data and populated in
umc.active_mask. Avoid reassigning this as AID mask, instead use the
mask directly while iterating through umc instances. This is to avoid
accesses to harvested UMC instances.

v2: fix warning (Alex)

Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c

index eafe20d8fe0b65e81125f463325885305ce8dd4a..0a1ef95b28668c8a7f304269f2fbf488b4b4e3cd 100644 (file)
@@ -387,6 +387,45 @@ int amdgpu_umc_fill_error_record(struct ras_err_data *err_data,
        return 0;
 }
 
+static int amdgpu_umc_loop_all_aid(struct amdgpu_device *adev, umc_func func,
+                                  void *data)
+{
+       uint32_t umc_node_inst;
+       uint32_t node_inst;
+       uint32_t umc_inst;
+       uint32_t ch_inst;
+       int ret;
+
+       /*
+        * This loop is done based on the following -
+        * umc.active mask = mask of active umc instances across all nodes
+        * umc.umc_inst_num = maximum number of umc instancess per node
+        * umc.node_inst_num = maximum number of node instances
+        * Channel instances are not assumed to be harvested.
+        */
+       dev_dbg(adev->dev, "active umcs :%lx umc_inst per node: %d",
+               adev->umc.active_mask, adev->umc.umc_inst_num);
+       for_each_set_bit(umc_node_inst, &(adev->umc.active_mask),
+                        adev->umc.node_inst_num * adev->umc.umc_inst_num) {
+               node_inst = umc_node_inst / adev->umc.umc_inst_num;
+               umc_inst = umc_node_inst % adev->umc.umc_inst_num;
+               LOOP_UMC_CH_INST(ch_inst) {
+                       dev_dbg(adev->dev,
+                               "node_inst :%d umc_inst: %d ch_inst: %d",
+                               node_inst, umc_inst, ch_inst);
+                       ret = func(adev, node_inst, umc_inst, ch_inst, data);
+                       if (ret) {
+                               dev_err(adev->dev,
+                                       "Node %d umc %d ch %d func returns %d\n",
+                                       node_inst, umc_inst, ch_inst, ret);
+                               return ret;
+                       }
+               }
+       }
+
+       return 0;
+}
+
 int amdgpu_umc_loop_channels(struct amdgpu_device *adev,
                        umc_func func, void *data)
 {
@@ -395,6 +434,9 @@ int amdgpu_umc_loop_channels(struct amdgpu_device *adev,
        uint32_t ch_inst         = 0;
        int ret = 0;
 
+       if (adev->aid_mask)
+               return amdgpu_umc_loop_all_aid(adev, func, data);
+
        if (adev->umc.node_inst_num) {
                LOOP_UMC_EACH_NODE_INST_AND_CH(node_inst, umc_inst, ch_inst) {
                        ret = func(adev, node_inst, umc_inst, ch_inst, data);
index 291549765c38c5b18f92d477d9038bd044192f0c..71b8ae7f2194ede001bc1561bdff02c88e93a661 100644 (file)
@@ -1504,7 +1504,6 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev)
                adev->umc.umc_inst_num = UMC_V12_0_UMC_INSTANCE_NUM;
                adev->umc.node_inst_num /= UMC_V12_0_UMC_INSTANCE_NUM;
                adev->umc.channel_offs = UMC_V12_0_PER_CHANNEL_OFFSET;
-               adev->umc.active_mask = adev->aid_mask;
                adev->umc.retire_unit = UMC_V12_0_BAD_PAGE_NUM_PER_CHANNEL;
                if (!adev->gmc.xgmi.connected_to_cpu && !adev->gmc.is_app_apu)
                        adev->umc.ras = &umc_v12_0_ras;