dma_fence_is_signaled() can return true *while* the fence is signaling. This has caused explosions before and I guess we can agree that it's just not ideal.
The fundamental issue is that the fence-signaled-bit is set under lock protection but read without it. So ideally, we would read it with the lock. This would not change the relative order, i.e. the bit would still be true in the fence callbacks. Christian informs us that taking the lock causes people to complain about performance regressions because the lock-taking shoots down copied cache-lines. (which is weird since it would mean that someone is repeatedly polling on fences instead of just registering a callback to notify himself once it signals) Let's accept the potential for regressions as true for now. Nevertheless, I think I can propose a path towards removing the race: This series suggests taking the lock in dma_fence_is_signaled() *unless* the driver explicitly asks for a check with a race-condition. As a preparation, I allow drivers to set flags when initializing fences. Then, we add a flag with which the driver can switch locking off for that particular function. By default, we let all drivers take the lock. Should we then, in the kernel release process get reports about regressions, we can set the race-flag for the affected driver and restore the old behavior. Should there be no reports, we could phase the flag out again after a few releases, always taking the lock. New users would always see the lock. I put all potentially affected parties on Cc. Please point out if you can already foresee your driver being negatively affected by this. P. Philipp Stanner (6): dma-buf: dma-fence: Add flags parameter to dma_fence_init() dma-buf: dma-fence: Add flag for using 64-bit seqnos dma-buf: Port users of dma_fence_init64() dma-buf: dma-fence: remove dma_fence_init64() dma-buf: dma-fence: Close race in dma_fence_is_signaled() by default drm/nouveau: Remove hacky fence check drivers/accel/amdxdna/amdxdna_ctx.c | 2 +- drivers/accel/ethosu/ethosu_job.c | 2 +- drivers/accel/ivpu/ivpu_job.c | 2 +- drivers/accel/rocket/rocket_job.c | 2 +- drivers/dma-buf/dma-fence-array.c | 2 +- drivers/dma-buf/dma-fence-chain.c | 4 +- drivers/dma-buf/dma-fence.c | 44 +++++------------ drivers/dma-buf/st-dma-fence-chain.c | 2 +- drivers/dma-buf/st-dma-fence-unwrap.c | 2 +- drivers/dma-buf/st-dma-fence.c | 2 +- drivers/dma-buf/st-dma-resv.c | 2 +- drivers/dma-buf/sw_sync.c | 2 +- .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c | 2 +- .../drm/amd/amdgpu/amdgpu_eviction_fence.c | 7 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 2 +- .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 5 +- .../gpu/drm/amd/amdgpu/amdgpu_vm_tlb_fence.c | 5 +- drivers/gpu/drm/drm_crtc.c | 2 +- drivers/gpu/drm/drm_writeback.c | 2 +- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 2 +- drivers/gpu/drm/i915/i915_request.c | 2 +- drivers/gpu/drm/i915/i915_sw_fence_work.c | 2 +- drivers/gpu/drm/i915/i915_vma_resource.c | 2 +- .../gpu/drm/i915/selftests/i915_sw_fence.c | 2 +- drivers/gpu/drm/imagination/pvr_ccb.c | 2 +- drivers/gpu/drm/imagination/pvr_queue.c | 2 +- drivers/gpu/drm/lima/lima_sched.c | 2 +- drivers/gpu/drm/msm/msm_fence.c | 2 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 13 ----- drivers/gpu/drm/nouveau/nouveau_fence.c | 4 +- drivers/gpu/drm/panfrost/panfrost_job.c | 2 +- drivers/gpu/drm/panthor/panthor_sched.c | 2 +- drivers/gpu/drm/qxl/qxl_release.c | 2 +- drivers/gpu/drm/radeon/radeon_fence.c | 2 +- drivers/gpu/drm/scheduler/sched_fence.c | 4 +- .../gpu/drm/scheduler/tests/mock_scheduler.c | 2 +- drivers/gpu/drm/ttm/tests/ttm_bo_test.c | 2 +- .../gpu/drm/ttm/tests/ttm_bo_validate_test.c | 2 +- drivers/gpu/drm/v3d/v3d_fence.c | 2 +- drivers/gpu/drm/vc4/vc4_gem.c | 2 +- drivers/gpu/drm/vgem/vgem_fence.c | 2 +- drivers/gpu/drm/virtio/virtgpu_fence.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 2 +- drivers/gpu/drm/xe/xe_hw_fence.c | 2 +- drivers/gpu/drm/xe/xe_oa.c | 2 +- drivers/gpu/drm/xe/xe_preempt_fence.c | 2 +- drivers/gpu/drm/xe/xe_tlb_inval.c | 2 +- drivers/gpu/host1x/fence.c | 2 +- drivers/iio/industrialio-buffer.c | 2 +- drivers/usb/gadget/function/f_fs.c | 2 +- include/linux/dma-fence.h | 48 +++++++++++++++++-- 52 files changed, 115 insertions(+), 105 deletions(-) -- 2.56.0
