Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync drm/panthor and drm/sched with 6.12-rc2 #264

Merged
merged 14 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -5399,7 +5399,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
if (!tmp_adev->asic_reset_res && !job_signaled)
drm_sched_resubmit_jobs(&ring->sched);

drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res);
drm_sched_start(&ring->sched);
}

if (adev->enable_mes && adev->ip_versions[GC_HWIP][0] != IP_VERSION(11, 0, 3))
Expand Down Expand Up @@ -5854,7 +5854,7 @@ void amdgpu_pci_resume(struct pci_dev *pdev)


drm_sched_resubmit_jobs(&ring->sched);
drm_sched_start(&ring->sched, true);
drm_sched_start(&ring->sched);
}

amdgpu_device_unset_mp1_state(adev);
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/etnaviv/etnaviv_sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job

drm_sched_resubmit_jobs(&gpu->sched);

drm_sched_start(&gpu->sched, true);
drm_sched_start(&gpu->sched);
return DRM_GPU_SCHED_STAT_NOMINAL;

out_no_timeout:
/* restart scheduler after GPU is usable again */
drm_sched_start(&gpu->sched, true);
drm_sched_start(&gpu->sched);
return DRM_GPU_SCHED_STAT_NOMINAL;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/lima/lima_sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ static enum drm_gpu_sched_stat lima_sched_timedout_job(struct drm_sched_job *job
lima_pm_idle(ldev);

drm_sched_resubmit_jobs(&pipe->base);
drm_sched_start(&pipe->base, true);
drm_sched_start(&pipe->base);

return DRM_GPU_SCHED_STAT_NOMINAL;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/panfrost/panfrost_job.c
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ panfrost_reset(struct panfrost_device *pfdev,

/* Restart the schedulers */
for (i = 0; i < NUM_JOB_SLOTS; i++)
drm_sched_start(&pfdev->js->queue[i].sched, true);
drm_sched_start(&pfdev->js->queue[i].sched);

/* Re-enable job interrupts now that everything has been restarted. */
job_write(pfdev, JOB_INT_MASK,
Expand Down
20 changes: 15 additions & 5 deletions drivers/gpu/drm/panthor/panthor_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,12 @@ static int mmu_hw_do_operation_locked(struct panthor_device *ptdev, int as_nr,
if (as_nr < 0)
return 0;

/*
* If the AS number is greater than zero, then we can be sure
* the device is up and running, so we don't need to explicitly
* power it up
*/

if (op != AS_COMMAND_UNLOCK)
lock_region(ptdev, as_nr, iova, size);

Expand Down Expand Up @@ -826,7 +832,7 @@ static void panthor_vm_stop(struct panthor_vm *vm)

static void panthor_vm_start(struct panthor_vm *vm)
{
drm_sched_start(&vm->sched, true);
drm_sched_start(&vm->sched);
}

/**
Expand Down Expand Up @@ -873,10 +879,6 @@ static int panthor_vm_flush_range(struct panthor_vm *vm, u64 iova, u64 size)
if (!drm_dev_enter(&ptdev->base, &cookie))
return 0;

/*
* If we made it this far, that means the device is awake, because
* upon device suspension, all active VMs are given an AS id of -1
*/
ret = mmu_hw_do_operation(vm, iova, size, AS_COMMAND_FLUSH_PT);

drm_dev_exit(cookie);
Expand Down Expand Up @@ -1248,9 +1250,17 @@ static int panthor_vm_prepare_map_op_ctx(struct panthor_vm_op_ctx *op_ctx,
goto err_cleanup;
}

/* drm_gpuvm_bo_obtain_prealloc() will call drm_gpuvm_bo_put() on our
* pre-allocated BO if the <BO,VM> association exists. Given we
* only have one ref on preallocated_vm_bo, drm_gpuvm_bo_destroy() will
* be called immediately, and we have to hold the VM resv lock when
* calling this function.
*/
dma_resv_lock(panthor_vm_resv(vm), NULL);
mutex_lock(&bo->gpuva_list_lock);
op_ctx->map.vm_bo = drm_gpuvm_bo_obtain_prealloc(preallocated_vm_bo);
mutex_unlock(&bo->gpuva_list_lock);
dma_resv_unlock(panthor_vm_resv(vm));

/* If the a vm_bo for this <VM,BO> combination exists, it already
* retains a pin ref, and we can release the one we took earlier.
Expand Down
38 changes: 26 additions & 12 deletions drivers/gpu/drm/panthor/panthor_sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,13 @@ cs_slot_sync_queue_state_locked(struct panthor_device *ptdev, u32 csg_id, u32 cs
list_move_tail(&group->wait_node,
&group->ptdev->scheduler->groups.waiting);
}
group->blocked_queues |= BIT(cs_id);

/* The queue is only blocked if there's no deferred operation
* pending, which can be checked through the scoreboard status.
*/
if (!cs_iface->output->status_scoreboards)
group->blocked_queues |= BIT(cs_id);

queue->syncwait.gpu_va = cs_iface->output->status_wait_sync_ptr;
queue->syncwait.ref = cs_iface->output->status_wait_sync_value;
status_wait_cond = cs_iface->output->status_wait & CS_STATUS_WAIT_SYNC_COND_MASK;
Expand Down Expand Up @@ -2046,6 +2052,7 @@ static void
tick_ctx_cleanup(struct panthor_scheduler *sched,
struct panthor_sched_tick_ctx *ctx)
{
struct panthor_device *ptdev = sched->ptdev;
struct panthor_group *group, *tmp;
u32 i;

Expand All @@ -2054,7 +2061,7 @@ tick_ctx_cleanup(struct panthor_scheduler *sched,
/* If everything went fine, we should only have groups
* to be terminated in the old_groups lists.
*/
drm_WARN_ON(&group->ptdev->base, !ctx->csg_upd_failed_mask &&
drm_WARN_ON(&ptdev->base, !ctx->csg_upd_failed_mask &&
group_can_run(group));

if (!group_can_run(group)) {
Expand All @@ -2077,7 +2084,7 @@ tick_ctx_cleanup(struct panthor_scheduler *sched,
/* If everything went fine, the groups to schedule lists should
* be empty.
*/
drm_WARN_ON(&group->ptdev->base,
drm_WARN_ON(&ptdev->base,
!ctx->csg_upd_failed_mask && !list_empty(&ctx->groups[i]));

list_for_each_entry_safe(group, tmp, &ctx->groups[i], run_node) {
Expand Down Expand Up @@ -2538,7 +2545,7 @@ static void queue_start(struct panthor_queue *queue)
list_for_each_entry(job, &queue->scheduler.pending_list, base.list)
job->base.s_fence->parent = dma_fence_get(job->done_fence);

drm_sched_start(&queue->scheduler, true);
drm_sched_start(&queue->scheduler);
}

static void panthor_group_stop(struct panthor_group *group)
Expand Down Expand Up @@ -3242,6 +3249,18 @@ int panthor_group_destroy(struct panthor_file *pfile, u32 group_handle)
return 0;
}

static struct panthor_group *group_from_handle(struct panthor_group_pool *pool,
u32 group_handle)
{
struct panthor_group *group;

xa_lock(&pool->xa);
group = group_get(xa_load(&pool->xa, group_handle));
xa_unlock(&pool->xa);

return group;
}

int panthor_group_get_state(struct panthor_file *pfile,
struct drm_panthor_group_get_state *get_state)
{
Expand All @@ -3253,7 +3272,7 @@ int panthor_group_get_state(struct panthor_file *pfile,
if (get_state->pad)
return -EINVAL;

group = group_get(xa_load(&gpool->xa, get_state->group_handle));
group = group_from_handle(gpool, get_state->group_handle);
if (!group)
return -EINVAL;

Expand Down Expand Up @@ -3384,7 +3403,7 @@ panthor_job_create(struct panthor_file *pfile,
job->call_info.latest_flush = qsubmit->latest_flush;
INIT_LIST_HEAD(&job->node);

job->group = group_get(xa_load(&gpool->xa, group_handle));
job->group = group_from_handle(gpool, group_handle);
if (!job->group) {
ret = -EINVAL;
goto err_put_job;
Expand Down Expand Up @@ -3424,13 +3443,8 @@ void panthor_job_update_resvs(struct drm_exec *exec, struct drm_sched_job *sched
{
struct panthor_job *job = container_of(sched_job, struct panthor_job, base);

/* Still not sure why we want USAGE_WRITE for external objects, since I
* was assuming this would be handled through explicit syncs being imported
* to external BOs with DMA_BUF_IOCTL_IMPORT_SYNC_FILE, but other drivers
* seem to pass DMA_RESV_USAGE_WRITE, so there must be a good reason.
*/
panthor_vm_update_resvs(job->group->vm, exec, &sched_job->s_fence->finished,
DMA_RESV_USAGE_BOOKKEEP, DMA_RESV_USAGE_WRITE);
DMA_RESV_USAGE_BOOKKEEP, DMA_RESV_USAGE_BOOKKEEP);
}

void panthor_sched_unplug(struct panthor_device *ptdev)
Expand Down
26 changes: 20 additions & 6 deletions drivers/gpu/drm/scheduler/sched_entity.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,19 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
entity->guilty = guilty;
entity->num_sched_list = num_sched_list;
entity->priority = priority;
/*
* It's perfectly valid to initialize an entity without having a valid
* scheduler attached. It's just not valid to use the scheduler before it
* is initialized itself.
*/
entity->sched_list = num_sched_list > 1 ? sched_list : NULL;
RCU_INIT_POINTER(entity->last_scheduled, NULL);
RB_CLEAR_NODE(&entity->rb_tree_node);

if (!sched_list[0]->sched_rq) {
/* Warn drivers not to do this and to fix their DRM
* calling order.
if (num_sched_list && !sched_list[0]->sched_rq) {
/* Since every entry covered by num_sched_list
* should be non-NULL and therefore we warn drivers
* not to do this and to fix their DRM calling order.
*/
pr_warn("%s: called with uninitialized scheduler\n", __func__);
} else if (num_sched_list) {
Expand Down Expand Up @@ -127,8 +133,10 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity,
{
WARN_ON(!num_sched_list || !sched_list);

spin_lock(&entity->rq_lock);
entity->sched_list = sched_list;
entity->num_sched_list = num_sched_list;
spin_unlock(&entity->rq_lock);
}
EXPORT_SYMBOL(drm_sched_entity_modify_sched);

Expand Down Expand Up @@ -374,7 +382,7 @@ static void drm_sched_entity_wakeup(struct dma_fence *f,
container_of(cb, struct drm_sched_entity, cb);

drm_sched_entity_clear_dep(f, cb);
drm_sched_wakeup(entity->rq->sched, entity);
drm_sched_wakeup(entity->rq->sched);
}

/**
Expand Down Expand Up @@ -591,6 +599,9 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)

/* first job wakes up scheduler */
if (first) {
struct drm_gpu_scheduler *sched;
struct drm_sched_rq *rq;

/* Add the entity to the run queue */
spin_lock(&entity->rq_lock);
if (entity->stopped) {
Expand All @@ -600,13 +611,16 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
return;
}

drm_sched_rq_add_entity(entity->rq, entity);
rq = entity->rq;
sched = rq->sched;

drm_sched_rq_add_entity(rq, entity);
spin_unlock(&entity->rq_lock);

if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
drm_sched_rq_update_fifo(entity, submit_ts);

drm_sched_wakeup(entity->rq->sched, entity);
drm_sched_wakeup(sched);
}
}
EXPORT_SYMBOL(drm_sched_entity_push_job);
4 changes: 1 addition & 3 deletions drivers/gpu/drm/scheduler/sched_fence.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ static struct kmem_cache *sched_fence_slab;

static int __init drm_sched_fence_slab_init(void)
{
sched_fence_slab = kmem_cache_create(
"drm_sched_fence", sizeof(struct drm_sched_fence), 0,
SLAB_HWCACHE_ALIGN, NULL);
sched_fence_slab = KMEM_CACHE(drm_sched_fence, SLAB_HWCACHE_ALIGN);
if (!sched_fence_slab)
return -ENOMEM;

Expand Down
Loading