Skip to content

Commit 1decbf6

Browse files
BNieuwenhuizenalexdeucher
authored andcommitted
drm/sched: Fix entities with 0 rqs.
Some blocks in amdgpu can have 0 rqs. Job creation already fails with -ENOENT when entity->rq is NULL, so jobs cannot be pushed. Without a rq there is no scheduler to pop jobs, and rq selection already does the right thing with a list of length 0. So the operations we need to fix are: - Creation, do not set rq to rq_list[0] if the list can have length 0. - Do not flush any jobs when there is no rq. - On entity destruction handle the rq = NULL case. - on set_priority, do not try to change the rq if it is NULL. Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent 7a5e0d9 commit 1decbf6

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

drivers/gpu/drm/scheduler/sched_entity.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
5252
{
5353
int i;
5454

55-
if (!(entity && rq_list && num_rq_list > 0 && rq_list[0]))
55+
if (!(entity && rq_list && (num_rq_list == 0 || rq_list[0])))
5656
return -EINVAL;
5757

5858
memset(entity, 0, sizeof(struct drm_sched_entity));
5959
INIT_LIST_HEAD(&entity->list);
60-
entity->rq = rq_list[0];
60+
entity->rq = NULL;
6161
entity->guilty = guilty;
6262
entity->num_rq_list = num_rq_list;
6363
entity->rq_list = kcalloc(num_rq_list, sizeof(struct drm_sched_rq *),
@@ -67,6 +67,10 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
6767

6868
for (i = 0; i < num_rq_list; ++i)
6969
entity->rq_list[i] = rq_list[i];
70+
71+
if (num_rq_list)
72+
entity->rq = rq_list[0];
73+
7074
entity->last_scheduled = NULL;
7175

7276
spin_lock_init(&entity->rq_lock);
@@ -165,6 +169,9 @@ long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout)
165169
struct task_struct *last_user;
166170
long ret = timeout;
167171

172+
if (!entity->rq)
173+
return 0;
174+
168175
sched = entity->rq->sched;
169176
/**
170177
* The client will not queue more IBs during this fini, consume existing
@@ -264,20 +271,24 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity)
264271
*/
265272
void drm_sched_entity_fini(struct drm_sched_entity *entity)
266273
{
267-
struct drm_gpu_scheduler *sched;
274+
struct drm_gpu_scheduler *sched = NULL;
268275

269-
sched = entity->rq->sched;
270-
drm_sched_rq_remove_entity(entity->rq, entity);
276+
if (entity->rq) {
277+
sched = entity->rq->sched;
278+
drm_sched_rq_remove_entity(entity->rq, entity);
279+
}
271280

272281
/* Consumption of existing IBs wasn't completed. Forcefully
273282
* remove them here.
274283
*/
275284
if (spsc_queue_peek(&entity->job_queue)) {
276-
/* Park the kernel for a moment to make sure it isn't processing
277-
* our enity.
278-
*/
279-
kthread_park(sched->thread);
280-
kthread_unpark(sched->thread);
285+
if (sched) {
286+
/* Park the kernel for a moment to make sure it isn't processing
287+
* our enity.
288+
*/
289+
kthread_park(sched->thread);
290+
kthread_unpark(sched->thread);
291+
}
281292
if (entity->dependency) {
282293
dma_fence_remove_callback(entity->dependency,
283294
&entity->cb);
@@ -362,9 +373,11 @@ void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
362373
for (i = 0; i < entity->num_rq_list; ++i)
363374
drm_sched_entity_set_rq_priority(&entity->rq_list[i], priority);
364375

365-
drm_sched_rq_remove_entity(entity->rq, entity);
366-
drm_sched_entity_set_rq_priority(&entity->rq, priority);
367-
drm_sched_rq_add_entity(entity->rq, entity);
376+
if (entity->rq) {
377+
drm_sched_rq_remove_entity(entity->rq, entity);
378+
drm_sched_entity_set_rq_priority(&entity->rq, priority);
379+
drm_sched_rq_add_entity(entity->rq, entity);
380+
}
368381

369382
spin_unlock(&entity->rq_lock);
370383
}

0 commit comments

Comments
 (0)