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

drm/amdgpu: unwrap fence chains in the explicit sync fence

Unwrap the explicit fence if it is a dma_fence_chain and
sync to the first fence not matching the owner rules.

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20210614174536.5188-1-christian.koenig@amd.com

+68 -50
+68 -50
drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
··· 28 28 * Christian König <christian.koenig@amd.com> 29 29 */ 30 30 31 + #include <linux/dma-fence-chain.h> 32 + 31 33 #include "amdgpu.h" 32 34 #include "amdgpu_trace.h" 33 35 #include "amdgpu_amdkfd.h" ··· 188 186 return amdgpu_sync_fence(sync, fence); 189 187 } 190 188 189 + /* Determine based on the owner and mode if we should sync to a fence or not */ 190 + static bool amdgpu_sync_test_fence(struct amdgpu_device *adev, 191 + enum amdgpu_sync_mode mode, 192 + void *owner, struct dma_fence *f) 193 + { 194 + void *fence_owner = amdgpu_sync_get_owner(f); 195 + 196 + /* Always sync to moves, no matter what */ 197 + if (fence_owner == AMDGPU_FENCE_OWNER_UNDEFINED) 198 + return true; 199 + 200 + /* We only want to trigger KFD eviction fences on 201 + * evict or move jobs. Skip KFD fences otherwise. 202 + */ 203 + if (fence_owner == AMDGPU_FENCE_OWNER_KFD && 204 + owner != AMDGPU_FENCE_OWNER_UNDEFINED) 205 + return false; 206 + 207 + /* Never sync to VM updates either. */ 208 + if (fence_owner == AMDGPU_FENCE_OWNER_VM && 209 + owner != AMDGPU_FENCE_OWNER_UNDEFINED) 210 + return false; 211 + 212 + /* Ignore fences depending on the sync mode */ 213 + switch (mode) { 214 + case AMDGPU_SYNC_ALWAYS: 215 + return true; 216 + 217 + case AMDGPU_SYNC_NE_OWNER: 218 + if (amdgpu_sync_same_dev(adev, f) && 219 + fence_owner == owner) 220 + return false; 221 + break; 222 + 223 + case AMDGPU_SYNC_EQ_OWNER: 224 + if (amdgpu_sync_same_dev(adev, f) && 225 + fence_owner != owner) 226 + return false; 227 + break; 228 + 229 + case AMDGPU_SYNC_EXPLICIT: 230 + return false; 231 + } 232 + 233 + WARN(debug_evictions && fence_owner == AMDGPU_FENCE_OWNER_KFD, 234 + "Adding eviction fence to sync obj"); 235 + return true; 236 + } 237 + 191 238 /** 192 239 * amdgpu_sync_resv - sync to a reservation object 193 240 * ··· 262 211 263 212 /* always sync to the exclusive fence */ 264 213 f = dma_resv_excl_fence(resv); 265 - r = amdgpu_sync_fence(sync, f); 214 + dma_fence_chain_for_each(f, f) { 215 + struct dma_fence_chain *chain = to_dma_fence_chain(f); 216 + 217 + if (amdgpu_sync_test_fence(adev, mode, owner, chain ? 218 + chain->fence : f)) { 219 + r = amdgpu_sync_fence(sync, f); 220 + dma_fence_put(f); 221 + if (r) 222 + return r; 223 + break; 224 + } 225 + } 266 226 267 227 flist = dma_resv_shared_list(resv); 268 - if (!flist || r) 269 - return r; 228 + if (!flist) 229 + return 0; 270 230 271 231 for (i = 0; i < flist->shared_count; ++i) { 272 - void *fence_owner; 273 - 274 232 f = rcu_dereference_protected(flist->shared[i], 275 233 dma_resv_held(resv)); 276 234 277 - fence_owner = amdgpu_sync_get_owner(f); 278 - 279 - /* Always sync to moves, no matter what */ 280 - if (fence_owner == AMDGPU_FENCE_OWNER_UNDEFINED) { 235 + if (amdgpu_sync_test_fence(adev, mode, owner, f)) { 281 236 r = amdgpu_sync_fence(sync, f); 282 237 if (r) 283 - break; 238 + return r; 284 239 } 285 - 286 - /* We only want to trigger KFD eviction fences on 287 - * evict or move jobs. Skip KFD fences otherwise. 288 - */ 289 - if (fence_owner == AMDGPU_FENCE_OWNER_KFD && 290 - owner != AMDGPU_FENCE_OWNER_UNDEFINED) 291 - continue; 292 - 293 - /* Never sync to VM updates either. */ 294 - if (fence_owner == AMDGPU_FENCE_OWNER_VM && 295 - owner != AMDGPU_FENCE_OWNER_UNDEFINED) 296 - continue; 297 - 298 - /* Ignore fences depending on the sync mode */ 299 - switch (mode) { 300 - case AMDGPU_SYNC_ALWAYS: 301 - break; 302 - 303 - case AMDGPU_SYNC_NE_OWNER: 304 - if (amdgpu_sync_same_dev(adev, f) && 305 - fence_owner == owner) 306 - continue; 307 - break; 308 - 309 - case AMDGPU_SYNC_EQ_OWNER: 310 - if (amdgpu_sync_same_dev(adev, f) && 311 - fence_owner != owner) 312 - continue; 313 - break; 314 - 315 - case AMDGPU_SYNC_EXPLICIT: 316 - continue; 317 - } 318 - 319 - WARN(debug_evictions && fence_owner == AMDGPU_FENCE_OWNER_KFD, 320 - "Adding eviction fence to sync obj"); 321 - r = amdgpu_sync_fence(sync, f); 322 - if (r) 323 - break; 324 240 } 325 - return r; 241 + return 0; 326 242 } 327 243 328 244 /**