[PATCH] drm/amdgpu: clean up and unify hw fence handling

Alex Deucher alexdeucher at gmail.com
Thu Aug 28 14:46:47 UTC 2025


On Thu, Aug 28, 2025 at 10:29 AM Christian König
<christian.koenig at amd.com> wrote:
>
>
>
> On 28.08.25 16:05, Alex Deucher wrote:
> > Decouple the amdgpu fence from the amdgpu_job structure.
> > This lets us clean up the separate fence ops for the embedded
> > fence and other fences.  This also allows us to allocate the
> > vm fence up front when we allocate the job.
> >
> > Cc: David.Wu3 at amd.com
> > Cc: christian.koenig at amd.com
> > Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
> > ---
> >
> > v2: Additional cleanup suggested by Christian
> >
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c |   2 +-
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c  |   7 +-
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c   | 140 ++------------------
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c      |  22 +--
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_job.c     |  41 ++++--
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_job.h     |   3 +-
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h    |   7 +-
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c      |   7 +-
> >  8 files changed, 64 insertions(+), 165 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
> > index f81608330a3d0..7ea3cb6491b1b 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
> > @@ -1902,7 +1902,7 @@ static void amdgpu_ib_preempt_mark_partial_job(struct amdgpu_ring *ring)
> >                       continue;
> >               }
> >               job = to_amdgpu_job(s_job);
> > -             if (preempted && (&job->hw_fence.base) == fence)
> > +             if (preempted && (&job->hw_fence->base) == fence)
> >                       /* mark the job as preempted */
> >                       job->preemption_status |= AMDGPU_IB_PREEMPTED;
> >       }
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > index 7783272a79302..add272fa31288 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > @@ -5798,11 +5798,6 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
> >               if (!amdgpu_ring_sched_ready(ring))
> >                       continue;
> >
> > -             /* Clear job fence from fence drv to avoid force_completion
> > -              * leave NULL and vm flush fence in fence drv
> > -              */
> > -             amdgpu_fence_driver_clear_job_fences(ring);
> > -
> >               /* after all hw jobs are reset, hw fence is meaningless, so force_completion */
> >               amdgpu_fence_driver_force_completion(ring);
> >       }
> > @@ -6526,7 +6521,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
> >        *
> >        * job->base holds a reference to parent fence
> >        */
> > -     if (job && dma_fence_is_signaled(&job->hw_fence.base)) {
> > +     if (job && dma_fence_is_signaled(&job->hw_fence->base)) {
> >               job_signaled = true;
> >               dev_info(adev->dev, "Guilty job already signaled, skipping HW reset");
> >               goto skip_hw_reset;
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > index 2d58aefbd68a7..1355fee0e978d 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > @@ -45,16 +45,11 @@
> >   * Cast helper
> >   */
> >  static const struct dma_fence_ops amdgpu_fence_ops;
> > -static const struct dma_fence_ops amdgpu_job_fence_ops;
> >  static inline struct amdgpu_fence *to_amdgpu_fence(struct dma_fence *f)
> >  {
> >       struct amdgpu_fence *__f = container_of(f, struct amdgpu_fence, base);
> >
> > -     if (__f->base.ops == &amdgpu_fence_ops ||
> > -         __f->base.ops == &amdgpu_job_fence_ops)
> > -             return __f;
> > -
> > -     return NULL;
> > +     return __f;
> >  }
> >
> >  /**
> > @@ -98,51 +93,33 @@ static u32 amdgpu_fence_read(struct amdgpu_ring *ring)
> >   * amdgpu_fence_emit - emit a fence on the requested ring
> >   *
> >   * @ring: ring the fence is associated with
> > - * @f: resulting fence object
> >   * @af: amdgpu fence input
> >   * @flags: flags to pass into the subordinate .emit_fence() call
> >   *
> >   * Emits a fence command on the requested ring (all asics).
> >   * Returns 0 on success, -ENOMEM on failure.
> >   */
> > -int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
> > -                   struct amdgpu_fence *af, unsigned int flags)
> > +int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af,
> > +                   unsigned int flags)
> >  {
> >       struct amdgpu_device *adev = ring->adev;
> >       struct dma_fence *fence;
> > -     struct amdgpu_fence *am_fence;
> >       struct dma_fence __rcu **ptr;
> >       uint32_t seq;
> >       int r;
> >
> > -     if (!af) {
> > -             /* create a separate hw fence */
> > -             am_fence = kzalloc(sizeof(*am_fence), GFP_KERNEL);
> > -             if (!am_fence)
> > -                     return -ENOMEM;
> > -     } else {
> > -             am_fence = af;
> > -     }
> > -     fence = &am_fence->base;
> > -     am_fence->ring = ring;
> > +     fence = &af->base;
> > +     af->ring = ring;
> >
> >       seq = ++ring->fence_drv.sync_seq;
> > -     am_fence->seq = seq;
> > -     if (af) {
> > -             dma_fence_init(fence, &amdgpu_job_fence_ops,
> > -                            &ring->fence_drv.lock,
> > -                            adev->fence_context + ring->idx, seq);
> > -             /* Against remove in amdgpu_job_{free, free_cb} */
> > -             dma_fence_get(fence);
> > -     } else {
> > -             dma_fence_init(fence, &amdgpu_fence_ops,
> > -                            &ring->fence_drv.lock,
> > -                            adev->fence_context + ring->idx, seq);
> > -     }
> > +     af->seq = seq;
>
> Why we have af->seq in the first place? That is identical to af->base.seq as far as I can see.

It must have been leftover from when I was working on the reset stuff.
I can drop it.

>
> > +     dma_fence_init(fence, &amdgpu_fence_ops,
> > +                    &ring->fence_drv.lock,
> > +                    adev->fence_context + ring->idx, seq);
> >
> >       amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,
> >                              seq, flags | AMDGPU_FENCE_FLAG_INT);
> > -     amdgpu_fence_save_wptr(fence);
> > +     amdgpu_fence_save_wptr(af);
> >       pm_runtime_get_noresume(adev_to_drm(adev)->dev);
> >       ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask];
> >       if (unlikely(rcu_dereference_protected(*ptr, 1))) {
> > @@ -167,8 +144,6 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
> >        */
> >       rcu_assign_pointer(*ptr, dma_fence_get(fence));
> >
> > -     *f = fence;
> > -
> >       return 0;
> >  }
> >
> > @@ -669,36 +644,6 @@ void amdgpu_fence_driver_hw_init(struct amdgpu_device *adev)
> >       }
> >  }
> >
> > -/**
> > - * amdgpu_fence_driver_clear_job_fences - clear job embedded fences of ring
> > - *
> > - * @ring: fence of the ring to be cleared
> > - *
> > - */
> > -void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring)
> > -{
> > -     int i;
> > -     struct dma_fence *old, **ptr;
> > -
> > -     for (i = 0; i <= ring->fence_drv.num_fences_mask; i++) {
> > -             ptr = &ring->fence_drv.fences[i];
> > -             old = rcu_dereference_protected(*ptr, 1);
> > -             if (old && old->ops == &amdgpu_job_fence_ops) {
> > -                     struct amdgpu_job *job;
> > -
> > -                     /* For non-scheduler bad job, i.e. failed ib test, we need to signal
> > -                      * it right here or we won't be able to track them in fence_drv
> > -                      * and they will remain unsignaled during sa_bo free.
> > -                      */
> > -                     job = container_of(old, struct amdgpu_job, hw_fence.base);
> > -                     if (!job->base.s_fence && !dma_fence_is_signaled(old))
> > -                             dma_fence_signal(old);
> > -                     RCU_INIT_POINTER(*ptr, NULL);
> > -                     dma_fence_put(old);
> > -             }
> > -     }
> > -}
> > -
> >  /**
> >   * amdgpu_fence_driver_set_error - set error code on fences
> >   * @ring: the ring which contains the fences
> > @@ -765,11 +710,9 @@ void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *fence)
> >       amdgpu_fence_process(fence->ring);
> >  }
> >
> > -void amdgpu_fence_save_wptr(struct dma_fence *fence)
> > +void amdgpu_fence_save_wptr(struct amdgpu_fence *af)
> >  {
> > -     struct amdgpu_fence *am_fence = container_of(fence, struct amdgpu_fence, base);
> > -
> > -     am_fence->wptr = am_fence->ring->wptr;
> > +     af->wptr = af->ring->wptr;
> >  }
> >
> >  static void amdgpu_ring_backup_unprocessed_command(struct amdgpu_ring *ring,
> > @@ -830,13 +773,6 @@ static const char *amdgpu_fence_get_timeline_name(struct dma_fence *f)
> >       return (const char *)to_amdgpu_fence(f)->ring->name;
> >  }
> >
> > -static const char *amdgpu_job_fence_get_timeline_name(struct dma_fence *f)
> > -{
> > -     struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence.base);
> > -
> > -     return (const char *)to_amdgpu_ring(job->base.sched)->name;
> > -}
> > -
> >  /**
> >   * amdgpu_fence_enable_signaling - enable signalling on fence
> >   * @f: fence
> > @@ -853,23 +789,6 @@ static bool amdgpu_fence_enable_signaling(struct dma_fence *f)
> >       return true;
> >  }
> >
> > -/**
> > - * amdgpu_job_fence_enable_signaling - enable signalling on job fence
> > - * @f: fence
> > - *
> > - * This is the simliar function with amdgpu_fence_enable_signaling above, it
> > - * only handles the job embedded fence.
> > - */
> > -static bool amdgpu_job_fence_enable_signaling(struct dma_fence *f)
> > -{
> > -     struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence.base);
> > -
> > -     if (!timer_pending(&to_amdgpu_ring(job->base.sched)->fence_drv.fallback_timer))
> > -             amdgpu_fence_schedule_fallback(to_amdgpu_ring(job->base.sched));
> > -
> > -     return true;
> > -}
> > -
> >  /**
> >   * amdgpu_fence_free - free up the fence memory
> >   *
> > @@ -885,21 +804,6 @@ static void amdgpu_fence_free(struct rcu_head *rcu)
> >       kfree(to_amdgpu_fence(f));
> >  }
> >
> > -/**
> > - * amdgpu_job_fence_free - free up the job with embedded fence
> > - *
> > - * @rcu: RCU callback head
> > - *
> > - * Free up the job with embedded fence after the RCU grace period.
> > - */
> > -static void amdgpu_job_fence_free(struct rcu_head *rcu)
> > -{
> > -     struct dma_fence *f = container_of(rcu, struct dma_fence, rcu);
> > -
> > -     /* free job if fence has a parent job */
> > -     kfree(container_of(f, struct amdgpu_job, hw_fence.base));
> > -}
> > -
> >  /**
> >   * amdgpu_fence_release - callback that fence can be freed
> >   *
> > @@ -913,19 +817,6 @@ static void amdgpu_fence_release(struct dma_fence *f)
> >       call_rcu(&f->rcu, amdgpu_fence_free);
> >  }
> >
> > -/**
> > - * amdgpu_job_fence_release - callback that job embedded fence can be freed
> > - *
> > - * @f: fence
> > - *
> > - * This is the simliar function with amdgpu_fence_release above, it
> > - * only handles the job embedded fence.
> > - */
> > -static void amdgpu_job_fence_release(struct dma_fence *f)
> > -{
> > -     call_rcu(&f->rcu, amdgpu_job_fence_free);
> > -}
> > -
> >  static const struct dma_fence_ops amdgpu_fence_ops = {
> >       .get_driver_name = amdgpu_fence_get_driver_name,
> >       .get_timeline_name = amdgpu_fence_get_timeline_name,
> > @@ -933,13 +824,6 @@ static const struct dma_fence_ops amdgpu_fence_ops = {
> >       .release = amdgpu_fence_release,
> >  };
> >
> > -static const struct dma_fence_ops amdgpu_job_fence_ops = {
> > -     .get_driver_name = amdgpu_fence_get_driver_name,
> > -     .get_timeline_name = amdgpu_job_fence_get_timeline_name,
> > -     .enable_signaling = amdgpu_job_fence_enable_signaling,
> > -     .release = amdgpu_job_fence_release,
> > -};
> > -
> >  /*
> >   * Fence debugfs
> >   */
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
> > index 7d9bcb72e8dd3..71215aeb1b6f5 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
> > @@ -128,7 +128,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
> >       struct amdgpu_device *adev = ring->adev;
> >       struct amdgpu_ib *ib = &ibs[0];
> >       struct dma_fence *tmp = NULL;
> > -     struct amdgpu_fence *af;
> > +     struct amdgpu_fence *af, *vm_af;
> >       bool need_ctx_switch;
> >       struct amdgpu_vm *vm;
> >       uint64_t fence_ctx;
> > @@ -148,18 +148,20 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
> >       /* ring tests don't use a job */
> >       if (job) {
> >               vm = job->vm;
> > -             fence_ctx = job->base.s_fence ?
> > -                     job->base.s_fence->scheduled.context : 0;
> > +             fence_ctx = job->base.s_fence ? job->base.s_fence->finished.context : 0;
>
> Please keep the 80 chars length, otherwise my editor starts to show it in red.

Weird.  Mine usually does too, but for some reason this didn't.  Fixed.

>
> >               shadow_va = job->shadow_va;
> >               csa_va = job->csa_va;
> >               gds_va = job->gds_va;
> >               init_shadow = job->init_shadow;
> > -             af = &job->hw_fence;
> > +             af = job->hw_fence;
> >               /* Save the context of the job for reset handling.
> >                * The driver needs this so it can skip the ring
> >                * contents for guilty contexts.
> >                */
> > -             af->context = job->base.s_fence ? job->base.s_fence->finished.context : 0;
> > +             af->context = fence_ctx;
> > +             vm_af = job->hw_vm_fence;
> > +             /* the vm fence is also part of the job's context */
> > +             vm_af->context = fence_ctx;
> >       } else {
> >               vm = NULL;
> >               fence_ctx = 0;
> > @@ -167,7 +169,10 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
> >               csa_va = 0;
> >               gds_va = 0;
> >               init_shadow = false;
> > -             af = NULL;
> > +             af = kzalloc(sizeof(*af), GFP_NOWAIT);
>
> Thinking more about it GFP_NOWAIT can fail to easily. Since this is relevant only for the extreme case of an IB test under a device reset it's probably ok to use GFP_ATOMIC and dip into the extra reserve.
>

Sure.  fixed.

Alex

> Regards,
> Christian.
>
> > +             if (!af)
> > +                     return -ENOMEM;
> > +             vm_af = NULL;
> >       }
> >
> >       if (!ring->sched.ready) {
> > @@ -289,7 +294,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
> >               amdgpu_ring_init_cond_exec(ring, ring->cond_exe_gpu_addr);
> >       }
> >
> > -     r = amdgpu_fence_emit(ring, f, af, fence_flags);
> > +     r = amdgpu_fence_emit(ring, af, fence_flags);
> >       if (r) {
> >               dev_err(adev->dev, "failed to emit fence (%d)\n", r);
> >               if (job && job->vmid)
> > @@ -297,6 +302,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
> >               amdgpu_ring_undo(ring);
> >               return r;
> >       }
> > +     *f = &af->base;
> >
> >       if (ring->funcs->insert_end)
> >               ring->funcs->insert_end(ring);
> > @@ -317,7 +323,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
> >        * fence so we know what rings contents to backup
> >        * after we reset the queue.
> >        */
> > -     amdgpu_fence_save_wptr(*f);
> > +     amdgpu_fence_save_wptr(af);
> >
> >       amdgpu_ring_ib_end(ring);
> >       amdgpu_ring_commit(ring);
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> > index 311e97c96c4e0..9a78fe01efa3a 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> > @@ -138,7 +138,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
> >                  ring->funcs->reset) {
> >               dev_err(adev->dev, "Starting %s ring reset\n",
> >                       s_job->sched->name);
> > -             r = amdgpu_ring_reset(ring, job->vmid, &job->hw_fence);
> > +             r = amdgpu_ring_reset(ring, job->vmid, job->hw_fence);
> >               if (!r) {
> >                       atomic_inc(&ring->adev->gpu_reset_counter);
> >                       dev_err(adev->dev, "Ring %s reset succeeded\n",
> > @@ -185,6 +185,9 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,
> >                    struct drm_sched_entity *entity, void *owner,
> >                    unsigned int num_ibs, struct amdgpu_job **job)
> >  {
> > +     struct amdgpu_fence *af;
> > +     int r;
> > +
> >       if (num_ibs == 0)
> >               return -EINVAL;
> >
> > @@ -192,6 +195,20 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,
> >       if (!*job)
> >               return -ENOMEM;
> >
> > +     af = kzalloc(sizeof(struct amdgpu_fence), GFP_KERNEL);
> > +     if (!af) {
> > +             r = -ENOMEM;
> > +             goto err_job;
> > +     }
> > +     (*job)->hw_fence = af;
> > +
> > +     af = kzalloc(sizeof(struct amdgpu_fence), GFP_KERNEL);
> > +     if (!af) {
> > +             r = -ENOMEM;
> > +             goto err_fence;
> > +     }
> > +     (*job)->hw_vm_fence = af;
> > +
> >       (*job)->vm = vm;
> >
> >       amdgpu_sync_create(&(*job)->explicit_sync);
> > @@ -202,6 +219,13 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,
> >               return 0;
> >
> >       return drm_sched_job_init(&(*job)->base, entity, 1, owner);
> > +
> > +err_fence:
> > +     kfree((*job)->hw_fence);
> > +err_job:
> > +     kfree(*job);
> > +
> > +     return r;
> >  }
> >
> >  int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev,
> > @@ -251,8 +275,8 @@ void amdgpu_job_free_resources(struct amdgpu_job *job)
> >       /* Check if any fences where initialized */
> >       if (job->base.s_fence && job->base.s_fence->finished.ops)
> >               f = &job->base.s_fence->finished;
> > -     else if (job->hw_fence.base.ops)
> > -             f = &job->hw_fence.base;
> > +     else if (job->hw_fence)
> > +             f = &job->hw_fence->base;
> >       else
> >               f = NULL;
> >
> > @@ -268,11 +292,7 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
> >
> >       amdgpu_sync_free(&job->explicit_sync);
> >
> > -     /* only put the hw fence if has embedded fence */
> > -     if (!job->hw_fence.base.ops)
> > -             kfree(job);
> > -     else
> > -             dma_fence_put(&job->hw_fence.base);
> > +     kfree(job);
> >  }
> >
> >  void amdgpu_job_set_gang_leader(struct amdgpu_job *job,
> > @@ -301,10 +321,7 @@ void amdgpu_job_free(struct amdgpu_job *job)
> >       if (job->gang_submit != &job->base.s_fence->scheduled)
> >               dma_fence_put(job->gang_submit);
> >
> > -     if (!job->hw_fence.base.ops)
> > -             kfree(job);
> > -     else
> > -             dma_fence_put(&job->hw_fence.base);
> > +     kfree(job);
> >  }
> >
> >  struct dma_fence *amdgpu_job_submit(struct amdgpu_job *job)
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> > index 931fed8892cc1..077b2414a24b7 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> > @@ -48,7 +48,8 @@ struct amdgpu_job {
> >       struct drm_sched_job    base;
> >       struct amdgpu_vm        *vm;
> >       struct amdgpu_sync      explicit_sync;
> > -     struct amdgpu_fence     hw_fence;
> > +     struct amdgpu_fence     *hw_fence;
> > +     struct amdgpu_fence     *hw_vm_fence;
> >       struct dma_fence        *gang_submit;
> >       uint32_t                preamble_status;
> >       uint32_t                preemption_status;
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
> > index 7670f5d82b9e4..901f8bd375212 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
> > @@ -152,11 +152,10 @@ struct amdgpu_fence {
> >
> >  extern const struct drm_sched_backend_ops amdgpu_sched_ops;
> >
> > -void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring);
> >  void amdgpu_fence_driver_set_error(struct amdgpu_ring *ring, int error);
> >  void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);
> >  void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *fence);
> > -void amdgpu_fence_save_wptr(struct dma_fence *fence);
> > +void amdgpu_fence_save_wptr(struct amdgpu_fence *af);
> >
> >  int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
> >  int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
> > @@ -166,8 +165,8 @@ void amdgpu_fence_driver_hw_init(struct amdgpu_device *adev);
> >  void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev);
> >  int amdgpu_fence_driver_sw_init(struct amdgpu_device *adev);
> >  void amdgpu_fence_driver_sw_fini(struct amdgpu_device *adev);
> > -int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
> > -                   struct amdgpu_fence *af, unsigned int flags);
> > +int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af,
> > +                   unsigned int flags);
> >  int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s,
> >                             uint32_t timeout);
> >  bool amdgpu_fence_process(struct amdgpu_ring *ring);
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> > index bf42246a3db2f..7d1a363ad6878 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> > @@ -772,7 +772,6 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
> >       bool cleaner_shader_needed = false;
> >       bool pasid_mapping_needed = false;
> >       struct dma_fence *fence = NULL;
> > -     struct amdgpu_fence *af;
> >       unsigned int patch;
> >       int r;
> >
> > @@ -835,13 +834,11 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
> >       }
> >
> >       if (vm_flush_needed || pasid_mapping_needed || cleaner_shader_needed) {
> > -             r = amdgpu_fence_emit(ring, &fence, NULL, 0);
> > +             r = amdgpu_fence_emit(ring, job->hw_vm_fence, 0);
> >               if (r)
> >                       return r;
> > -             /* this is part of the job's context */
> > -             af = container_of(fence, struct amdgpu_fence, base);
> > -             af->context = job->base.s_fence ? job->base.s_fence->finished.context : 0;
> >       }
> > +     fence = &job->hw_vm_fence->base;
> >
> >       if (vm_flush_needed) {
> >               mutex_lock(&id_mgr->lock);
>


More information about the amd-gfx mailing list