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


Reply via email to