162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright 2015 Advanced Micro Devices, Inc. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 562306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 662306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation 762306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 862306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 962306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 1262306a36Sopenharmony_ci * all copies or substantial portions of the Software. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1562306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1662306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1762306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1862306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1962306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2062306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci */ 2462306a36Sopenharmony_ci#include <linux/kthread.h> 2562306a36Sopenharmony_ci#include <linux/wait.h> 2662306a36Sopenharmony_ci#include <linux/sched.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#include <drm/drm_drv.h> 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#include "amdgpu.h" 3162306a36Sopenharmony_ci#include "amdgpu_trace.h" 3262306a36Sopenharmony_ci#include "amdgpu_reset.h" 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cistatic enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) 3562306a36Sopenharmony_ci{ 3662306a36Sopenharmony_ci struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched); 3762306a36Sopenharmony_ci struct amdgpu_job *job = to_amdgpu_job(s_job); 3862306a36Sopenharmony_ci struct amdgpu_task_info ti; 3962306a36Sopenharmony_ci struct amdgpu_device *adev = ring->adev; 4062306a36Sopenharmony_ci int idx; 4162306a36Sopenharmony_ci int r; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci if (!drm_dev_enter(adev_to_drm(adev), &idx)) { 4462306a36Sopenharmony_ci DRM_INFO("%s - device unplugged skipping recovery on scheduler:%s", 4562306a36Sopenharmony_ci __func__, s_job->sched->name); 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci /* Effectively the job is aborted as the device is gone */ 4862306a36Sopenharmony_ci return DRM_GPU_SCHED_STAT_ENODEV; 4962306a36Sopenharmony_ci } 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci memset(&ti, 0, sizeof(struct amdgpu_task_info)); 5262306a36Sopenharmony_ci adev->job_hang = true; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci if (amdgpu_gpu_recovery && 5562306a36Sopenharmony_ci amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) { 5662306a36Sopenharmony_ci DRM_ERROR("ring %s timeout, but soft recovered\n", 5762306a36Sopenharmony_ci s_job->sched->name); 5862306a36Sopenharmony_ci goto exit; 5962306a36Sopenharmony_ci } 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci amdgpu_vm_get_task_info(ring->adev, job->pasid, &ti); 6262306a36Sopenharmony_ci DRM_ERROR("ring %s timeout, signaled seq=%u, emitted seq=%u\n", 6362306a36Sopenharmony_ci job->base.sched->name, atomic_read(&ring->fence_drv.last_seq), 6462306a36Sopenharmony_ci ring->fence_drv.sync_seq); 6562306a36Sopenharmony_ci DRM_ERROR("Process information: process %s pid %d thread %s pid %d\n", 6662306a36Sopenharmony_ci ti.process_name, ti.tgid, ti.task_name, ti.pid); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci dma_fence_set_error(&s_job->s_fence->finished, -ETIME); 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci if (amdgpu_device_should_recover_gpu(ring->adev)) { 7162306a36Sopenharmony_ci struct amdgpu_reset_context reset_context; 7262306a36Sopenharmony_ci memset(&reset_context, 0, sizeof(reset_context)); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci reset_context.method = AMD_RESET_METHOD_NONE; 7562306a36Sopenharmony_ci reset_context.reset_req_dev = adev; 7662306a36Sopenharmony_ci clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci r = amdgpu_device_gpu_recover(ring->adev, job, &reset_context); 7962306a36Sopenharmony_ci if (r) 8062306a36Sopenharmony_ci DRM_ERROR("GPU Recovery Failed: %d\n", r); 8162306a36Sopenharmony_ci } else { 8262306a36Sopenharmony_ci drm_sched_suspend_timeout(&ring->sched); 8362306a36Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 8462306a36Sopenharmony_ci adev->virt.tdr_debug = true; 8562306a36Sopenharmony_ci } 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ciexit: 8862306a36Sopenharmony_ci adev->job_hang = false; 8962306a36Sopenharmony_ci drm_dev_exit(idx); 9062306a36Sopenharmony_ci return DRM_GPU_SCHED_STAT_NOMINAL; 9162306a36Sopenharmony_ci} 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ciint amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm, 9462306a36Sopenharmony_ci struct drm_sched_entity *entity, void *owner, 9562306a36Sopenharmony_ci unsigned int num_ibs, struct amdgpu_job **job) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci if (num_ibs == 0) 9862306a36Sopenharmony_ci return -EINVAL; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci *job = kzalloc(struct_size(*job, ibs, num_ibs), GFP_KERNEL); 10162306a36Sopenharmony_ci if (!*job) 10262306a36Sopenharmony_ci return -ENOMEM; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci /* 10562306a36Sopenharmony_ci * Initialize the scheduler to at least some ring so that we always 10662306a36Sopenharmony_ci * have a pointer to adev. 10762306a36Sopenharmony_ci */ 10862306a36Sopenharmony_ci (*job)->base.sched = &adev->rings[0]->sched; 10962306a36Sopenharmony_ci (*job)->vm = vm; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci amdgpu_sync_create(&(*job)->explicit_sync); 11262306a36Sopenharmony_ci (*job)->generation = amdgpu_vm_generation(adev, vm); 11362306a36Sopenharmony_ci (*job)->vm_pd_addr = AMDGPU_BO_INVALID_OFFSET; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci if (!entity) 11662306a36Sopenharmony_ci return 0; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci return drm_sched_job_init(&(*job)->base, entity, owner); 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ciint amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, 12262306a36Sopenharmony_ci struct drm_sched_entity *entity, void *owner, 12362306a36Sopenharmony_ci size_t size, enum amdgpu_ib_pool_type pool_type, 12462306a36Sopenharmony_ci struct amdgpu_job **job) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci int r; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci r = amdgpu_job_alloc(adev, NULL, entity, owner, 1, job); 12962306a36Sopenharmony_ci if (r) 13062306a36Sopenharmony_ci return r; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci (*job)->num_ibs = 1; 13362306a36Sopenharmony_ci r = amdgpu_ib_get(adev, NULL, size, pool_type, &(*job)->ibs[0]); 13462306a36Sopenharmony_ci if (r) { 13562306a36Sopenharmony_ci if (entity) 13662306a36Sopenharmony_ci drm_sched_job_cleanup(&(*job)->base); 13762306a36Sopenharmony_ci kfree(*job); 13862306a36Sopenharmony_ci } 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci return r; 14162306a36Sopenharmony_ci} 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_civoid amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds, 14462306a36Sopenharmony_ci struct amdgpu_bo *gws, struct amdgpu_bo *oa) 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci if (gds) { 14762306a36Sopenharmony_ci job->gds_base = amdgpu_bo_gpu_offset(gds) >> PAGE_SHIFT; 14862306a36Sopenharmony_ci job->gds_size = amdgpu_bo_size(gds) >> PAGE_SHIFT; 14962306a36Sopenharmony_ci } 15062306a36Sopenharmony_ci if (gws) { 15162306a36Sopenharmony_ci job->gws_base = amdgpu_bo_gpu_offset(gws) >> PAGE_SHIFT; 15262306a36Sopenharmony_ci job->gws_size = amdgpu_bo_size(gws) >> PAGE_SHIFT; 15362306a36Sopenharmony_ci } 15462306a36Sopenharmony_ci if (oa) { 15562306a36Sopenharmony_ci job->oa_base = amdgpu_bo_gpu_offset(oa) >> PAGE_SHIFT; 15662306a36Sopenharmony_ci job->oa_size = amdgpu_bo_size(oa) >> PAGE_SHIFT; 15762306a36Sopenharmony_ci } 15862306a36Sopenharmony_ci} 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_civoid amdgpu_job_free_resources(struct amdgpu_job *job) 16162306a36Sopenharmony_ci{ 16262306a36Sopenharmony_ci struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched); 16362306a36Sopenharmony_ci struct dma_fence *f; 16462306a36Sopenharmony_ci unsigned i; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci /* Check if any fences where initialized */ 16762306a36Sopenharmony_ci if (job->base.s_fence && job->base.s_fence->finished.ops) 16862306a36Sopenharmony_ci f = &job->base.s_fence->finished; 16962306a36Sopenharmony_ci else if (job->hw_fence.ops) 17062306a36Sopenharmony_ci f = &job->hw_fence; 17162306a36Sopenharmony_ci else 17262306a36Sopenharmony_ci f = NULL; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci for (i = 0; i < job->num_ibs; ++i) 17562306a36Sopenharmony_ci amdgpu_ib_free(ring->adev, &job->ibs[i], f); 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistatic void amdgpu_job_free_cb(struct drm_sched_job *s_job) 17962306a36Sopenharmony_ci{ 18062306a36Sopenharmony_ci struct amdgpu_job *job = to_amdgpu_job(s_job); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci drm_sched_job_cleanup(s_job); 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci amdgpu_sync_free(&job->explicit_sync); 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci /* only put the hw fence if has embedded fence */ 18762306a36Sopenharmony_ci if (!job->hw_fence.ops) 18862306a36Sopenharmony_ci kfree(job); 18962306a36Sopenharmony_ci else 19062306a36Sopenharmony_ci dma_fence_put(&job->hw_fence); 19162306a36Sopenharmony_ci} 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_civoid amdgpu_job_set_gang_leader(struct amdgpu_job *job, 19462306a36Sopenharmony_ci struct amdgpu_job *leader) 19562306a36Sopenharmony_ci{ 19662306a36Sopenharmony_ci struct dma_fence *fence = &leader->base.s_fence->scheduled; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci WARN_ON(job->gang_submit); 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci /* 20162306a36Sopenharmony_ci * Don't add a reference when we are the gang leader to avoid circle 20262306a36Sopenharmony_ci * dependency. 20362306a36Sopenharmony_ci */ 20462306a36Sopenharmony_ci if (job != leader) 20562306a36Sopenharmony_ci dma_fence_get(fence); 20662306a36Sopenharmony_ci job->gang_submit = fence; 20762306a36Sopenharmony_ci} 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_civoid amdgpu_job_free(struct amdgpu_job *job) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci if (job->base.entity) 21262306a36Sopenharmony_ci drm_sched_job_cleanup(&job->base); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci amdgpu_job_free_resources(job); 21562306a36Sopenharmony_ci amdgpu_sync_free(&job->explicit_sync); 21662306a36Sopenharmony_ci if (job->gang_submit != &job->base.s_fence->scheduled) 21762306a36Sopenharmony_ci dma_fence_put(job->gang_submit); 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci if (!job->hw_fence.ops) 22062306a36Sopenharmony_ci kfree(job); 22162306a36Sopenharmony_ci else 22262306a36Sopenharmony_ci dma_fence_put(&job->hw_fence); 22362306a36Sopenharmony_ci} 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_cistruct dma_fence *amdgpu_job_submit(struct amdgpu_job *job) 22662306a36Sopenharmony_ci{ 22762306a36Sopenharmony_ci struct dma_fence *f; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci drm_sched_job_arm(&job->base); 23062306a36Sopenharmony_ci f = dma_fence_get(&job->base.s_fence->finished); 23162306a36Sopenharmony_ci amdgpu_job_free_resources(job); 23262306a36Sopenharmony_ci drm_sched_entity_push_job(&job->base); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci return f; 23562306a36Sopenharmony_ci} 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ciint amdgpu_job_submit_direct(struct amdgpu_job *job, struct amdgpu_ring *ring, 23862306a36Sopenharmony_ci struct dma_fence **fence) 23962306a36Sopenharmony_ci{ 24062306a36Sopenharmony_ci int r; 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci job->base.sched = &ring->sched; 24362306a36Sopenharmony_ci r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs, job, fence); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci if (r) 24662306a36Sopenharmony_ci return r; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci amdgpu_job_free(job); 24962306a36Sopenharmony_ci return 0; 25062306a36Sopenharmony_ci} 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_cistatic struct dma_fence * 25362306a36Sopenharmony_ciamdgpu_job_prepare_job(struct drm_sched_job *sched_job, 25462306a36Sopenharmony_ci struct drm_sched_entity *s_entity) 25562306a36Sopenharmony_ci{ 25662306a36Sopenharmony_ci struct amdgpu_ring *ring = to_amdgpu_ring(s_entity->rq->sched); 25762306a36Sopenharmony_ci struct amdgpu_job *job = to_amdgpu_job(sched_job); 25862306a36Sopenharmony_ci struct dma_fence *fence = NULL; 25962306a36Sopenharmony_ci int r; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci /* Ignore soft recovered fences here */ 26262306a36Sopenharmony_ci r = drm_sched_entity_error(s_entity); 26362306a36Sopenharmony_ci if (r && r != -ENODATA) 26462306a36Sopenharmony_ci goto error; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci if (!fence && job->gang_submit) 26762306a36Sopenharmony_ci fence = amdgpu_device_switch_gang(ring->adev, job->gang_submit); 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci while (!fence && job->vm && !job->vmid) { 27062306a36Sopenharmony_ci r = amdgpu_vmid_grab(job->vm, ring, job, &fence); 27162306a36Sopenharmony_ci if (r) { 27262306a36Sopenharmony_ci DRM_ERROR("Error getting VM ID (%d)\n", r); 27362306a36Sopenharmony_ci goto error; 27462306a36Sopenharmony_ci } 27562306a36Sopenharmony_ci } 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci return fence; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_cierror: 28062306a36Sopenharmony_ci dma_fence_set_error(&job->base.s_fence->finished, r); 28162306a36Sopenharmony_ci return NULL; 28262306a36Sopenharmony_ci} 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_cistatic struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job) 28562306a36Sopenharmony_ci{ 28662306a36Sopenharmony_ci struct amdgpu_ring *ring = to_amdgpu_ring(sched_job->sched); 28762306a36Sopenharmony_ci struct amdgpu_device *adev = ring->adev; 28862306a36Sopenharmony_ci struct dma_fence *fence = NULL, *finished; 28962306a36Sopenharmony_ci struct amdgpu_job *job; 29062306a36Sopenharmony_ci int r = 0; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci job = to_amdgpu_job(sched_job); 29362306a36Sopenharmony_ci finished = &job->base.s_fence->finished; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci trace_amdgpu_sched_run_job(job); 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci /* Skip job if VRAM is lost and never resubmit gangs */ 29862306a36Sopenharmony_ci if (job->generation != amdgpu_vm_generation(adev, job->vm) || 29962306a36Sopenharmony_ci (job->job_run_counter && job->gang_submit)) 30062306a36Sopenharmony_ci dma_fence_set_error(finished, -ECANCELED); 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci if (finished->error < 0) { 30362306a36Sopenharmony_ci DRM_INFO("Skip scheduling IBs!\n"); 30462306a36Sopenharmony_ci } else { 30562306a36Sopenharmony_ci r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs, job, 30662306a36Sopenharmony_ci &fence); 30762306a36Sopenharmony_ci if (r) 30862306a36Sopenharmony_ci DRM_ERROR("Error scheduling IBs (%d)\n", r); 30962306a36Sopenharmony_ci } 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci job->job_run_counter++; 31262306a36Sopenharmony_ci amdgpu_job_free_resources(job); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci fence = r ? ERR_PTR(r) : fence; 31562306a36Sopenharmony_ci return fence; 31662306a36Sopenharmony_ci} 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci#define to_drm_sched_job(sched_job) \ 31962306a36Sopenharmony_ci container_of((sched_job), struct drm_sched_job, queue_node) 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_civoid amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched) 32262306a36Sopenharmony_ci{ 32362306a36Sopenharmony_ci struct drm_sched_job *s_job; 32462306a36Sopenharmony_ci struct drm_sched_entity *s_entity = NULL; 32562306a36Sopenharmony_ci int i; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci /* Signal all jobs not yet scheduled */ 32862306a36Sopenharmony_ci for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) { 32962306a36Sopenharmony_ci struct drm_sched_rq *rq = &sched->sched_rq[i]; 33062306a36Sopenharmony_ci spin_lock(&rq->lock); 33162306a36Sopenharmony_ci list_for_each_entry(s_entity, &rq->entities, list) { 33262306a36Sopenharmony_ci while ((s_job = to_drm_sched_job(spsc_queue_pop(&s_entity->job_queue)))) { 33362306a36Sopenharmony_ci struct drm_sched_fence *s_fence = s_job->s_fence; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci dma_fence_signal(&s_fence->scheduled); 33662306a36Sopenharmony_ci dma_fence_set_error(&s_fence->finished, -EHWPOISON); 33762306a36Sopenharmony_ci dma_fence_signal(&s_fence->finished); 33862306a36Sopenharmony_ci } 33962306a36Sopenharmony_ci } 34062306a36Sopenharmony_ci spin_unlock(&rq->lock); 34162306a36Sopenharmony_ci } 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci /* Signal all jobs already scheduled to HW */ 34462306a36Sopenharmony_ci list_for_each_entry(s_job, &sched->pending_list, list) { 34562306a36Sopenharmony_ci struct drm_sched_fence *s_fence = s_job->s_fence; 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci dma_fence_set_error(&s_fence->finished, -EHWPOISON); 34862306a36Sopenharmony_ci dma_fence_signal(&s_fence->finished); 34962306a36Sopenharmony_ci } 35062306a36Sopenharmony_ci} 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ciconst struct drm_sched_backend_ops amdgpu_sched_ops = { 35362306a36Sopenharmony_ci .prepare_job = amdgpu_job_prepare_job, 35462306a36Sopenharmony_ci .run_job = amdgpu_job_run, 35562306a36Sopenharmony_ci .timedout_job = amdgpu_job_timedout, 35662306a36Sopenharmony_ci .free_job = amdgpu_job_free_cb 35762306a36Sopenharmony_ci}; 358