diff options
author | Christian König <christian.koenig@amd.com> | 2016-02-03 07:44:52 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-02-10 14:17:18 -0500 |
commit | 50838c8cc413de8da39c4c216ae05410845d5a44 (patch) | |
tree | 1a7f94a784593e9da9a02d801f28d46ac4dbafa7 /drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |
parent | 4acabfe3793eb9bf89f71cc0cef23dfb2a812916 (diff) |
drm/amdgpu: add proper job alloc/free functions
And use them in the CS instead of allocating IBs and jobs separately.
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucer@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 65 |
1 files changed, 22 insertions, 43 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 55179efccfcf..e9d88771783b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -121,7 +121,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
121 | uint64_t *chunk_array_user; | 121 | uint64_t *chunk_array_user; |
122 | uint64_t *chunk_array; | 122 | uint64_t *chunk_array; |
123 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; | 123 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; |
124 | unsigned size; | 124 | unsigned size, num_ibs = 0; |
125 | int i; | 125 | int i; |
126 | int ret; | 126 | int ret; |
127 | 127 | ||
@@ -186,7 +186,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
186 | 186 | ||
187 | switch (p->chunks[i].chunk_id) { | 187 | switch (p->chunks[i].chunk_id) { |
188 | case AMDGPU_CHUNK_ID_IB: | 188 | case AMDGPU_CHUNK_ID_IB: |
189 | p->num_ibs++; | 189 | ++num_ibs; |
190 | break; | 190 | break; |
191 | 191 | ||
192 | case AMDGPU_CHUNK_ID_FENCE: | 192 | case AMDGPU_CHUNK_ID_FENCE: |
@@ -211,16 +211,9 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
211 | } | 211 | } |
212 | } | 212 | } |
213 | 213 | ||
214 | if (p->num_ibs == 0) { | 214 | ret = amdgpu_job_alloc(p->adev, num_ibs, &p->job); |
215 | ret = -EINVAL; | 215 | if (ret) |
216 | goto free_all_kdata; | 216 | goto free_all_kdata; |
217 | } | ||
218 | |||
219 | p->ibs = kcalloc(p->num_ibs, sizeof(struct amdgpu_ib), GFP_KERNEL); | ||
220 | if (!p->ibs) { | ||
221 | ret = -ENOMEM; | ||
222 | goto free_all_kdata; | ||
223 | } | ||
224 | 217 | ||
225 | kfree(chunk_array); | 218 | kfree(chunk_array); |
226 | return 0; | 219 | return 0; |
@@ -414,7 +407,7 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p) | |||
414 | 407 | ||
415 | list_for_each_entry(e, &p->validated, tv.head) { | 408 | list_for_each_entry(e, &p->validated, tv.head) { |
416 | struct reservation_object *resv = e->robj->tbo.resv; | 409 | struct reservation_object *resv = e->robj->tbo.resv; |
417 | r = amdgpu_sync_resv(p->adev, &p->ibs[0].sync, resv, p->filp); | 410 | r = amdgpu_sync_resv(p->adev, &p->job->ibs[0].sync, resv, p->filp); |
418 | 411 | ||
419 | if (r) | 412 | if (r) |
420 | return r; | 413 | return r; |
@@ -477,10 +470,8 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo | |||
477 | for (i = 0; i < parser->nchunks; i++) | 470 | for (i = 0; i < parser->nchunks; i++) |
478 | drm_free_large(parser->chunks[i].kdata); | 471 | drm_free_large(parser->chunks[i].kdata); |
479 | kfree(parser->chunks); | 472 | kfree(parser->chunks); |
480 | if (parser->ibs) | 473 | if (parser->job) |
481 | for (i = 0; i < parser->num_ibs; i++) | 474 | amdgpu_job_free(parser->job); |
482 | amdgpu_ib_free(parser->adev, &parser->ibs[i]); | ||
483 | kfree(parser->ibs); | ||
484 | amdgpu_bo_unref(&parser->uf.bo); | 475 | amdgpu_bo_unref(&parser->uf.bo); |
485 | amdgpu_bo_unref(&parser->uf_entry.robj); | 476 | amdgpu_bo_unref(&parser->uf_entry.robj); |
486 | } | 477 | } |
@@ -497,7 +488,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, | |||
497 | if (r) | 488 | if (r) |
498 | return r; | 489 | return r; |
499 | 490 | ||
500 | r = amdgpu_sync_fence(adev, &p->ibs[0].sync, vm->page_directory_fence); | 491 | r = amdgpu_sync_fence(adev, &p->job->ibs[0].sync, vm->page_directory_fence); |
501 | if (r) | 492 | if (r) |
502 | return r; | 493 | return r; |
503 | 494 | ||
@@ -523,14 +514,14 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, | |||
523 | return r; | 514 | return r; |
524 | 515 | ||
525 | f = bo_va->last_pt_update; | 516 | f = bo_va->last_pt_update; |
526 | r = amdgpu_sync_fence(adev, &p->ibs[0].sync, f); | 517 | r = amdgpu_sync_fence(adev, &p->job->ibs[0].sync, f); |
527 | if (r) | 518 | if (r) |
528 | return r; | 519 | return r; |
529 | } | 520 | } |
530 | 521 | ||
531 | } | 522 | } |
532 | 523 | ||
533 | r = amdgpu_vm_clear_invalids(adev, vm, &p->ibs[0].sync); | 524 | r = amdgpu_vm_clear_invalids(adev, vm, &p->job->ibs[0].sync); |
534 | 525 | ||
535 | if (amdgpu_vm_debug && p->bo_list) { | 526 | if (amdgpu_vm_debug && p->bo_list) { |
536 | /* Invalidate all BOs to test for userspace bugs */ | 527 | /* Invalidate all BOs to test for userspace bugs */ |
@@ -556,8 +547,8 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, | |||
556 | int i, r; | 547 | int i, r; |
557 | 548 | ||
558 | /* Only for UVD/VCE VM emulation */ | 549 | /* Only for UVD/VCE VM emulation */ |
559 | for (i = 0; i < parser->num_ibs; i++) { | 550 | for (i = 0; i < parser->job->num_ibs; i++) { |
560 | ring = parser->ibs[i].ring; | 551 | ring = parser->job->ibs[i].ring; |
561 | if (ring->funcs->parse_cs) { | 552 | if (ring->funcs->parse_cs) { |
562 | r = amdgpu_ring_parse_cs(ring, parser, i); | 553 | r = amdgpu_ring_parse_cs(ring, parser, i); |
563 | if (r) | 554 | if (r) |
@@ -590,14 +581,14 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, | |||
590 | int i, j; | 581 | int i, j; |
591 | int r; | 582 | int r; |
592 | 583 | ||
593 | for (i = 0, j = 0; i < parser->nchunks && j < parser->num_ibs; i++) { | 584 | for (i = 0, j = 0; i < parser->nchunks && j < parser->job->num_ibs; i++) { |
594 | struct amdgpu_cs_chunk *chunk; | 585 | struct amdgpu_cs_chunk *chunk; |
595 | struct amdgpu_ib *ib; | 586 | struct amdgpu_ib *ib; |
596 | struct drm_amdgpu_cs_chunk_ib *chunk_ib; | 587 | struct drm_amdgpu_cs_chunk_ib *chunk_ib; |
597 | struct amdgpu_ring *ring; | 588 | struct amdgpu_ring *ring; |
598 | 589 | ||
599 | chunk = &parser->chunks[i]; | 590 | chunk = &parser->chunks[i]; |
600 | ib = &parser->ibs[j]; | 591 | ib = &parser->job->ibs[j]; |
601 | chunk_ib = (struct drm_amdgpu_cs_chunk_ib *)chunk->kdata; | 592 | chunk_ib = (struct drm_amdgpu_cs_chunk_ib *)chunk->kdata; |
602 | 593 | ||
603 | if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB) | 594 | if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB) |
@@ -666,7 +657,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, | |||
666 | struct amdgpu_bo *gds = parser->bo_list->gds_obj; | 657 | struct amdgpu_bo *gds = parser->bo_list->gds_obj; |
667 | struct amdgpu_bo *gws = parser->bo_list->gws_obj; | 658 | struct amdgpu_bo *gws = parser->bo_list->gws_obj; |
668 | struct amdgpu_bo *oa = parser->bo_list->oa_obj; | 659 | struct amdgpu_bo *oa = parser->bo_list->oa_obj; |
669 | struct amdgpu_ib *ib = &parser->ibs[0]; | 660 | struct amdgpu_ib *ib = &parser->job->ibs[0]; |
670 | 661 | ||
671 | if (gds) { | 662 | if (gds) { |
672 | ib->gds_base = amdgpu_bo_gpu_offset(gds); | 663 | ib->gds_base = amdgpu_bo_gpu_offset(gds); |
@@ -683,7 +674,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, | |||
683 | } | 674 | } |
684 | /* wrap the last IB with user fence */ | 675 | /* wrap the last IB with user fence */ |
685 | if (parser->uf.bo) { | 676 | if (parser->uf.bo) { |
686 | struct amdgpu_ib *ib = &parser->ibs[parser->num_ibs - 1]; | 677 | struct amdgpu_ib *ib = &parser->job->ibs[parser->job->num_ibs - 1]; |
687 | 678 | ||
688 | /* UVD & VCE fw doesn't support user fences */ | 679 | /* UVD & VCE fw doesn't support user fences */ |
689 | if (ib->ring->type == AMDGPU_RING_TYPE_UVD || | 680 | if (ib->ring->type == AMDGPU_RING_TYPE_UVD || |
@@ -704,7 +695,7 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, | |||
704 | int i, j, r; | 695 | int i, j, r; |
705 | 696 | ||
706 | /* Add dependencies to first IB */ | 697 | /* Add dependencies to first IB */ |
707 | ib = &p->ibs[0]; | 698 | ib = &p->job->ibs[0]; |
708 | for (i = 0; i < p->nchunks; ++i) { | 699 | for (i = 0; i < p->nchunks; ++i) { |
709 | struct drm_amdgpu_cs_chunk_dep *deps; | 700 | struct drm_amdgpu_cs_chunk_dep *deps; |
710 | struct amdgpu_cs_chunk *chunk; | 701 | struct amdgpu_cs_chunk *chunk; |
@@ -756,26 +747,19 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, | |||
756 | 747 | ||
757 | static int amdgpu_cs_free_job(struct amdgpu_job *job) | 748 | static int amdgpu_cs_free_job(struct amdgpu_job *job) |
758 | { | 749 | { |
759 | int i; | 750 | amdgpu_job_free(job); |
760 | if (job->ibs) | ||
761 | for (i = 0; i < job->num_ibs; i++) | ||
762 | amdgpu_ib_free(job->adev, &job->ibs[i]); | ||
763 | kfree(job->ibs); | ||
764 | if (job->uf.bo) | ||
765 | amdgpu_bo_unref(&job->uf.bo); | ||
766 | return 0; | 751 | return 0; |
767 | } | 752 | } |
768 | 753 | ||
769 | static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | 754 | static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, |
770 | union drm_amdgpu_cs *cs) | 755 | union drm_amdgpu_cs *cs) |
771 | { | 756 | { |
772 | struct amdgpu_ring * ring = p->ibs->ring; | 757 | struct amdgpu_ring * ring = p->job->ibs->ring; |
773 | struct amd_sched_fence *fence; | 758 | struct amd_sched_fence *fence; |
774 | struct amdgpu_job *job; | 759 | struct amdgpu_job *job; |
775 | 760 | ||
776 | job = kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL); | 761 | job = p->job; |
777 | if (!job) | 762 | p->job = NULL; |
778 | return -ENOMEM; | ||
779 | 763 | ||
780 | job->base.sched = &ring->sched; | 764 | job->base.sched = &ring->sched; |
781 | job->base.s_entity = &p->ctx->rings[ring->idx].entity; | 765 | job->base.s_entity = &p->ctx->rings[ring->idx].entity; |
@@ -783,11 +767,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | |||
783 | job->owner = p->filp; | 767 | job->owner = p->filp; |
784 | job->free_job = amdgpu_cs_free_job; | 768 | job->free_job = amdgpu_cs_free_job; |
785 | 769 | ||
786 | job->ibs = p->ibs; | ||
787 | job->num_ibs = p->num_ibs; | ||
788 | p->ibs = NULL; | ||
789 | p->num_ibs = 0; | ||
790 | |||
791 | if (job->ibs[job->num_ibs - 1].user) { | 770 | if (job->ibs[job->num_ibs - 1].user) { |
792 | job->uf = p->uf; | 771 | job->uf = p->uf; |
793 | job->ibs[job->num_ibs - 1].user = &job->uf; | 772 | job->ibs[job->num_ibs - 1].user = &job->uf; |
@@ -854,7 +833,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
854 | if (r) | 833 | if (r) |
855 | goto out; | 834 | goto out; |
856 | 835 | ||
857 | for (i = 0; i < parser.num_ibs; i++) | 836 | for (i = 0; i < parser.job->num_ibs; i++) |
858 | trace_amdgpu_cs(&parser, i); | 837 | trace_amdgpu_cs(&parser, i); |
859 | 838 | ||
860 | r = amdgpu_cs_ib_vm_chunk(adev, &parser); | 839 | r = amdgpu_cs_ib_vm_chunk(adev, &parser); |