On 04.09.25 21:41, David Wu wrote: > On 2025-09-04 13:46, Alex Deucher wrote: >> On Thu, Sep 4, 2025 at 1:34 PM David Wu <david...@amd.com> wrote: >>> On 2025-09-04 10:45, 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. >>>> >>>> v2: Additional cleanup suggested by Christian >>>> v3: Additional cleanups suggested by Christian >>>> v4: Additional cleanups suggested by David and >>>> vm fence fix >>>> >>>> Cc: david....@amd.com >>>> Cc: christian.koe...@amd.com >>>> Signed-off-by: Alex Deucher <alexander.deuc...@amd.com> >>>> --- >>>> 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 | 143 ++------------------ >>>> drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 17 ++- >>>> drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 43 ++++-- >>>> drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | 3 +- >>>> drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 8 +- >>>> drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 7 +- >>>> 8 files changed, 63 insertions(+), 167 deletions(-) >>>> >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c >>>> index 0e6e2e2acf5b5..7119cf658de8d 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 b9e2f0293d617..79af75032d0e6 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 1a2710f453551..85cefbe40aef8 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,32 @@ 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); >>>> - } >>>> + 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 +143,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 +643,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 >>>> @@ -755,7 +699,7 @@ void amdgpu_fence_driver_force_completion(struct >>>> amdgpu_ring *ring) >>>> /** >>>> * amdgpu_fence_driver_guilty_force_completion - force signal of >>>> specified sequence >>>> * >>>> - * @fence: fence of the ring to signal >>>> + * @af: fence of the ring to signal >>>> * >>>> */ >>>> void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence >>>> *af) >>>> @@ -781,15 +725,13 @@ void >>>> amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *af) >>>> } >>>> rcu_read_unlock(); >>>> } >>>> - amdgpu_fence_write(ring, af->seq); >>>> + amdgpu_fence_write(ring, af->base.seqno); >>> af->base.seqno is a type of u64 - but the amdgpu_fence_write takes a u32 >>> argument. Should we >>> cast it? (assume seqno never overflows a u32) >> The seq number will always be 32 bits. dma_fences have a 64 bit >> sequence number but we use a 32 bit one for the hw fences. See >> amdgpu_fence_emit(). We pass the hw sequence number to >> dma_fence_init(). No need to cast it. > hmm.. understood the situation - my concern is a u64 passed to u32 without a > cast is > more like a coding error even though in fact it works in our case - by > casting we > know and accept 32bit from 64bit value. Or add a comment so anyone not > familiar with that implication knows why we can do it. Not sure if all > compilers > allow it without complains.
Giving a 64bit value as parameter for a function taking only 32bits is usually harmless. What we could do is to explicitely use the lower_32bits() macro, but I think that would probably be overkill. Christian. > David >> >> Alex >> >>> David >>> amdgpu_fence_process(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, >>> @@ -850,13 +792,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 >>> @@ -873,23 +808,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 >>> * >>> @@ -905,21 +823,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 >>> * >>> @@ -933,19 +836,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, >>> @@ -953,13 +843,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..39229ece83f83 100644 >>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c >>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c >>> @@ -149,17 +149,19 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, >>> unsigned int num_ibs, >>> if (job) { >>> vm = job->vm; >>> fence_ctx = job->base.s_fence ? >>> - job->base.s_fence->scheduled.context : 0; >>> + job->base.s_fence->finished.context : 0; >>> 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; >>> + /* the vm fence is also part of the job's context */ >>> + job->hw_vm_fence->context = fence_ctx; >>> } else { >>> vm = NULL; >>> fence_ctx = 0; >>> @@ -167,7 +169,9 @@ 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_ATOMIC); >>> + if (!af) >>> + return -ENOMEM; >>> } >>> >>> if (!ring->sched.ready) { >>> @@ -289,7 +293,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 +301,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 +322,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 172620880cada..55c7e104d5ca0 100644 >>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c >>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c >>> @@ -137,7 +137,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", >>> @@ -187,6 +187,9 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, struct >>> amdgpu_vm *vm, >>> unsigned int num_ibs, struct amdgpu_job **job, >>> u64 drm_client_id) >>> { >>> + struct amdgpu_fence *af; >>> + int r; >>> + >>> if (num_ibs == 0) >>> return -EINVAL; >>> >>> @@ -194,6 +197,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); >>> @@ -205,6 +222,13 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, >>> struct amdgpu_vm *vm, >>> >>> return drm_sched_job_init(&(*job)->base, entity, 1, owner, >>> drm_client_id); >>> + >>> +err_fence: >>> + kfree((*job)->hw_fence); >>> +err_job: >>> + kfree(*job); >>> + >>> + return r; >>> } >>> >>> int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, >>> @@ -251,11 +275,11 @@ void amdgpu_job_free_resources(struct amdgpu_job *job) >>> struct dma_fence *f; >>> unsigned i; >>> >>> - /* Check if any fences where initialized */ >>> + /* Check if any fences were 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 && job->hw_fence->base.ops) >>> + f = &job->hw_fence->base; >>> else >>> f = NULL; >>> >>> @@ -271,11 +295,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, >>> @@ -304,10 +324,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 2f302266662bc..d25f1fcf0242e 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 0704fd9b85fdb..5d44f1354c8d8 100644 >>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h >>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h >>> @@ -147,16 +147,14 @@ struct amdgpu_fence { >>> u64 wptr; >>> /* fence context for resets */ >>> u64 context; >>> - uint32_t seq; >>> }; >>> >>> 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 >>> *af); >>> -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 +164,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 bd12d8ff15a42..76bae546df11c 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,12 +834,10 @@ 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) { >>>