Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/scheduler: rework entity creation

Entity currently keeps a copy of run_queue list and modify it in
drm_sched_entity_set_priority(). Entities shouldn't modify run_queue
list. Use drm_gpu_scheduler list instead of drm_sched_rq list
in drm_sched_entity struct. In this way we can select a runqueue based
on entity/ctx's priority for a drm scheduler.

Signed-off-by: Nirmoy Das <nirmoy.das@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Nirmoy Das and committed by
Alex Deucher
b3ac1766 45a80abe

+79 -76
+4 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
··· 122 122 123 123 for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) { 124 124 struct amdgpu_ring *rings[AMDGPU_MAX_RINGS]; 125 - struct drm_sched_rq *rqs[AMDGPU_MAX_RINGS]; 125 + struct drm_gpu_scheduler *sched_list[AMDGPU_MAX_RINGS]; 126 126 unsigned num_rings = 0; 127 127 unsigned num_rqs = 0; 128 128 ··· 181 181 if (!rings[j]->adev) 182 182 continue; 183 183 184 - rqs[num_rqs++] = &rings[j]->sched.sched_rq[priority]; 184 + sched_list[num_rqs++] = &rings[j]->sched; 185 185 } 186 186 187 187 for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) 188 188 r = drm_sched_entity_init(&ctx->entities[i][j].entity, 189 - rqs, num_rqs, &ctx->guilty); 189 + priority, sched_list, 190 + num_rqs, &ctx->guilty); 190 191 if (r) 191 192 goto error_cleanup_entities; 192 193 }
+5 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
··· 1987 1987 1988 1988 if (enable) { 1989 1989 struct amdgpu_ring *ring; 1990 - struct drm_sched_rq *rq; 1990 + struct drm_gpu_scheduler *sched; 1991 1991 1992 1992 ring = adev->mman.buffer_funcs_ring; 1993 - rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_KERNEL]; 1994 - r = drm_sched_entity_init(&adev->mman.entity, &rq, 1, NULL); 1993 + sched = &ring->sched; 1994 + r = drm_sched_entity_init(&adev->mman.entity, 1995 + DRM_SCHED_PRIORITY_KERNEL, &sched, 1996 + 1, NULL); 1995 1997 if (r) { 1996 1998 DRM_ERROR("Failed setting up TTM BO move entity (%d)\n", 1997 1999 r);
+4 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
··· 330 330 int amdgpu_uvd_entity_init(struct amdgpu_device *adev) 331 331 { 332 332 struct amdgpu_ring *ring; 333 - struct drm_sched_rq *rq; 333 + struct drm_gpu_scheduler *sched; 334 334 int r; 335 335 336 336 ring = &adev->uvd.inst[0].ring; 337 - rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; 338 - r = drm_sched_entity_init(&adev->uvd.entity, &rq, 1, NULL); 337 + sched = &ring->sched; 338 + r = drm_sched_entity_init(&adev->uvd.entity, DRM_SCHED_PRIORITY_NORMAL, 339 + &sched, 1, NULL); 339 340 if (r) { 340 341 DRM_ERROR("Failed setting up UVD kernel entity.\n"); 341 342 return r;
+4 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
··· 240 240 int amdgpu_vce_entity_init(struct amdgpu_device *adev) 241 241 { 242 242 struct amdgpu_ring *ring; 243 - struct drm_sched_rq *rq; 243 + struct drm_gpu_scheduler *sched; 244 244 int r; 245 245 246 246 ring = &adev->vce.ring[0]; 247 - rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; 248 - r = drm_sched_entity_init(&adev->vce.entity, &rq, 1, NULL); 247 + sched = &ring->sched; 248 + r = drm_sched_entity_init(&adev->vce.entity, DRM_SCHED_PRIORITY_NORMAL, 249 + &sched, 1, NULL); 249 250 if (r != 0) { 250 251 DRM_ERROR("Failed setting up VCE run queue.\n"); 251 252 return r;
+10 -4
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 2740 2740 { 2741 2741 struct amdgpu_bo_param bp; 2742 2742 struct amdgpu_bo *root; 2743 + struct drm_gpu_scheduler *sched_list[AMDGPU_MAX_RINGS]; 2743 2744 int r, i; 2744 2745 2745 2746 vm->va = RB_ROOT_CACHED; ··· 2754 2753 spin_lock_init(&vm->invalidated_lock); 2755 2754 INIT_LIST_HEAD(&vm->freed); 2756 2755 2756 + for (i = 0; i < adev->vm_manager.vm_pte_num_rqs; i++) 2757 + sched_list[i] = adev->vm_manager.vm_pte_rqs[i]->sched; 2758 + 2757 2759 /* create scheduler entities for page table updates */ 2758 - r = drm_sched_entity_init(&vm->direct, adev->vm_manager.vm_pte_rqs, 2759 - adev->vm_manager.vm_pte_num_rqs, NULL); 2760 + r = drm_sched_entity_init(&vm->direct, DRM_SCHED_PRIORITY_NORMAL, 2761 + sched_list, adev->vm_manager.vm_pte_num_rqs, 2762 + NULL); 2760 2763 if (r) 2761 2764 return r; 2762 2765 2763 - r = drm_sched_entity_init(&vm->delayed, adev->vm_manager.vm_pte_rqs, 2764 - adev->vm_manager.vm_pte_num_rqs, NULL); 2766 + r = drm_sched_entity_init(&vm->delayed, DRM_SCHED_PRIORITY_NORMAL, 2767 + sched_list, adev->vm_manager.vm_pte_num_rqs, 2768 + NULL); 2765 2769 if (r) 2766 2770 goto error_free_direct; 2767 2771
+4 -3
drivers/gpu/drm/etnaviv/etnaviv_drv.c
··· 65 65 66 66 for (i = 0; i < ETNA_MAX_PIPES; i++) { 67 67 struct etnaviv_gpu *gpu = priv->gpu[i]; 68 - struct drm_sched_rq *rq; 68 + struct drm_gpu_scheduler *sched; 69 69 70 70 if (gpu) { 71 - rq = &gpu->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; 71 + sched = &gpu->sched; 72 72 drm_sched_entity_init(&ctx->sched_entity[i], 73 - &rq, 1, NULL); 73 + DRM_SCHED_PRIORITY_NORMAL, &sched, 74 + 1, NULL); 74 75 } 75 76 } 76 77
+3 -2
drivers/gpu/drm/lima/lima_sched.c
··· 159 159 struct lima_sched_context *context, 160 160 atomic_t *guilty) 161 161 { 162 - struct drm_sched_rq *rq = pipe->base.sched_rq + DRM_SCHED_PRIORITY_NORMAL; 162 + struct drm_gpu_scheduler *sched = &pipe->base; 163 163 164 - return drm_sched_entity_init(&context->base, &rq, 1, guilty); 164 + return drm_sched_entity_init(&context->base, DRM_SCHED_PRIORITY_NORMAL, 165 + &sched, 1, guilty); 165 166 } 166 167 167 168 void lima_sched_context_fini(struct lima_sched_pipe *pipe,
+5 -3
drivers/gpu/drm/panfrost/panfrost_job.c
··· 542 542 { 543 543 struct panfrost_device *pfdev = panfrost_priv->pfdev; 544 544 struct panfrost_job_slot *js = pfdev->js; 545 - struct drm_sched_rq *rq; 545 + struct drm_gpu_scheduler *sched; 546 546 int ret, i; 547 547 548 548 for (i = 0; i < NUM_JOB_SLOTS; i++) { 549 - rq = &js->queue[i].sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; 550 - ret = drm_sched_entity_init(&panfrost_priv->sched_entity[i], &rq, 1, NULL); 549 + sched = &js->queue[i].sched; 550 + ret = drm_sched_entity_init(&panfrost_priv->sched_entity[i], 551 + DRM_SCHED_PRIORITY_NORMAL, &sched, 552 + 1, NULL); 551 553 if (WARN_ON(ret)) 552 554 return ret; 553 555 }
+30 -46
drivers/gpu/drm/scheduler/sched_entity.c
··· 38 38 * submit to HW ring. 39 39 * 40 40 * @entity: scheduler entity to init 41 - * @rq_list: the list of run queue on which jobs from this 41 + * @priority: priority of the entity 42 + * @sched_list: the list of drm scheds on which jobs from this 42 43 * entity can be submitted 43 - * @num_rq_list: number of run queue in rq_list 44 + * @num_sched_list: number of drm sched in sched_list 44 45 * @guilty: atomic_t set to 1 when a job on this queue 45 46 * is found to be guilty causing a timeout 46 47 * ··· 51 50 * Returns 0 on success or a negative error code on failure. 52 51 */ 53 52 int drm_sched_entity_init(struct drm_sched_entity *entity, 54 - struct drm_sched_rq **rq_list, 55 - unsigned int num_rq_list, 53 + enum drm_sched_priority priority, 54 + struct drm_gpu_scheduler **sched_list, 55 + unsigned int num_sched_list, 56 56 atomic_t *guilty) 57 57 { 58 58 int i; 59 59 60 - if (!(entity && rq_list && (num_rq_list == 0 || rq_list[0]))) 60 + if (!(entity && sched_list && (num_sched_list == 0 || sched_list[0]))) 61 61 return -EINVAL; 62 62 63 63 memset(entity, 0, sizeof(struct drm_sched_entity)); 64 64 INIT_LIST_HEAD(&entity->list); 65 65 entity->rq = NULL; 66 66 entity->guilty = guilty; 67 - entity->num_rq_list = num_rq_list; 68 - entity->rq_list = kcalloc(num_rq_list, sizeof(struct drm_sched_rq *), 69 - GFP_KERNEL); 70 - if (!entity->rq_list) 67 + entity->num_sched_list = num_sched_list; 68 + entity->priority = priority; 69 + entity->sched_list = kcalloc(num_sched_list, 70 + sizeof(struct drm_gpu_scheduler *), GFP_KERNEL); 71 + 72 + if(!entity->sched_list) 71 73 return -ENOMEM; 72 74 73 75 init_completion(&entity->entity_idle); 74 76 75 - for (i = 0; i < num_rq_list; ++i) 76 - entity->rq_list[i] = rq_list[i]; 77 + for (i = 0; i < num_sched_list; i++) 78 + entity->sched_list[i] = sched_list[i]; 77 79 78 - if (num_rq_list) 79 - entity->rq = rq_list[0]; 80 + if (num_sched_list) 81 + entity->rq = &entity->sched_list[0]->sched_rq[entity->priority]; 80 82 81 83 entity->last_scheduled = NULL; 82 84 ··· 143 139 unsigned int min_jobs = UINT_MAX, num_jobs; 144 140 int i; 145 141 146 - for (i = 0; i < entity->num_rq_list; ++i) { 147 - struct drm_gpu_scheduler *sched = entity->rq_list[i]->sched; 142 + for (i = 0; i < entity->num_sched_list; ++i) { 143 + struct drm_gpu_scheduler *sched = entity->sched_list[i]; 148 144 149 - if (!entity->rq_list[i]->sched->ready) { 145 + if (!entity->sched_list[i]->ready) { 150 146 DRM_WARN("sched%s is not ready, skipping", sched->name); 151 147 continue; 152 148 } ··· 154 150 num_jobs = atomic_read(&sched->num_jobs); 155 151 if (num_jobs < min_jobs) { 156 152 min_jobs = num_jobs; 157 - rq = entity->rq_list[i]; 153 + rq = &entity->sched_list[i]->sched_rq[entity->priority]; 158 154 } 159 155 } 160 156 ··· 312 308 313 309 dma_fence_put(entity->last_scheduled); 314 310 entity->last_scheduled = NULL; 315 - kfree(entity->rq_list); 311 + kfree(entity->sched_list); 316 312 } 317 313 EXPORT_SYMBOL(drm_sched_entity_fini); 318 314 ··· 358 354 } 359 355 360 356 /** 361 - * drm_sched_entity_set_rq_priority - helper for drm_sched_entity_set_priority 362 - */ 363 - static void drm_sched_entity_set_rq_priority(struct drm_sched_rq **rq, 364 - enum drm_sched_priority priority) 365 - { 366 - *rq = &(*rq)->sched->sched_rq[priority]; 367 - } 368 - 369 - /** 370 357 * drm_sched_entity_set_priority - Sets priority of the entity 371 358 * 372 359 * @entity: scheduler entity ··· 368 373 void drm_sched_entity_set_priority(struct drm_sched_entity *entity, 369 374 enum drm_sched_priority priority) 370 375 { 371 - unsigned int i; 372 - 373 376 spin_lock(&entity->rq_lock); 374 - 375 - for (i = 0; i < entity->num_rq_list; ++i) 376 - drm_sched_entity_set_rq_priority(&entity->rq_list[i], priority); 377 - 378 - if (entity->rq) { 379 - drm_sched_rq_remove_entity(entity->rq, entity); 380 - drm_sched_entity_set_rq_priority(&entity->rq, priority); 381 - drm_sched_rq_add_entity(entity->rq, entity); 382 - } 383 - 377 + entity->priority = priority; 384 378 spin_unlock(&entity->rq_lock); 385 379 } 386 380 EXPORT_SYMBOL(drm_sched_entity_set_priority); ··· 474 490 struct dma_fence *fence; 475 491 struct drm_sched_rq *rq; 476 492 477 - if (spsc_queue_count(&entity->job_queue) || entity->num_rq_list <= 1) 493 + if (spsc_queue_count(&entity->job_queue) || entity->num_sched_list <= 1) 478 494 return; 479 495 480 496 fence = READ_ONCE(entity->last_scheduled); 481 497 if (fence && !dma_fence_is_signaled(fence)) 482 498 return; 483 499 484 - rq = drm_sched_entity_get_free_sched(entity); 485 - if (rq == entity->rq) 486 - return; 487 - 488 500 spin_lock(&entity->rq_lock); 489 - drm_sched_rq_remove_entity(entity->rq, entity); 490 - entity->rq = rq; 501 + rq = drm_sched_entity_get_free_sched(entity); 502 + if (rq != entity->rq) { 503 + drm_sched_rq_remove_entity(entity->rq, entity); 504 + entity->rq = rq; 505 + } 506 + 491 507 spin_unlock(&entity->rq_lock); 492 508 } 493 509
+5 -3
drivers/gpu/drm/v3d/v3d_drv.c
··· 140 140 { 141 141 struct v3d_dev *v3d = to_v3d_dev(dev); 142 142 struct v3d_file_priv *v3d_priv; 143 - struct drm_sched_rq *rq; 143 + struct drm_gpu_scheduler *sched; 144 144 int i; 145 145 146 146 v3d_priv = kzalloc(sizeof(*v3d_priv), GFP_KERNEL); ··· 150 150 v3d_priv->v3d = v3d; 151 151 152 152 for (i = 0; i < V3D_MAX_QUEUES; i++) { 153 - rq = &v3d->queue[i].sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; 154 - drm_sched_entity_init(&v3d_priv->sched_entity[i], &rq, 1, NULL); 153 + sched = &v3d->queue[i].sched; 154 + drm_sched_entity_init(&v3d_priv->sched_entity[i], 155 + DRM_SCHED_PRIORITY_NORMAL, &sched, 156 + 1, NULL); 155 157 } 156 158 157 159 file->driver_priv = v3d_priv;
+5 -3
include/drm/gpu_scheduler.h
··· 81 81 struct drm_sched_entity { 82 82 struct list_head list; 83 83 struct drm_sched_rq *rq; 84 - struct drm_sched_rq **rq_list; 85 - unsigned int num_rq_list; 84 + unsigned int num_sched_list; 85 + struct drm_gpu_scheduler **sched_list; 86 + enum drm_sched_priority priority; 86 87 spinlock_t rq_lock; 87 88 88 89 struct spsc_queue job_queue; ··· 313 312 struct drm_sched_entity *entity); 314 313 315 314 int drm_sched_entity_init(struct drm_sched_entity *entity, 316 - struct drm_sched_rq **rq_list, 315 + enum drm_sched_priority priority, 316 + struct drm_gpu_scheduler **sched_list, 317 317 unsigned int num_rq_list, 318 318 atomic_t *guilty); 319 319 long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout);