diff options
author | Christian König <christian.koenig@amd.com> | 2017-09-05 08:30:05 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-09-12 14:24:09 -0400 |
commit | ca666a3c298f838346ccea46ff542c605e68deb5 (patch) | |
tree | 7ac2c1cecaaf8c52a94439604d942f6001af0cd2 | |
parent | b72cf4fca2bb786e20864b5e8755105aa9626fb4 (diff) |
drm/amdgpu: stop using BO status for user pages
Instead use a counter to figure out if we need to set new pages or not.
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 14 |
3 files changed, 22 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index cc6de0b46326..f3e561136597 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1802,6 +1802,7 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, | |||
1802 | unsigned long end); | 1802 | unsigned long end); |
1803 | bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, | 1803 | bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, |
1804 | int *last_invalidated); | 1804 | int *last_invalidated); |
1805 | bool amdgpu_ttm_tt_userptr_needs_pages(struct ttm_tt *ttm); | ||
1805 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm); | 1806 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm); |
1806 | uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, | 1807 | uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, |
1807 | struct ttm_mem_reg *mem); | 1808 | struct ttm_mem_reg *mem); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 283a216ee758..4d3f8fbfa59d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -473,7 +473,8 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, | |||
473 | return -EPERM; | 473 | return -EPERM; |
474 | 474 | ||
475 | /* Check if we have user pages and nobody bound the BO already */ | 475 | /* Check if we have user pages and nobody bound the BO already */ |
476 | if (lobj->user_pages && bo->tbo.ttm->state != tt_bound) { | 476 | if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm) && |
477 | lobj->user_pages) { | ||
477 | amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, | 478 | amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, |
478 | lobj->user_pages); | 479 | lobj->user_pages); |
479 | binding_userptr = true; | 480 | binding_userptr = true; |
@@ -534,23 +535,25 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
534 | INIT_LIST_HEAD(&need_pages); | 535 | INIT_LIST_HEAD(&need_pages); |
535 | for (i = p->bo_list->first_userptr; | 536 | for (i = p->bo_list->first_userptr; |
536 | i < p->bo_list->num_entries; ++i) { | 537 | i < p->bo_list->num_entries; ++i) { |
538 | struct amdgpu_bo *bo; | ||
537 | 539 | ||
538 | e = &p->bo_list->array[i]; | 540 | e = &p->bo_list->array[i]; |
541 | bo = e->robj; | ||
539 | 542 | ||
540 | if (amdgpu_ttm_tt_userptr_invalidated(e->robj->tbo.ttm, | 543 | if (amdgpu_ttm_tt_userptr_invalidated(bo->tbo.ttm, |
541 | &e->user_invalidated) && e->user_pages) { | 544 | &e->user_invalidated) && e->user_pages) { |
542 | 545 | ||
543 | /* We acquired a page array, but somebody | 546 | /* We acquired a page array, but somebody |
544 | * invalidated it. Free it and try again | 547 | * invalidated it. Free it and try again |
545 | */ | 548 | */ |
546 | release_pages(e->user_pages, | 549 | release_pages(e->user_pages, |
547 | e->robj->tbo.ttm->num_pages, | 550 | bo->tbo.ttm->num_pages, |
548 | false); | 551 | false); |
549 | kvfree(e->user_pages); | 552 | kvfree(e->user_pages); |
550 | e->user_pages = NULL; | 553 | e->user_pages = NULL; |
551 | } | 554 | } |
552 | 555 | ||
553 | if (e->robj->tbo.ttm->state != tt_bound && | 556 | if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm) && |
554 | !e->user_pages) { | 557 | !e->user_pages) { |
555 | list_del(&e->tv.head); | 558 | list_del(&e->tv.head); |
556 | list_add(&e->tv.head, &need_pages); | 559 | list_add(&e->tv.head, &need_pages); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index ea0378c8b049..e67785191032 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | |||
@@ -609,6 +609,7 @@ struct amdgpu_ttm_tt { | |||
609 | spinlock_t guptasklock; | 609 | spinlock_t guptasklock; |
610 | struct list_head guptasks; | 610 | struct list_head guptasks; |
611 | atomic_t mmu_invalidations; | 611 | atomic_t mmu_invalidations; |
612 | uint32_t last_set_pages; | ||
612 | struct list_head list; | 613 | struct list_head list; |
613 | }; | 614 | }; |
614 | 615 | ||
@@ -672,8 +673,10 @@ release_pages: | |||
672 | 673 | ||
673 | void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages) | 674 | void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages) |
674 | { | 675 | { |
676 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | ||
675 | unsigned i; | 677 | unsigned i; |
676 | 678 | ||
679 | gtt->last_set_pages = atomic_read(>t->mmu_invalidations); | ||
677 | for (i = 0; i < ttm->num_pages; ++i) { | 680 | for (i = 0; i < ttm->num_pages; ++i) { |
678 | if (ttm->pages[i]) | 681 | if (ttm->pages[i]) |
679 | put_page(ttm->pages[i]); | 682 | put_page(ttm->pages[i]); |
@@ -1025,6 +1028,7 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, | |||
1025 | spin_lock_init(>t->guptasklock); | 1028 | spin_lock_init(>t->guptasklock); |
1026 | INIT_LIST_HEAD(>t->guptasks); | 1029 | INIT_LIST_HEAD(>t->guptasks); |
1027 | atomic_set(>t->mmu_invalidations, 0); | 1030 | atomic_set(>t->mmu_invalidations, 0); |
1031 | gtt->last_set_pages = 0; | ||
1028 | 1032 | ||
1029 | return 0; | 1033 | return 0; |
1030 | } | 1034 | } |
@@ -1077,6 +1081,16 @@ bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, | |||
1077 | return prev_invalidated != *last_invalidated; | 1081 | return prev_invalidated != *last_invalidated; |
1078 | } | 1082 | } |
1079 | 1083 | ||
1084 | bool amdgpu_ttm_tt_userptr_needs_pages(struct ttm_tt *ttm) | ||
1085 | { | ||
1086 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | ||
1087 | |||
1088 | if (gtt == NULL || !gtt->userptr) | ||
1089 | return false; | ||
1090 | |||
1091 | return atomic_read(>t->mmu_invalidations) != gtt->last_set_pages; | ||
1092 | } | ||
1093 | |||
1080 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm) | 1094 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm) |
1081 | { | 1095 | { |
1082 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 1096 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |