Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amdgpu: fix return random value when multiple threads read registers via mes.

The currect code use the address "adev->mes.read_val_ptr" to
store the value read from register via mes.
So when multiple threads read register,
multiple threads have to share the one address,
and overwrite the value each other.

Assign an address by "amdgpu_device_wb_get" to store register value.
each thread will has an address to store register value.

Signed-off-by: chongli2 <chongli2@amd.com>
Reviewed-by: Emily Deng <Emily.Deng@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

chongli2 and committed by
Alex Deucher
f4a3246a cd82f29e

+13 -20
+13 -17
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
··· 192 192 (uint64_t *)&adev->wb.wb[adev->mes.query_status_fence_offs[i]]; 193 193 } 194 194 195 - r = amdgpu_device_wb_get(adev, &adev->mes.read_val_offs); 196 - if (r) { 197 - dev_err(adev->dev, 198 - "(%d) read_val_offs alloc failed\n", r); 199 - goto error; 200 - } 201 - adev->mes.read_val_gpu_addr = 202 - adev->wb.gpu_addr + (adev->mes.read_val_offs * 4); 203 - adev->mes.read_val_ptr = 204 - (uint32_t *)&adev->wb.wb[adev->mes.read_val_offs]; 205 - 206 195 r = amdgpu_mes_doorbell_init(adev); 207 196 if (r) 208 197 goto error; ··· 212 223 amdgpu_device_wb_free(adev, 213 224 adev->mes.query_status_fence_offs[i]); 214 225 } 215 - if (adev->mes.read_val_ptr) 216 - amdgpu_device_wb_free(adev, adev->mes.read_val_offs); 217 226 218 227 idr_destroy(&adev->mes.pasid_idr); 219 228 idr_destroy(&adev->mes.gang_id_idr); ··· 236 249 amdgpu_device_wb_free(adev, 237 250 adev->mes.query_status_fence_offs[i]); 238 251 } 239 - if (adev->mes.read_val_ptr) 240 - amdgpu_device_wb_free(adev, adev->mes.read_val_offs); 241 252 242 253 amdgpu_mes_doorbell_free(adev); 243 254 ··· 906 921 { 907 922 struct mes_misc_op_input op_input; 908 923 int r, val = 0; 924 + uint32_t addr_offset = 0; 925 + uint64_t read_val_gpu_addr; 926 + uint32_t *read_val_ptr; 909 927 928 + if (amdgpu_device_wb_get(adev, &addr_offset)) { 929 + DRM_ERROR("critical bug! too many mes readers\n"); 930 + goto error; 931 + } 932 + read_val_gpu_addr = adev->wb.gpu_addr + (addr_offset * 4); 933 + read_val_ptr = (uint32_t *)&adev->wb.wb[addr_offset]; 910 934 op_input.op = MES_MISC_OP_READ_REG; 911 935 op_input.read_reg.reg_offset = reg; 912 - op_input.read_reg.buffer_addr = adev->mes.read_val_gpu_addr; 936 + op_input.read_reg.buffer_addr = read_val_gpu_addr; 913 937 914 938 if (!adev->mes.funcs->misc_op) { 915 939 DRM_ERROR("mes rreg is not supported!\n"); ··· 929 935 if (r) 930 936 DRM_ERROR("failed to read reg (0x%x)\n", reg); 931 937 else 932 - val = *(adev->mes.read_val_ptr); 938 + val = *(read_val_ptr); 933 939 934 940 error: 941 + if (addr_offset) 942 + amdgpu_device_wb_free(adev, addr_offset); 935 943 return val; 936 944 } 937 945
-3
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
··· 120 120 uint32_t query_status_fence_offs[AMDGPU_MAX_MES_PIPES]; 121 121 uint64_t query_status_fence_gpu_addr[AMDGPU_MAX_MES_PIPES]; 122 122 uint64_t *query_status_fence_ptr[AMDGPU_MAX_MES_PIPES]; 123 - uint32_t read_val_offs; 124 - uint64_t read_val_gpu_addr; 125 - uint32_t *read_val_ptr; 126 123 127 124 uint32_t saved_flags; 128 125