DF-3862 / fix.diff
--- a/sys/dev/drm/amd/amdgpu/amdgpu_device.c +++ b/sys/dev/drm/amd/amdgpu/amdgpu_device.c @@ -3389,6 +3389,14 @@ struct amdgpu_job *job) { int i, r, resched; + /* DF-3862: the timed-out job carries no reference held by the TDR + * path (drm_sched_job_timedout drops job_list_lock before calling + * us). Fence completions during the reset can schedule + * drm_sched_job_finish -> amdgpu_job_free_cb and kfree(job). + * Snapshot the scheduler pointer once and stop dereferencing @job + * after hw_job_reset/force_completion. + */ + struct drm_gpu_scheduler *job_sched = job ? job->base.sched : NULL; dev_info(adev->dev, "GPU reset begin!\n"); @@ -3411,7 +3419,7 @@ kthread_park(ring->sched.thread); - if (job && job->base.sched != &ring->sched) + if (job_sched && job_sched != &ring->sched) continue; drm_sched_hw_job_reset(&ring->sched, job ? &job->base : NULL); @@ -3435,7 +3443,7 @@ * or all rings (in the case @job is NULL) * after above amdgpu_reset accomplished */ - if ((!job || job->base.sched == &ring->sched) && !r) + if ((!job_sched || job_sched == &ring->sched) && !r) drm_sched_job_recovery(&ring->sched); kthread_unpark(ring->sched.thread); |