From: Christian König christian.koenig@amd.com
It's only used once after initializing and that ptr can be calculated from the BO as well.
Signed-off-by: Christian König christian.koenig@amd.com --- drivers/gpu/drm/radeon/radeon.h | 1 - drivers/gpu/drm/radeon/radeon_cs.c | 15 +++++++++------ drivers/gpu/drm/radeon/radeon_vm.c | 2 -- 3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3207bb6..4a09ffd 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1045,7 +1045,6 @@ void cayman_dma_fini(struct radeon_device *rdev); * CS. */ struct radeon_cs_reloc { - struct drm_gem_object *gobj; struct radeon_bo *robj; struct ttm_validate_buffer tv; uint64_t gpu_offset; diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index f5e0a69..7846c3e 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -101,6 +101,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
for (i = 0; i < p->nrelocs; i++) { struct drm_radeon_cs_reloc *r; + struct drm_gem_object *gobj; unsigned priority;
duplicate = false; @@ -117,15 +118,14 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) continue; }
- p->relocs[i].gobj = drm_gem_object_lookup(ddev, p->filp, - r->handle); - if (p->relocs[i].gobj == NULL) { + gobj = drm_gem_object_lookup(ddev, p->filp, r->handle); + if (gobj == NULL) { DRM_ERROR("gem object lookup failed 0x%x\n", r->handle); return -ENOENT; } p->relocs_ptr[i] = &p->relocs[i]; - p->relocs[i].robj = gem_to_radeon_bo(p->relocs[i].gobj); + p->relocs[i].robj = gem_to_radeon_bo(gobj);
/* The userspace buffer priorities are from 0 to 15. A higher * number means the buffer is more important. @@ -439,8 +439,11 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo
if (parser->relocs != NULL) { for (i = 0; i < parser->nrelocs; i++) { - if (parser->relocs[i].gobj) - drm_gem_object_unreference_unlocked(parser->relocs[i].gobj); + struct radeon_bo *bo = parser->relocs[i].robj; + if (bo == NULL) + continue; + + drm_gem_object_unreference_unlocked(&bo->gem_base); } } kfree(parser->track); diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 0b10f3a..2b2eb1c 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -138,7 +138,6 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, return NULL;
/* add the vm page table to the list */ - list[0].gobj = NULL; list[0].robj = vm->page_directory; list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM; list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM; @@ -152,7 +151,6 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, if (!vm->page_tables[i].bo) continue;
- list[idx].gobj = NULL; list[idx].robj = vm->page_tables[i].bo; list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM; list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM;
From: Christian König christian.koenig@amd.com
It's only used for duplicate check and that can be done on the original as well.
Signed-off-by: Christian König christian.koenig@amd.com --- drivers/gpu/drm/radeon/radeon.h | 1 - drivers/gpu/drm/radeon/radeon_cs.c | 6 +++--- drivers/gpu/drm/radeon/radeon_vm.c | 2 -- 3 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 4a09ffd..17db846 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1051,7 +1051,6 @@ struct radeon_cs_reloc { unsigned prefered_domains; unsigned allowed_domains; uint32_t tiling_flags; - uint32_t handle; };
struct radeon_cs_chunk { diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 7846c3e..f1f584a 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -107,14 +107,15 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) duplicate = false; r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4]; for (j = 0; j < i; j++) { - if (r->handle == p->relocs[j].handle) { + struct drm_radeon_cs_reloc *other; + other = (void *)&chunk->kdata[j*4]; + if (r->handle == other->handle) { p->relocs_ptr[i] = &p->relocs[j]; duplicate = true; break; } } if (duplicate) { - p->relocs[i].handle = 0; continue; }
@@ -184,7 +185,6 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
p->relocs[i].tv.bo = &p->relocs[i].robj->tbo; p->relocs[i].tv.shared = !r->write_domain; - p->relocs[i].handle = r->handle;
radeon_cs_buckets_add(&buckets, &p->relocs[i].tv.head, priority); diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 2b2eb1c..c4ffe02 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -144,7 +144,6 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, list[0].tv.bo = &vm->page_directory->tbo; list[0].tv.shared = true; list[0].tiling_flags = 0; - list[0].handle = 0; list_add(&list[0].tv.head, head);
for (i = 0, idx = 1; i <= vm->max_pde_used; i++) { @@ -157,7 +156,6 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, list[idx].tv.bo = &list[idx].robj->tbo; list[idx].tv.shared = true; list[idx].tiling_flags = 0; - list[idx].handle = 0; list_add(&list[idx++].tv.head, head); }
From: Christian König christian.koenig@amd.com
Better match what it is actually doing.
Signed-off-by: Christian König christian.koenig@amd.com --- drivers/gpu/drm/radeon/evergreen_cs.c | 8 ++++---- drivers/gpu/drm/radeon/r100.c | 8 ++++---- drivers/gpu/drm/radeon/r200.c | 2 +- drivers/gpu/drm/radeon/r300.c | 4 ++-- drivers/gpu/drm/radeon/r600_cs.c | 10 +++++----- drivers/gpu/drm/radeon/radeon.h | 28 ++++++++++++++-------------- drivers/gpu/drm/radeon/radeon_cs.c | 10 +++++----- drivers/gpu/drm/radeon/radeon_gem.c | 2 +- drivers/gpu/drm/radeon/radeon_object.c | 2 +- drivers/gpu/drm/radeon/radeon_uvd.c | 2 +- drivers/gpu/drm/radeon/radeon_vce.c | 2 +- drivers/gpu/drm/radeon/radeon_vm.c | 6 +++--- 12 files changed, 42 insertions(+), 42 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 5c8b358..a1dece6 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -35,7 +35,7 @@ #define MIN(a,b) (((a)<(b))?(a):(b))
int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc); + struct radeon_bo_list **cs_reloc); struct evergreen_cs_track { u32 group_size; u32 nbanks; @@ -1094,7 +1094,7 @@ static int evergreen_cs_parse_packet0(struct radeon_cs_parser *p, static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) { struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track; - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; u32 last_reg; u32 m, i, tmp, *ib; int r; @@ -1792,7 +1792,7 @@ static bool evergreen_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) static int evergreen_packet3_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct evergreen_cs_track *track; volatile u32 *ib; unsigned idx; @@ -2685,7 +2685,7 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) int evergreen_dma_cs_parse(struct radeon_cs_parser *p) { struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; - struct radeon_cs_reloc *src_reloc, *dst_reloc, *dst2_reloc; + struct radeon_bo_list *src_reloc, *dst_reloc, *dst2_reloc; u32 header, cmd, count, sub_cmd; volatile u32 *ib = p->ib.ptr; u32 idx; diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 10f8be0..8174731 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1254,7 +1254,7 @@ int r100_reloc_pitch_offset(struct radeon_cs_parser *p, int r; u32 tile_flags = 0; u32 tmp; - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; u32 value;
r = radeon_cs_packet_next_reloc(p, &reloc, 0); @@ -1293,7 +1293,7 @@ int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, int idx) { unsigned c, i; - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r100_cs_track *track; int r = 0; volatile uint32_t *ib; @@ -1542,7 +1542,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt, unsigned idx, unsigned reg) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r100_cs_track *track; volatile uint32_t *ib; uint32_t tmp; @@ -1901,7 +1901,7 @@ int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, static int r100_packet3_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r100_cs_track *track; unsigned idx; volatile uint32_t *ib; diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index 732d493..c70e6d5 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -146,7 +146,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt, unsigned idx, unsigned reg) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r100_cs_track *track; volatile uint32_t *ib; uint32_t tmp; diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 1bc4704..91d2442 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -598,7 +598,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt, unsigned idx, unsigned reg) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r100_cs_track *track; volatile uint32_t *ib; uint32_t tmp, tile_flags = 0; @@ -1142,7 +1142,7 @@ fail: static int r300_packet3_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r100_cs_track *track; volatile uint32_t *ib; unsigned idx; diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index c47537a..b81ba19 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -969,7 +969,7 @@ static int r600_cs_parse_packet0(struct radeon_cs_parser *p, static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) { struct r600_cs_track *track = (struct r600_cs_track *)p->track; - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; u32 m, i, tmp, *ib; int r;
@@ -1626,7 +1626,7 @@ static bool r600_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) static int r600_packet3_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; struct r600_cs_track *track; volatile u32 *ib; unsigned idx; @@ -2354,7 +2354,7 @@ static int r600_cs_parser_relocs_legacy(struct radeon_cs_parser *p) if (p->chunk_relocs_idx == -1) { return 0; } - p->relocs = kzalloc(sizeof(struct radeon_cs_reloc), GFP_KERNEL); + p->relocs = kzalloc(sizeof(struct radeon_bo_list), GFP_KERNEL); if (p->relocs == NULL) { return -ENOMEM; } @@ -2435,7 +2435,7 @@ void r600_cs_legacy_init(void) * GPU offset using the provided start. **/ int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc) + struct radeon_bo_list **cs_reloc) { struct radeon_cs_chunk *relocs_chunk; unsigned idx; @@ -2473,7 +2473,7 @@ int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, int r600_dma_cs_parse(struct radeon_cs_parser *p) { struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; - struct radeon_cs_reloc *src_reloc, *dst_reloc; + struct radeon_bo_list *src_reloc, *dst_reloc; u32 header, cmd, count, tiled; volatile u32 *ib = p->ib.ptr; u32 idx, idx_value; diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 17db846..da1c549 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -450,6 +450,15 @@ struct radeon_mman { #endif };
+struct radeon_bo_list { + struct radeon_bo *robj; + struct ttm_validate_buffer tv; + uint64_t gpu_offset; + unsigned prefered_domains; + unsigned allowed_domains; + uint32_t tiling_flags; +}; + /* bo virtual address in a specific vm */ struct radeon_bo_va { /* protected by bo being reserved */ @@ -1044,15 +1053,6 @@ void cayman_dma_fini(struct radeon_device *rdev); /* * CS. */ -struct radeon_cs_reloc { - struct radeon_bo *robj; - struct ttm_validate_buffer tv; - uint64_t gpu_offset; - unsigned prefered_domains; - unsigned allowed_domains; - uint32_t tiling_flags; -}; - struct radeon_cs_chunk { uint32_t chunk_id; uint32_t length_dw; @@ -1072,9 +1072,9 @@ struct radeon_cs_parser { unsigned idx; /* relocations */ unsigned nrelocs; - struct radeon_cs_reloc *relocs; - struct radeon_cs_reloc **relocs_ptr; - struct radeon_cs_reloc *vm_bos; + struct radeon_bo_list *relocs; + struct radeon_bo_list **relocs_ptr; + struct radeon_bo_list *vm_bos; struct list_head validated; unsigned dma_reloc_idx; /* indices of various chunks */ @@ -2973,7 +2973,7 @@ int radeon_vm_manager_init(struct radeon_device *rdev); void radeon_vm_manager_fini(struct radeon_device *rdev); int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); -struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, +struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev, struct radeon_vm *vm, struct list_head *head); struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, @@ -3087,7 +3087,7 @@ bool radeon_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p); void radeon_cs_dump_packet(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt); int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc, + struct radeon_bo_list **cs_reloc, int nomm); int r600_cs_common_vline_parse(struct radeon_cs_parser *p, uint32_t *vline_start_end, diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index f1f584a..fb776cb 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -92,7 +92,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) if (p->relocs_ptr == NULL) { return -ENOMEM; } - p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_cs_reloc), GFP_KERNEL); + p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_bo_list), GFP_KERNEL); if (p->relocs == NULL) { return -ENOMEM; } @@ -251,7 +251,7 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority
static int radeon_cs_sync_rings(struct radeon_cs_parser *p) { - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; int r;
list_for_each_entry(reloc, &p->validated, tv.head) { @@ -397,8 +397,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) static int cmp_size_smaller_first(void *priv, struct list_head *a, struct list_head *b) { - struct radeon_cs_reloc *la = list_entry(a, struct radeon_cs_reloc, tv.head); - struct radeon_cs_reloc *lb = list_entry(b, struct radeon_cs_reloc, tv.head); + struct radeon_bo_list *la = list_entry(a, struct radeon_bo_list, tv.head); + struct radeon_bo_list *lb = list_entry(b, struct radeon_bo_list, tv.head);
/* Sort A before B if A is smaller. */ return (int)la->robj->tbo.num_pages - (int)lb->robj->tbo.num_pages; @@ -832,7 +832,7 @@ void radeon_cs_dump_packet(struct radeon_cs_parser *p, * GPU offset using the provided start. **/ int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc, + struct radeon_bo_list **cs_reloc, int nomm) { struct radeon_cs_chunk *relocs_chunk; diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 12cfaea..6162bd2 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -548,7 +548,7 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, struct radeon_bo_va *bo_va) { struct ttm_validate_buffer tv, *entry; - struct radeon_cs_reloc *vm_bos; + struct radeon_bo_list *vm_bos; struct ww_acquire_ctx ticket; struct list_head list; unsigned domain; diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 87b00d9..4ab0747 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -502,7 +502,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev, struct ww_acquire_ctx *ticket, struct list_head *head, int ring) { - struct radeon_cs_reloc *lobj; + struct radeon_bo_list *lobj; struct radeon_bo *bo; int r; u64 bytes_moved = 0, initial_bytes_moved; diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 11b6624..7c22b93 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -488,7 +488,7 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, unsigned buf_sizes[], bool *has_msg_cmd) { struct radeon_cs_chunk *relocs_chunk; - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; unsigned idx, cmd, offset; uint64_t start, end; int r; diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c index 9e85757..8b4eea4 100644 --- a/drivers/gpu/drm/radeon/radeon_vce.c +++ b/drivers/gpu/drm/radeon/radeon_vce.c @@ -453,7 +453,7 @@ int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi, unsigned size) { struct radeon_cs_chunk *relocs_chunk; - struct radeon_cs_reloc *reloc; + struct radeon_bo_list *reloc; uint64_t start, end, offset; unsigned idx;
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index c4ffe02..0423e29 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -125,15 +125,15 @@ void radeon_vm_manager_fini(struct radeon_device *rdev) * Add the page directory to the list of BOs to * validate for command submission (cayman+). */ -struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, +struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev, struct radeon_vm *vm, struct list_head *head) { - struct radeon_cs_reloc *list; + struct radeon_bo_list *list; unsigned i, idx;
list = drm_malloc_ab(vm->max_pde_used + 2, - sizeof(struct radeon_cs_reloc)); + sizeof(struct radeon_bo_list)); if (!list) return NULL;
From: Christian König christian.koenig@amd.com
The BO_VA contains everything necessary.
Signed-off-by: Christian König christian.koenig@amd.com --- drivers/gpu/drm/radeon/radeon_vm.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 0423e29..6bc3821 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -798,11 +798,11 @@ static void radeon_vm_frag_ptes(struct radeon_device *rdev, * * Global and local mutex must be locked! */ -static void radeon_vm_update_ptes(struct radeon_device *rdev, - struct radeon_vm *vm, - struct radeon_ib *ib, - uint64_t start, uint64_t end, - uint64_t dst, uint32_t flags) +static int radeon_vm_update_ptes(struct radeon_device *rdev, + struct radeon_vm *vm, + struct radeon_ib *ib, + uint64_t start, uint64_t end, + uint64_t dst, uint32_t flags) { uint64_t mask = RADEON_VM_PTE_COUNT - 1; uint64_t last_pte = ~0, last_dst = ~0; @@ -815,8 +815,12 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, struct radeon_bo *pt = vm->page_tables[pt_idx].bo; unsigned nptes; uint64_t pte; + int r;
radeon_sync_resv(rdev, &ib->sync, pt->tbo.resv, true); + r = reservation_object_reserve_shared(pt->tbo.resv); + if (r) + return r;
if ((addr & ~mask) == (end & ~mask)) nptes = end - addr; @@ -850,6 +854,8 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, last_pte + 8 * count, last_dst, flags); } + + return 0; }
/** @@ -874,7 +880,7 @@ static void radeon_vm_fence_pts(struct radeon_vm *vm, end >>= radeon_vm_block_size;
for (i = start; i <= end; ++i) - radeon_bo_fence(vm->page_tables[i].bo, fence, false); + radeon_bo_fence(vm->page_tables[i].bo, fence, true); }
/** @@ -983,9 +989,13 @@ int radeon_vm_bo_update(struct radeon_device *rdev, radeon_sync_fence(&ib.sync, vm->ids[i].last_id_use); }
- radeon_vm_update_ptes(rdev, vm, &ib, bo_va->it.start, - bo_va->it.last + 1, addr, - radeon_vm_page_flags(bo_va->flags)); + r = radeon_vm_update_ptes(rdev, vm, &ib, bo_va->it.start, + bo_va->it.last + 1, addr, + radeon_vm_page_flags(bo_va->flags)); + if (r) { + radeon_ib_free(rdev, &ib); + return r; + }
radeon_asic_vm_pad_ib(rdev, &ib); WARN_ON(ib.length_dw > ndw);
From: Christian König christian.koenig@amd.com
Stop using the VM mutex for this
Signed-off-by: Christian König christian.koenig@amd.com --- drivers/gpu/drm/radeon/radeon.h | 3 +++ drivers/gpu/drm/radeon/radeon_vm.c | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index da1c549..3680cf0 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -929,6 +929,9 @@ struct radeon_vm {
struct rb_root va;
+ /* ptotecting invalidated and freed */ + spinlock_t status_lock; + /* BOs moved, but not yet updated in the PT */ struct list_head invalidated;
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 6bc3821..cde48c4 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -487,7 +487,9 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, tmp->vm = vm; tmp->addr = bo_va->addr; tmp->bo = radeon_bo_ref(bo_va->bo); + spin_lock(&vm->status_lock); list_add(&tmp->vm_status, &vm->freed); + spin_unlock(&vm->status_lock); }
interval_tree_remove(&bo_va->it, &vm->va); @@ -913,7 +915,9 @@ int radeon_vm_bo_update(struct radeon_device *rdev, return -EINVAL; }
+ spin_lock(&vm->status_lock); list_del_init(&bo_va->vm_status); + spin_unlock(&vm->status_lock);
bo_va->flags &= ~RADEON_VM_PAGE_VALID; bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; @@ -1028,17 +1032,25 @@ int radeon_vm_bo_update(struct radeon_device *rdev, int radeon_vm_clear_freed(struct radeon_device *rdev, struct radeon_vm *vm) { - struct radeon_bo_va *bo_va, *tmp; + struct radeon_bo_va *bo_va; int r;
- list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { + spin_lock(&vm->status_lock); + while (!list_empty(&vm->freed)) { + bo_va = list_first_entry(&vm->freed, + struct radeon_bo_va, vm_status); + spin_unlock(&vm->status_lock); + r = radeon_vm_bo_update(rdev, bo_va, NULL); radeon_bo_unref(&bo_va->bo); radeon_fence_unref(&bo_va->last_pt_update); kfree(bo_va); if (r) return r; + + spin_lock(&vm->status_lock); } + spin_unlock(&vm->status_lock); return 0;
} @@ -1057,14 +1069,23 @@ int radeon_vm_clear_freed(struct radeon_device *rdev, int radeon_vm_clear_invalids(struct radeon_device *rdev, struct radeon_vm *vm) { - struct radeon_bo_va *bo_va, *tmp; + struct radeon_bo_va *bo_va; int r;
- list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, vm_status) { + spin_lock(&vm->status_lock); + while (!list_empty(&vm->invalidated)) { + bo_va = list_first_entry(&vm->invalidated, + struct radeon_bo_va, vm_status); + spin_unlock(&vm->status_lock); + r = radeon_vm_bo_update(rdev, bo_va, NULL); if (r) return r; + + spin_lock(&vm->status_lock); } + spin_unlock(&vm->status_lock); + return 0; }
@@ -1087,6 +1108,7 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev,
mutex_lock(&vm->mutex); interval_tree_remove(&bo_va->it, &vm->va); + spin_lock(&vm->status_lock); list_del(&bo_va->vm_status);
if (bo_va->addr) { @@ -1096,6 +1118,7 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev, radeon_fence_unref(&bo_va->last_pt_update); kfree(bo_va); } + spin_unlock(&vm->status_lock);
mutex_unlock(&vm->mutex); } @@ -1116,10 +1139,10 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev,
list_for_each_entry(bo_va, &bo->va, bo_list) { if (bo_va->addr) { - mutex_lock(&bo_va->vm->mutex); + spin_lock(&bo_va->vm->status_lock); list_del(&bo_va->vm_status); list_add(&bo_va->vm_status, &bo_va->vm->invalidated); - mutex_unlock(&bo_va->vm->mutex); + spin_unlock(&bo_va->vm->status_lock); } } } @@ -1147,6 +1170,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) } mutex_init(&vm->mutex); vm->va = RB_ROOT; + spin_lock_init(&vm->status_lock); INIT_LIST_HEAD(&vm->invalidated); INIT_LIST_HEAD(&vm->freed);
Am 27.11.2014 14:48, schrieb Christian König:
From: Christian König christian.koenig@amd.com
Stop using the VM mutex for this
Signed-off-by: Christian König christian.koenig@amd.com
drivers/gpu/drm/radeon/radeon.h | 3 +++ drivers/gpu/drm/radeon/radeon_vm.c | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index da1c549..3680cf0 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -929,6 +929,9 @@ struct radeon_vm {
struct rb_root va;
- /* ptotecting invalidated and freed */
protecting
- spinlock_t status_lock;
- /* BOs moved, but not yet updated in the PT */ struct list_head invalidated;
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 6bc3821..cde48c4 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -487,7 +487,9 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, tmp->vm = vm; tmp->addr = bo_va->addr; tmp->bo = radeon_bo_ref(bo_va->bo);
spin_lock(&vm->status_lock); list_add(&tmp->vm_status, &vm->freed);
spin_unlock(&vm->status_lock);
}
interval_tree_remove(&bo_va->it, &vm->va);
@@ -913,7 +915,9 @@ int radeon_vm_bo_update(struct radeon_device *rdev, return -EINVAL; }
spin_lock(&vm->status_lock); list_del_init(&bo_va->vm_status);
spin_unlock(&vm->status_lock);
bo_va->flags &= ~RADEON_VM_PAGE_VALID; bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM;
@@ -1028,17 +1032,25 @@ int radeon_vm_bo_update(struct radeon_device *rdev, int radeon_vm_clear_freed(struct radeon_device *rdev, struct radeon_vm *vm) {
- struct radeon_bo_va *bo_va, *tmp;
- struct radeon_bo_va *bo_va; int r;
- list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) {
- spin_lock(&vm->status_lock);
- while (!list_empty(&vm->freed)) {
bo_va = list_first_entry(&vm->freed,
struct radeon_bo_va, vm_status);
spin_unlock(&vm->status_lock);
- r = radeon_vm_bo_update(rdev, bo_va, NULL); radeon_bo_unref(&bo_va->bo); radeon_fence_unref(&bo_va->last_pt_update); kfree(bo_va); if (r) return r;
}spin_lock(&vm->status_lock);
- spin_unlock(&vm->status_lock); return 0;
} @@ -1057,14 +1069,23 @@ int radeon_vm_clear_freed(struct radeon_device *rdev, int radeon_vm_clear_invalids(struct radeon_device *rdev, struct radeon_vm *vm) {
- struct radeon_bo_va *bo_va, *tmp;
- struct radeon_bo_va *bo_va; int r;
- list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, vm_status) {
- spin_lock(&vm->status_lock);
- while (!list_empty(&vm->invalidated)) {
bo_va = list_first_entry(&vm->invalidated,
struct radeon_bo_va, vm_status);
spin_unlock(&vm->status_lock);
- r = radeon_vm_bo_update(rdev, bo_va, NULL); if (r) return r;
}spin_lock(&vm->status_lock);
- spin_unlock(&vm->status_lock);
- return 0;
}
@@ -1087,6 +1108,7 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev,
mutex_lock(&vm->mutex); interval_tree_remove(&bo_va->it, &vm->va);
spin_lock(&vm->status_lock); list_del(&bo_va->vm_status);
if (bo_va->addr) {
@@ -1096,6 +1118,7 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev, radeon_fence_unref(&bo_va->last_pt_update); kfree(bo_va); }
spin_unlock(&vm->status_lock);
mutex_unlock(&vm->mutex);
} @@ -1116,10 +1139,10 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev,
list_for_each_entry(bo_va, &bo->va, bo_list) { if (bo_va->addr) {
mutex_lock(&bo_va->vm->mutex);
spin_lock(&bo_va->vm->status_lock); list_del(&bo_va->vm_status); list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
mutex_unlock(&bo_va->vm->mutex);
} }spin_unlock(&bo_va->vm->status_lock);
} @@ -1147,6 +1170,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) } mutex_init(&vm->mutex); vm->va = RB_ROOT;
- spin_lock_init(&vm->status_lock); INIT_LIST_HEAD(&vm->invalidated); INIT_LIST_HEAD(&vm->freed);
From: Christian König christian.koenig@amd.com
Signed-off-by: Christian König christian.koenig@amd.com --- drivers/gpu/drm/radeon/radeon.h | 2 +- drivers/gpu/drm/radeon/radeon_cs.c | 9 +++++-- drivers/gpu/drm/radeon/radeon_gem.c | 17 ++++++++++---- drivers/gpu/drm/radeon/radeon_kms.c | 5 ++++ drivers/gpu/drm/radeon/radeon_vm.c | 47 +++++++++---------------------------- 5 files changed, 36 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3680cf0..699446a 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -925,7 +925,7 @@ struct radeon_vm_id { };
struct radeon_vm { - struct mutex mutex; + struct mutex lock;
struct rb_root va;
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index fb776cb..7a90378 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -195,6 +195,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) if (p->cs_flags & RADEON_CS_USE_VM) p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm, &p->validated); + if (need_mmap_lock) down_read(¤t->mm->mmap_sem);
@@ -571,7 +572,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, if (parser->ring == R600_RING_TYPE_UVD_INDEX) radeon_uvd_note_usage(rdev);
- mutex_lock(&vm->mutex); r = radeon_bo_vm_update_pte(parser, vm); if (r) { goto out; @@ -592,7 +592,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, }
out: - mutex_unlock(&vm->mutex); return r; }
@@ -696,6 +695,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) }
r = radeon_cs_ib_fill(rdev, &parser); + if (parser.cs_flags & RADEON_CS_USE_VM) + mutex_lock(&parser.ib.vm->lock); if (!r) { r = radeon_cs_parser_relocs(&parser); if (r && r != -ERESTARTSYS) @@ -704,6 +705,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
if (r) { radeon_cs_parser_fini(&parser, r, false); + if (parser.cs_flags & RADEON_CS_USE_VM) + mutex_unlock(&parser.ib.vm->lock); up_read(&rdev->exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r; @@ -721,6 +724,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) } out: radeon_cs_parser_fini(&parser, r, true); + if (parser.cs_flags & RADEON_CS_USE_VM) + mutex_unlock(&parser.ib.vm->lock); up_read(&rdev->exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r; diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 6162bd2..4eafec6 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -150,8 +150,10 @@ int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri return 0; }
+ mutex_lock(&vm->lock); r = radeon_bo_reserve(rbo, false); if (r) { + mutex_unlock(&vm->lock); return r; }
@@ -162,6 +164,7 @@ int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri ++bo_va->ref_count; } radeon_bo_unreserve(rbo); + mutex_unlock(&vm->lock);
return 0; } @@ -180,8 +183,10 @@ void radeon_gem_object_close(struct drm_gem_object *obj, return; }
+ mutex_lock(&vm->lock); r = radeon_bo_reserve(rbo, true); if (r) { + mutex_unlock(&vm->lock); dev_err(rdev->dev, "leaking bo va because " "we fail to reserve bo (%d)\n", r); return; @@ -193,6 +198,7 @@ void radeon_gem_object_close(struct drm_gem_object *obj, } } radeon_bo_unreserve(rbo); + mutex_unlock(&vm->lock); }
static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r) @@ -576,17 +582,13 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, goto error_unreserve; }
- mutex_lock(&bo_va->vm->mutex); r = radeon_vm_clear_freed(rdev, bo_va->vm); if (r) - goto error_unlock; + goto error_unreserve;
if (bo_va->it.start) r = radeon_vm_bo_update(rdev, bo_va, &bo_va->bo->tbo.mem);
-error_unlock: - mutex_unlock(&bo_va->vm->mutex); - error_unreserve: ttm_eu_backoff_reservation(&ticket, &list);
@@ -662,14 +664,18 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, return -ENOENT; } rbo = gem_to_radeon_bo(gobj); + mutex_lock(&fpriv->vm.lock); r = radeon_bo_reserve(rbo, false); if (r) { + mutex_unlock(&fpriv->vm.lock); args->operation = RADEON_VA_RESULT_ERROR; drm_gem_object_unreference_unlocked(gobj); return r; } bo_va = radeon_vm_bo_find(&fpriv->vm, rbo); if (!bo_va) { + radeon_bo_unreserve(rbo); + mutex_unlock(&fpriv->vm.lock); args->operation = RADEON_VA_RESULT_ERROR; drm_gem_object_unreference_unlocked(gobj); return -ENOENT; @@ -698,6 +704,7 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, args->operation = RADEON_VA_RESULT_ERROR; } out: + mutex_unlock(&fpriv->vm.lock); drm_gem_object_unreference_unlocked(gobj); return r; } diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index f4dd26a..d994006 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -613,8 +613,10 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) }
if (rdev->accel_working) { + mutex_lock(&vm->lock); r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); if (r) { + mutex_unlock(&vm->lock); radeon_vm_fini(rdev, vm); kfree(fpriv); return r; @@ -628,6 +630,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) RADEON_VA_IB_OFFSET, RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_SNOOPED); + mutex_unlock(&vm->lock); if (r) { radeon_vm_fini(rdev, vm); kfree(fpriv); @@ -662,12 +665,14 @@ void radeon_driver_postclose_kms(struct drm_device *dev, int r;
if (rdev->accel_working) { + mutex_lock(&vm->lock); r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); if (!r) { if (vm->ib_bo_va) radeon_vm_bo_rmv(rdev, vm->ib_bo_va); radeon_bo_unreserve(rdev->ring_tmp_bo.bo); } + mutex_unlock(&vm->lock); }
radeon_vm_fini(rdev, vm); diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index cde48c4..658183f 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -172,7 +172,7 @@ struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev, * Allocate an id for the vm (cayman+). * Returns the fence we need to sync to (if any). * - * Global and local mutex must be locked! + * Mutex must be locked! */ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, struct radeon_vm *vm, int ring) @@ -231,7 +231,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, * * Flush the vm (cayman+). * - * Global and local mutex must be locked! + * Mutex must be locked! */ void radeon_vm_flush(struct radeon_device *rdev, struct radeon_vm *vm, @@ -263,7 +263,7 @@ void radeon_vm_flush(struct radeon_device *rdev, * Fence the vm (cayman+). * Set the fence used to protect page table and id. * - * Global and local mutex must be locked! + * Mutex must be locked! */ void radeon_vm_fence(struct radeon_device *rdev, struct radeon_vm *vm, @@ -314,7 +314,7 @@ struct radeon_bo_va *radeon_vm_bo_find(struct radeon_vm *vm, * Add @bo to the list of bos associated with the vm * Returns newly added bo_va or NULL for failure * - * Object has to be reserved! + * Mutex must be locked and object has to be reserved! */ struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev, struct radeon_vm *vm, @@ -336,9 +336,7 @@ struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev, INIT_LIST_HEAD(&bo_va->bo_list); INIT_LIST_HEAD(&bo_va->vm_status);
- mutex_lock(&vm->mutex); list_add_tail(&bo_va->bo_list, &bo->va); - mutex_unlock(&vm->mutex);
return bo_va; } @@ -441,7 +439,8 @@ error_unreserve: * Validate and set the offset requested within the vm address space. * Returns 0 for success, error for failure. * - * Object has to be reserved and gets unreserved by this function! + * Mutex must be locked and object has to be reserved and gets + * unreserved by this function! */ int radeon_vm_bo_set_addr(struct radeon_device *rdev, struct radeon_bo_va *bo_va, @@ -472,14 +471,12 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, eoffset = last_pfn = 0; }
- mutex_lock(&vm->mutex); if (bo_va->it.start || bo_va->it.last) { if (bo_va->addr) { /* add a clone of the bo_va to clear the old address */ struct radeon_bo_va *tmp; tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); if (!tmp) { - mutex_unlock(&vm->mutex); return -ENOMEM; } tmp->it.start = bo_va->it.start; @@ -509,7 +506,6 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, dev_err(rdev->dev, "bo %p va 0x%010Lx conflict with " "(bo %p 0x%010lx 0x%010lx)\n", bo_va->bo, soffset, tmp->bo, tmp->it.start, tmp->it.last); - mutex_unlock(&vm->mutex); return -EINVAL; } bo_va->it.start = soffset; @@ -537,9 +533,6 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, if (vm->page_tables[pt_idx].bo) continue;
- /* drop mutex to allocate and clear page table */ - mutex_unlock(&vm->mutex); - r = radeon_bo_create(rdev, RADEON_VM_PTE_COUNT * 8, RADEON_GPU_PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, 0, @@ -554,21 +547,10 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, return r; }
- /* aquire mutex again */ - mutex_lock(&vm->mutex); - if (vm->page_tables[pt_idx].bo) { - /* someone else allocated the pt in the meantime */ - mutex_unlock(&vm->mutex); - radeon_bo_unref(&pt); - mutex_lock(&vm->mutex); - continue; - } - vm->page_tables[pt_idx].addr = 0; vm->page_tables[pt_idx].bo = pt; }
- mutex_unlock(&vm->mutex); return 0; }
@@ -627,7 +609,7 @@ static uint32_t radeon_vm_page_flags(uint32_t flags) * and updates the page directory (cayman+). * Returns 0 for success, error for failure. * - * Global and local mutex must be locked! + * Mutex must be locked! */ int radeon_vm_update_page_directory(struct radeon_device *rdev, struct radeon_vm *vm) @@ -717,8 +699,6 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, * @pe_end: last PTE to handle * @addr: addr those PTEs should point to * @flags: hw mapping flags - * - * Global and local mutex must be locked! */ static void radeon_vm_frag_ptes(struct radeon_device *rdev, struct radeon_ib *ib, @@ -798,7 +778,6 @@ static void radeon_vm_frag_ptes(struct radeon_device *rdev, * * Update the page tables in the range @start - @end (cayman+). * - * Global and local mutex must be locked! */ static int radeon_vm_update_ptes(struct radeon_device *rdev, struct radeon_vm *vm, @@ -870,7 +849,6 @@ static int radeon_vm_update_ptes(struct radeon_device *rdev, * * Fence the page tables in the range @start - @end (cayman+). * - * Global and local mutex must be locked! */ static void radeon_vm_fence_pts(struct radeon_vm *vm, uint64_t start, uint64_t end, @@ -896,7 +874,7 @@ static void radeon_vm_fence_pts(struct radeon_vm *vm, * Fill in the page table entries for @bo (cayman+). * Returns 0 for success, -EINVAL for failure. * - * Object have to be reserved and mutex must be locked! + * Mutex must be locked and BOs have to be reserved! */ int radeon_vm_bo_update(struct radeon_device *rdev, struct radeon_bo_va *bo_va, @@ -1097,7 +1075,7 @@ int radeon_vm_clear_invalids(struct radeon_device *rdev, * * Remove @bo_va->bo from the requested vm (cayman+). * - * Object have to be reserved! + * Mutex must be locked and object has to be reserved! */ void radeon_vm_bo_rmv(struct radeon_device *rdev, struct radeon_bo_va *bo_va) @@ -1106,7 +1084,6 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev,
list_del(&bo_va->bo_list);
- mutex_lock(&vm->mutex); interval_tree_remove(&bo_va->it, &vm->va); spin_lock(&vm->status_lock); list_del(&bo_va->vm_status); @@ -1119,8 +1096,6 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev, kfree(bo_va); } spin_unlock(&vm->status_lock); - - mutex_unlock(&vm->mutex); }
/** @@ -1168,7 +1143,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) vm->ids[i].flushed_updates = NULL; vm->ids[i].last_id_use = NULL; } - mutex_init(&vm->mutex); + mutex_init(&vm->lock); vm->va = RB_ROOT; spin_lock_init(&vm->status_lock); INIT_LIST_HEAD(&vm->invalidated); @@ -1245,5 +1220,5 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) radeon_fence_unref(&vm->ids[i].last_id_use); }
- mutex_destroy(&vm->mutex); + mutex_destroy(&vm->lock); }
Ah, crap. Drop the last two, they are still work in progress.
I was on the wrong branch while sending them, Christian.
Am 27.11.2014 um 14:48 schrieb Christian König:
From: Christian König christian.koenig@amd.com
Signed-off-by: Christian König christian.koenig@amd.com
drivers/gpu/drm/radeon/radeon.h | 2 +- drivers/gpu/drm/radeon/radeon_cs.c | 9 +++++-- drivers/gpu/drm/radeon/radeon_gem.c | 17 ++++++++++---- drivers/gpu/drm/radeon/radeon_kms.c | 5 ++++ drivers/gpu/drm/radeon/radeon_vm.c | 47 +++++++++---------------------------- 5 files changed, 36 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3680cf0..699446a 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -925,7 +925,7 @@ struct radeon_vm_id { };
struct radeon_vm {
- struct mutex mutex;
struct mutex lock;
struct rb_root va;
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index fb776cb..7a90378 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -195,6 +195,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) if (p->cs_flags & RADEON_CS_USE_VM) p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm, &p->validated);
- if (need_mmap_lock) down_read(¤t->mm->mmap_sem);
@@ -571,7 +572,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, if (parser->ring == R600_RING_TYPE_UVD_INDEX) radeon_uvd_note_usage(rdev);
- mutex_lock(&vm->mutex); r = radeon_bo_vm_update_pte(parser, vm); if (r) { goto out;
@@ -592,7 +592,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, }
out:
- mutex_unlock(&vm->mutex); return r; }
@@ -696,6 +695,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) }
r = radeon_cs_ib_fill(rdev, &parser);
- if (parser.cs_flags & RADEON_CS_USE_VM)
if (!r) { r = radeon_cs_parser_relocs(&parser); if (r && r != -ERESTARTSYS)mutex_lock(&parser.ib.vm->lock);
@@ -704,6 +705,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
if (r) { radeon_cs_parser_fini(&parser, r, false);
if (parser.cs_flags & RADEON_CS_USE_VM)
up_read(&rdev->exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r;mutex_unlock(&parser.ib.vm->lock);
@@ -721,6 +724,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) } out: radeon_cs_parser_fini(&parser, r, true);
- if (parser.cs_flags & RADEON_CS_USE_VM)
up_read(&rdev->exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r;mutex_unlock(&parser.ib.vm->lock);
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 6162bd2..4eafec6 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -150,8 +150,10 @@ int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri return 0; }
- mutex_lock(&vm->lock); r = radeon_bo_reserve(rbo, false); if (r) {
return r; }mutex_unlock(&vm->lock);
@@ -162,6 +164,7 @@ int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri ++bo_va->ref_count; } radeon_bo_unreserve(rbo);
mutex_unlock(&vm->lock);
return 0; }
@@ -180,8 +183,10 @@ void radeon_gem_object_close(struct drm_gem_object *obj, return; }
- mutex_lock(&vm->lock); r = radeon_bo_reserve(rbo, true); if (r) {
dev_err(rdev->dev, "leaking bo va because " "we fail to reserve bo (%d)\n", r); return;mutex_unlock(&vm->lock);
@@ -193,6 +198,7 @@ void radeon_gem_object_close(struct drm_gem_object *obj, } } radeon_bo_unreserve(rbo);
mutex_unlock(&vm->lock); }
static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r)
@@ -576,17 +582,13 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, goto error_unreserve; }
- mutex_lock(&bo_va->vm->mutex); r = radeon_vm_clear_freed(rdev, bo_va->vm); if (r)
goto error_unlock;
goto error_unreserve;
if (bo_va->it.start) r = radeon_vm_bo_update(rdev, bo_va, &bo_va->bo->tbo.mem);
-error_unlock:
- mutex_unlock(&bo_va->vm->mutex);
- error_unreserve: ttm_eu_backoff_reservation(&ticket, &list);
@@ -662,14 +664,18 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, return -ENOENT; } rbo = gem_to_radeon_bo(gobj);
- mutex_lock(&fpriv->vm.lock); r = radeon_bo_reserve(rbo, false); if (r) {
args->operation = RADEON_VA_RESULT_ERROR; drm_gem_object_unreference_unlocked(gobj); return r; } bo_va = radeon_vm_bo_find(&fpriv->vm, rbo); if (!bo_va) {mutex_unlock(&fpriv->vm.lock);
radeon_bo_unreserve(rbo);
args->operation = RADEON_VA_RESULT_ERROR; drm_gem_object_unreference_unlocked(gobj); return -ENOENT;mutex_unlock(&fpriv->vm.lock);
@@ -698,6 +704,7 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, args->operation = RADEON_VA_RESULT_ERROR; } out:
- mutex_unlock(&fpriv->vm.lock); drm_gem_object_unreference_unlocked(gobj); return r; }
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index f4dd26a..d994006 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -613,8 +613,10 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) }
if (rdev->accel_working) {
mutex_lock(&vm->lock); r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); if (r) {
mutex_unlock(&vm->lock); radeon_vm_fini(rdev, vm); kfree(fpriv); return r;
@@ -628,6 +630,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) RADEON_VA_IB_OFFSET, RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_SNOOPED);
mutex_unlock(&vm->lock); if (r) { radeon_vm_fini(rdev, vm); kfree(fpriv);
@@ -662,12 +665,14 @@ void radeon_driver_postclose_kms(struct drm_device *dev, int r;
if (rdev->accel_working) {
mutex_lock(&vm->lock); r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); if (!r) { if (vm->ib_bo_va) radeon_vm_bo_rmv(rdev, vm->ib_bo_va); radeon_bo_unreserve(rdev->ring_tmp_bo.bo); }
mutex_unlock(&vm->lock);
}
radeon_vm_fini(rdev, vm);
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index cde48c4..658183f 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -172,7 +172,7 @@ struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev,
- Allocate an id for the vm (cayman+).
- Returns the fence we need to sync to (if any).
- Global and local mutex must be locked!
*/ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, struct radeon_vm *vm, int ring)
- Mutex must be locked!
@@ -231,7 +231,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
- Flush the vm (cayman+).
- Global and local mutex must be locked!
*/ void radeon_vm_flush(struct radeon_device *rdev, struct radeon_vm *vm,
- Mutex must be locked!
@@ -263,7 +263,7 @@ void radeon_vm_flush(struct radeon_device *rdev,
- Fence the vm (cayman+).
- Set the fence used to protect page table and id.
- Global and local mutex must be locked!
*/ void radeon_vm_fence(struct radeon_device *rdev, struct radeon_vm *vm,
- Mutex must be locked!
@@ -314,7 +314,7 @@ struct radeon_bo_va *radeon_vm_bo_find(struct radeon_vm *vm,
- Add @bo to the list of bos associated with the vm
- Returns newly added bo_va or NULL for failure
- Object has to be reserved!
*/ struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev, struct radeon_vm *vm,
- Mutex must be locked and object has to be reserved!
@@ -336,9 +336,7 @@ struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev, INIT_LIST_HEAD(&bo_va->bo_list); INIT_LIST_HEAD(&bo_va->vm_status);
mutex_lock(&vm->mutex); list_add_tail(&bo_va->bo_list, &bo->va);
mutex_unlock(&vm->mutex);
return bo_va; }
@@ -441,7 +439,8 @@ error_unreserve:
- Validate and set the offset requested within the vm address space.
- Returns 0 for success, error for failure.
- Object has to be reserved and gets unreserved by this function!
- Mutex must be locked and object has to be reserved and gets
*/ int radeon_vm_bo_set_addr(struct radeon_device *rdev, struct radeon_bo_va *bo_va,
- unreserved by this function!
@@ -472,14 +471,12 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, eoffset = last_pfn = 0; }
- mutex_lock(&vm->mutex); if (bo_va->it.start || bo_va->it.last) { if (bo_va->addr) { /* add a clone of the bo_va to clear the old address */ struct radeon_bo_va *tmp; tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); if (!tmp) {
mutex_unlock(&vm->mutex); return -ENOMEM; } tmp->it.start = bo_va->it.start;
@@ -509,7 +506,6 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, dev_err(rdev->dev, "bo %p va 0x%010Lx conflict with " "(bo %p 0x%010lx 0x%010lx)\n", bo_va->bo, soffset, tmp->bo, tmp->it.start, tmp->it.last);
} bo_va->it.start = soffset;mutex_unlock(&vm->mutex); return -EINVAL;
@@ -537,9 +533,6 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, if (vm->page_tables[pt_idx].bo) continue;
/* drop mutex to allocate and clear page table */
mutex_unlock(&vm->mutex);
- r = radeon_bo_create(rdev, RADEON_VM_PTE_COUNT * 8, RADEON_GPU_PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, 0,
@@ -554,21 +547,10 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, return r; }
/* aquire mutex again */
mutex_lock(&vm->mutex);
if (vm->page_tables[pt_idx].bo) {
/* someone else allocated the pt in the meantime */
mutex_unlock(&vm->mutex);
radeon_bo_unref(&pt);
mutex_lock(&vm->mutex);
continue;
}
vm->page_tables[pt_idx].addr = 0; vm->page_tables[pt_idx].bo = pt; }
mutex_unlock(&vm->mutex); return 0; }
@@ -627,7 +609,7 @@ static uint32_t radeon_vm_page_flags(uint32_t flags)
- and updates the page directory (cayman+).
- Returns 0 for success, error for failure.
- Global and local mutex must be locked!
*/ int radeon_vm_update_page_directory(struct radeon_device *rdev, struct radeon_vm *vm)
- Mutex must be locked!
@@ -717,8 +699,6 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
- @pe_end: last PTE to handle
- @addr: addr those PTEs should point to
- @flags: hw mapping flags
*/ static void radeon_vm_frag_ptes(struct radeon_device *rdev, struct radeon_ib *ib,
- Global and local mutex must be locked!
@@ -798,7 +778,6 @@ static void radeon_vm_frag_ptes(struct radeon_device *rdev,
- Update the page tables in the range @start - @end (cayman+).
*/ static int radeon_vm_update_ptes(struct radeon_device *rdev, struct radeon_vm *vm,
- Global and local mutex must be locked!
@@ -870,7 +849,6 @@ static int radeon_vm_update_ptes(struct radeon_device *rdev,
- Fence the page tables in the range @start - @end (cayman+).
*/ static void radeon_vm_fence_pts(struct radeon_vm *vm, uint64_t start, uint64_t end,
- Global and local mutex must be locked!
@@ -896,7 +874,7 @@ static void radeon_vm_fence_pts(struct radeon_vm *vm,
- Fill in the page table entries for @bo (cayman+).
- Returns 0 for success, -EINVAL for failure.
- Object have to be reserved and mutex must be locked!
*/ int radeon_vm_bo_update(struct radeon_device *rdev, struct radeon_bo_va *bo_va,
- Mutex must be locked and BOs have to be reserved!
@@ -1097,7 +1075,7 @@ int radeon_vm_clear_invalids(struct radeon_device *rdev,
- Remove @bo_va->bo from the requested vm (cayman+).
- Object have to be reserved!
*/ void radeon_vm_bo_rmv(struct radeon_device *rdev, struct radeon_bo_va *bo_va)
- Mutex must be locked and object has to be reserved!
@@ -1106,7 +1084,6 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev,
list_del(&bo_va->bo_list);
- mutex_lock(&vm->mutex); interval_tree_remove(&bo_va->it, &vm->va); spin_lock(&vm->status_lock); list_del(&bo_va->vm_status);
@@ -1119,8 +1096,6 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev, kfree(bo_va); } spin_unlock(&vm->status_lock);
mutex_unlock(&vm->mutex); }
/**
@@ -1168,7 +1143,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) vm->ids[i].flushed_updates = NULL; vm->ids[i].last_id_use = NULL; }
- mutex_init(&vm->mutex);
- mutex_init(&vm->lock); vm->va = RB_ROOT; spin_lock_init(&vm->status_lock); INIT_LIST_HEAD(&vm->invalidated);
@@ -1245,5 +1220,5 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) radeon_fence_unref(&vm->ids[i].last_id_use); }
- mutex_destroy(&vm->mutex);
- mutex_destroy(&vm->lock); }
On Thu, Nov 27, 2014 at 9:06 AM, Christian König deathsimple@vodafone.de wrote:
Ah, crap. Drop the last two, they are still work in progress.
I was on the wrong branch while sending them,
Added 1-5 to my -next branch including fixing the spelling in the comment in patch 5.
Thanks,
Alex
Christian.
Am 27.11.2014 um 14:48 schrieb Christian König:
From: Christian König christian.koenig@amd.com
Signed-off-by: Christian König christian.koenig@amd.com
drivers/gpu/drm/radeon/radeon.h | 2 +- drivers/gpu/drm/radeon/radeon_cs.c | 9 +++++-- drivers/gpu/drm/radeon/radeon_gem.c | 17 ++++++++++---- drivers/gpu/drm/radeon/radeon_kms.c | 5 ++++ drivers/gpu/drm/radeon/radeon_vm.c | 47 +++++++++---------------------------- 5 files changed, 36 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3680cf0..699446a 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -925,7 +925,7 @@ struct radeon_vm_id { }; struct radeon_vm {
struct mutex mutex;
diff --git a/drivers/gpu/drm/radeon/radeon_cs.cstruct mutex lock; struct rb_root va;
b/drivers/gpu/drm/radeon/radeon_cs.c index fb776cb..7a90378 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -195,6 +195,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) if (p->cs_flags & RADEON_CS_USE_VM) p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm, &p->validated);
@@ -571,7 +572,6 @@ static int radeon_cs_ib_vm_chunk(structif (need_mmap_lock) down_read(¤t->mm->mmap_sem);
radeon_device *rdev, if (parser->ring == R600_RING_TYPE_UVD_INDEX) radeon_uvd_note_usage(rdev);
mutex_lock(&vm->mutex); r = radeon_bo_vm_update_pte(parser, vm); if (r) { goto out;
@@ -592,7 +592,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, } out:
} @@ -696,6 +695,8 @@ int radeon_cs_ioctl(struct drm_device *dev, voidmutex_unlock(&vm->mutex); return r;
*data, struct drm_file *filp) } r = radeon_cs_ib_fill(rdev, &parser);
if (parser.cs_flags & RADEON_CS_USE_VM)
mutex_lock(&parser.ib.vm->lock); if (!r) { r = radeon_cs_parser_relocs(&parser); if (r && r != -ERESTARTSYS)
@@ -704,6 +705,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (r) { radeon_cs_parser_fini(&parser, r, false);
if (parser.cs_flags & RADEON_CS_USE_VM)
mutex_unlock(&parser.ib.vm->lock); up_read(&rdev->exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r;
@@ -721,6 +724,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) } out: radeon_cs_parser_fini(&parser, r, true);
if (parser.cs_flags & RADEON_CS_USE_VM)
mutex_unlock(&parser.ib.vm->lock); up_read(&rdev->exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r;
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 6162bd2..4eafec6 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -150,8 +150,10 @@ int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri return 0; }
mutex_lock(&vm->lock); r = radeon_bo_reserve(rbo, false); if (r) {
@@ -162,6 +164,7 @@ int radeon_gem_object_open(struct drm_gem_objectmutex_unlock(&vm->lock); return r; }
*obj, struct drm_file *file_pri ++bo_va->ref_count; } radeon_bo_unreserve(rbo);
}mutex_unlock(&vm->lock); return 0;
@@ -180,8 +183,10 @@ void radeon_gem_object_close(struct drm_gem_object *obj, return; }
mutex_lock(&vm->lock); r = radeon_bo_reserve(rbo, true); if (r) {
mutex_unlock(&vm->lock); dev_err(rdev->dev, "leaking bo va because " "we fail to reserve bo (%d)\n", r); return;
@@ -193,6 +198,7 @@ void radeon_gem_object_close(struct drm_gem_object *obj, } } radeon_bo_unreserve(rbo);
} static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r)mutex_unlock(&vm->lock);
@@ -576,17 +582,13 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, goto error_unreserve; }
mutex_lock(&bo_va->vm->mutex); r = radeon_vm_clear_freed(rdev, bo_va->vm); if (r)
goto error_unlock;
-error_unlock:goto error_unreserve; if (bo_va->it.start) r = radeon_vm_bo_update(rdev, bo_va, &bo_va->bo->tbo.mem);
mutex_unlock(&bo_va->vm->mutex);
- error_unreserve: ttm_eu_backoff_reservation(&ticket, &list); @@ -662,14 +664,18 @@ int radeon_gem_va_ioctl(struct drm_device *dev,
void *data, return -ENOENT; } rbo = gem_to_radeon_bo(gobj);
mutex_lock(&fpriv->vm.lock); r = radeon_bo_reserve(rbo, false); if (r) {
mutex_unlock(&fpriv->vm.lock); args->operation = RADEON_VA_RESULT_ERROR; drm_gem_object_unreference_unlocked(gobj); return r; } bo_va = radeon_vm_bo_find(&fpriv->vm, rbo); if (!bo_va) {
radeon_bo_unreserve(rbo);
mutex_unlock(&fpriv->vm.lock); args->operation = RADEON_VA_RESULT_ERROR; drm_gem_object_unreference_unlocked(gobj); return -ENOENT;
@@ -698,6 +704,7 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, args->operation = RADEON_VA_RESULT_ERROR; } out:
}mutex_unlock(&fpriv->vm.lock); drm_gem_object_unreference_unlocked(gobj); return r;
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index f4dd26a..d994006 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -613,8 +613,10 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) } if (rdev->accel_working) {
mutex_lock(&vm->lock); r = radeon_bo_reserve(rdev->ring_tmp_bo.bo,
false); if (r) {
mutex_unlock(&vm->lock); radeon_vm_fini(rdev, vm); kfree(fpriv); return r;
@@ -628,6 +630,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) RADEON_VA_IB_OFFSET, RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_SNOOPED);
mutex_unlock(&vm->lock); if (r) { radeon_vm_fini(rdev, vm); kfree(fpriv);
@@ -662,12 +665,14 @@ void radeon_driver_postclose_kms(struct drm_device *dev, int r; if (rdev->accel_working) {
mutex_lock(&vm->lock); r = radeon_bo_reserve(rdev->ring_tmp_bo.bo,
false); if (!r) { if (vm->ib_bo_va) radeon_vm_bo_rmv(rdev, vm->ib_bo_va); radeon_bo_unreserve(rdev->ring_tmp_bo.bo); }
mutex_unlock(&vm->lock); } radeon_vm_fini(rdev, vm);
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index cde48c4..658183f 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -172,7 +172,7 @@ struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev,
- Allocate an id for the vm (cayman+).
- Returns the fence we need to sync to (if any).
- Global and local mutex must be locked!
*/ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, struct radeon_vm *vm, int ring)
- Mutex must be locked!
@@ -231,7 +231,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
- Flush the vm (cayman+).
- Global and local mutex must be locked!
*/ void radeon_vm_flush(struct radeon_device *rdev, struct radeon_vm *vm,
- Mutex must be locked!
@@ -263,7 +263,7 @@ void radeon_vm_flush(struct radeon_device *rdev,
- Fence the vm (cayman+).
- Set the fence used to protect page table and id.
- Global and local mutex must be locked!
*/ void radeon_vm_fence(struct radeon_device *rdev, struct radeon_vm *vm,
- Mutex must be locked!
@@ -314,7 +314,7 @@ struct radeon_bo_va *radeon_vm_bo_find(struct radeon_vm *vm,
- Add @bo to the list of bos associated with the vm
- Returns newly added bo_va or NULL for failure
- Object has to be reserved!
*/ struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev, struct radeon_vm *vm,
- Mutex must be locked and object has to be reserved!
@@ -336,9 +336,7 @@ struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev, INIT_LIST_HEAD(&bo_va->bo_list); INIT_LIST_HEAD(&bo_va->vm_status);
mutex_lock(&vm->mutex); list_add_tail(&bo_va->bo_list, &bo->va);
}mutex_unlock(&vm->mutex); return bo_va;
@@ -441,7 +439,8 @@ error_unreserve:
- Validate and set the offset requested within the vm address space.
- Returns 0 for success, error for failure.
- Object has to be reserved and gets unreserved by this function!
- Mutex must be locked and object has to be reserved and gets
*/ int radeon_vm_bo_set_addr(struct radeon_device *rdev, struct radeon_bo_va *bo_va,
- unreserved by this function!
@@ -472,14 +471,12 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, eoffset = last_pfn = 0; }
mutex_lock(&vm->mutex); if (bo_va->it.start || bo_va->it.last) { if (bo_va->addr) { /* add a clone of the bo_va to clear the old
address */ struct radeon_bo_va *tmp; tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); if (!tmp) {
mutex_unlock(&vm->mutex); return -ENOMEM; } tmp->it.start = bo_va->it.start;
@@ -509,7 +506,6 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, dev_err(rdev->dev, "bo %p va 0x%010Lx conflict with " "(bo %p 0x%010lx 0x%010lx)\n", bo_va->bo, soffset, tmp->bo, tmp->it.start, tmp->it.last);
mutex_unlock(&vm->mutex); return -EINVAL; } bo_va->it.start = soffset;
@@ -537,9 +533,6 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, if (vm->page_tables[pt_idx].bo) continue;
/* drop mutex to allocate and clear page table */
mutex_unlock(&vm->mutex);
r = radeon_bo_create(rdev, RADEON_VM_PTE_COUNT * 8, RADEON_GPU_PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, 0,
@@ -554,21 +547,10 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, return r; }
/* aquire mutex again */
mutex_lock(&vm->mutex);
if (vm->page_tables[pt_idx].bo) {
/* someone else allocated the pt in the meantime
*/
mutex_unlock(&vm->mutex);
radeon_bo_unref(&pt);
mutex_lock(&vm->mutex);
continue;
}
vm->page_tables[pt_idx].addr = 0; vm->page_tables[pt_idx].bo = pt; }
} @@ -627,7 +609,7 @@ static uint32_t radeon_vm_page_flags(uint32_t flags)
mutex_unlock(&vm->mutex); return 0;
- and updates the page directory (cayman+).
- Returns 0 for success, error for failure.
- Global and local mutex must be locked!
*/ int radeon_vm_update_page_directory(struct radeon_device *rdev, struct radeon_vm *vm)
- Mutex must be locked!
@@ -717,8 +699,6 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
- @pe_end: last PTE to handle
- @addr: addr those PTEs should point to
- @flags: hw mapping flags
*/ static void radeon_vm_frag_ptes(struct radeon_device *rdev, struct radeon_ib *ib,
- Global and local mutex must be locked!
@@ -798,7 +778,6 @@ static void radeon_vm_frag_ptes(struct radeon_device *rdev,
- Update the page tables in the range @start - @end (cayman+).
*/ static int radeon_vm_update_ptes(struct radeon_device *rdev, struct radeon_vm *vm,
- Global and local mutex must be locked!
@@ -870,7 +849,6 @@ static int radeon_vm_update_ptes(struct radeon_device *rdev,
- Fence the page tables in the range @start - @end (cayman+).
*/ static void radeon_vm_fence_pts(struct radeon_vm *vm, uint64_t start, uint64_t end,
- Global and local mutex must be locked!
@@ -896,7 +874,7 @@ static void radeon_vm_fence_pts(struct radeon_vm *vm,
- Fill in the page table entries for @bo (cayman+).
- Returns 0 for success, -EINVAL for failure.
- Object have to be reserved and mutex must be locked!
*/ int radeon_vm_bo_update(struct radeon_device *rdev, struct radeon_bo_va *bo_va,
- Mutex must be locked and BOs have to be reserved!
@@ -1097,7 +1075,7 @@ int radeon_vm_clear_invalids(struct radeon_device *rdev,
- Remove @bo_va->bo from the requested vm (cayman+).
- Object have to be reserved!
*/ void radeon_vm_bo_rmv(struct radeon_device *rdev, struct radeon_bo_va *bo_va)
- Mutex must be locked and object has to be reserved!
@@ -1106,7 +1084,6 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev, list_del(&bo_va->bo_list);
mutex_lock(&vm->mutex); interval_tree_remove(&bo_va->it, &vm->va); spin_lock(&vm->status_lock); list_del(&bo_va->vm_status);
@@ -1119,8 +1096,6 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev, kfree(bo_va); } spin_unlock(&vm->status_lock);
} /**mutex_unlock(&vm->mutex);
@@ -1168,7 +1143,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) vm->ids[i].flushed_updates = NULL; vm->ids[i].last_id_use = NULL; }
mutex_init(&vm->mutex);
mutex_init(&vm->lock); vm->va = RB_ROOT; spin_lock_init(&vm->status_lock); INIT_LIST_HEAD(&vm->invalidated);
@@ -1245,5 +1220,5 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) radeon_fence_unref(&vm->ids[i].last_id_use); }
mutex_destroy(&vm->mutex);
}mutex_destroy(&vm->lock);
From: Christian König christian.koenig@amd.com
Just use the list structure directly for representing the entries.
Signed-off-by: Christian König christian.koenig@amd.com --- drivers/gpu/drm/radeon/radeon.h | 12 +++--- drivers/gpu/drm/radeon/radeon_cs.c | 4 +- drivers/gpu/drm/radeon/radeon_gem.c | 11 ++---- drivers/gpu/drm/radeon/radeon_vm.c | 75 ++++++++++++++++--------------------- 4 files changed, 41 insertions(+), 61 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 699446a..d652ccb 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -911,8 +911,8 @@ struct radeon_mec { R600_PTE_SYSTEM | R600_PTE_VALID )
struct radeon_vm_pt { - struct radeon_bo *bo; - uint64_t addr; + struct radeon_bo_list list; + uint64_t addr; };
struct radeon_vm_id { @@ -939,7 +939,7 @@ struct radeon_vm { struct list_head freed;
/* contains the page directory */ - struct radeon_bo *page_directory; + struct radeon_bo_list page_directory; unsigned max_pde_used;
/* array of page tables, one for each page directory entry */ @@ -1077,7 +1077,6 @@ struct radeon_cs_parser { unsigned nrelocs; struct radeon_bo_list *relocs; struct radeon_bo_list **relocs_ptr; - struct radeon_bo_list *vm_bos; struct list_head validated; unsigned dma_reloc_idx; /* indices of various chunks */ @@ -2976,9 +2975,8 @@ int radeon_vm_manager_init(struct radeon_device *rdev); void radeon_vm_manager_fini(struct radeon_device *rdev); int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); -struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev, - struct radeon_vm *vm, - struct list_head *head); +void radeon_vm_add_bos(struct radeon_device *rdev, struct radeon_vm *vm, + struct list_head *head); struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, struct radeon_vm *vm, int ring); void radeon_vm_flush(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 7a90378..551980c 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -193,8 +193,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) radeon_cs_buckets_get_list(&buckets, &p->validated);
if (p->cs_flags & RADEON_CS_USE_VM) - p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm, - &p->validated); + radeon_vm_add_bos(p->rdev, p->ib.vm, &p->validated);
if (need_mmap_lock) down_read(¤t->mm->mmap_sem); @@ -450,7 +449,6 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo kfree(parser->track); kfree(parser->relocs); kfree(parser->relocs_ptr); - drm_free_large(parser->vm_bos); for (i = 0; i < parser->nchunks; i++) drm_free_large(parser->chunks[i].kdata); kfree(parser->chunks); diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 4eafec6..26d1af1 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -554,7 +554,6 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, struct radeon_bo_va *bo_va) { struct ttm_validate_buffer tv, *entry; - struct radeon_bo_list *vm_bos; struct ww_acquire_ctx ticket; struct list_head list; unsigned domain; @@ -566,13 +565,11 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, tv.shared = true; list_add(&tv.head, &list);
- vm_bos = radeon_vm_get_bos(rdev, bo_va->vm, &list); - if (!vm_bos) - return; + radeon_vm_add_bos(rdev, bo_va->vm, &list);
r = ttm_eu_reserve_buffers(&ticket, &list, true); if (r) - goto error_free; + goto error_done;
list_for_each_entry(entry, &list, head) { domain = radeon_mem_type_to_domain(entry->bo->mem.mem_type); @@ -592,9 +589,7 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, error_unreserve: ttm_eu_backoff_reservation(&ticket, &list);
-error_free: - drm_free_large(vm_bos); - +error_done: if (r) DRM_ERROR("Couldn't update BO_VA (%d)\n", r); } diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 658183f..b09c998 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -117,7 +117,7 @@ void radeon_vm_manager_fini(struct radeon_device *rdev) }
/** - * radeon_vm_get_bos - add the vm BOs to a validation list + * radeon_vm_add_bos - add the PD/PT BOs to a validation list * * @vm: vm providing the BOs * @head: head of validation list @@ -125,41 +125,18 @@ void radeon_vm_manager_fini(struct radeon_device *rdev) * Add the page directory to the list of BOs to * validate for command submission (cayman+). */ -struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev, - struct radeon_vm *vm, - struct list_head *head) +void radeon_vm_add_bos(struct radeon_device *rdev, struct radeon_vm *vm, + struct list_head *head) { - struct radeon_bo_list *list; unsigned i, idx;
- list = drm_malloc_ab(vm->max_pde_used + 2, - sizeof(struct radeon_bo_list)); - if (!list) - return NULL; - - /* add the vm page table to the list */ - list[0].robj = vm->page_directory; - list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM; - list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM; - list[0].tv.bo = &vm->page_directory->tbo; - list[0].tv.shared = true; - list[0].tiling_flags = 0; - list_add(&list[0].tv.head, head); - + list_add(&vm->page_directory.tv.head, head); for (i = 0, idx = 1; i <= vm->max_pde_used; i++) { - if (!vm->page_tables[i].bo) + if (!vm->page_tables[i].list.robj) continue;
- list[idx].robj = vm->page_tables[i].bo; - list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM; - list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM; - list[idx].tv.bo = &list[idx].robj->tbo; - list[idx].tv.shared = true; - list[idx].tiling_flags = 0; - list_add(&list[idx++].tv.head, head); + list_add(&vm->page_tables[i].list.tv.head, head); } - - return list; }
/** @@ -237,7 +214,7 @@ void radeon_vm_flush(struct radeon_device *rdev, struct radeon_vm *vm, int ring, struct radeon_fence *updates) { - uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory); + uint64_t pd_addr = vm->page_directory.gpu_offset; struct radeon_vm_id *vm_id = &vm->ids[ring];
if (pd_addr != vm_id->pd_gpu_addr || !vm_id->flushed_updates || @@ -528,9 +505,10 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev,
/* walk over the address space and allocate the page tables */ for (pt_idx = soffset; pt_idx <= eoffset; ++pt_idx) { + struct radeon_vm_pt *entry = &vm->page_tables[pt_idx]; struct radeon_bo *pt;
- if (vm->page_tables[pt_idx].bo) + if (entry->list.robj) continue;
r = radeon_bo_create(rdev, RADEON_VM_PTE_COUNT * 8, @@ -547,8 +525,13 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, return r; }
- vm->page_tables[pt_idx].addr = 0; - vm->page_tables[pt_idx].bo = pt; + entry->list.robj = pt; + entry->list.prefered_domains = RADEON_GEM_DOMAIN_VRAM; + entry->list.allowed_domains = RADEON_GEM_DOMAIN_VRAM; + entry->list.tv.bo = &pt->tbo; + entry->list.tv.shared = true; + entry->list.tiling_flags = 0; + entry->addr = 0; }
return 0; @@ -614,7 +597,7 @@ static uint32_t radeon_vm_page_flags(uint32_t flags) int radeon_vm_update_page_directory(struct radeon_device *rdev, struct radeon_vm *vm) { - struct radeon_bo *pd = vm->page_directory; + struct radeon_bo *pd = vm->page_directory.robj; uint64_t pd_addr = radeon_bo_gpu_offset(pd); uint32_t incr = RADEON_VM_PTE_COUNT * 8; uint64_t last_pde = ~0, last_pt = ~0; @@ -639,7 +622,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
/* walk over the address space and update the page directory */ for (pt_idx = 0; pt_idx <= vm->max_pde_used; ++pt_idx) { - struct radeon_bo *bo = vm->page_tables[pt_idx].bo; + struct radeon_bo *bo = vm->page_tables[pt_idx].list.robj; uint64_t pde, pt;
if (bo == NULL) @@ -793,7 +776,7 @@ static int radeon_vm_update_ptes(struct radeon_device *rdev, /* walk over the address space and update the page tables */ for (addr = start; addr < end; ) { uint64_t pt_idx = addr >> radeon_vm_block_size; - struct radeon_bo *pt = vm->page_tables[pt_idx].bo; + struct radeon_bo *pt = vm->page_tables[pt_idx].list.robj; unsigned nptes; uint64_t pte; int r; @@ -860,7 +843,7 @@ static void radeon_vm_fence_pts(struct radeon_vm *vm, end >>= radeon_vm_block_size;
for (i = start; i <= end; ++i) - radeon_bo_fence(vm->page_tables[i].bo, fence, true); + radeon_bo_fence(vm->page_tables[i].list.robj, fence, true); }
/** @@ -1162,17 +1145,23 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
r = radeon_bo_create(rdev, pd_size, align, true, RADEON_GEM_DOMAIN_VRAM, 0, NULL, - NULL, &vm->page_directory); + NULL, &vm->page_directory.robj); if (r) return r;
- r = radeon_vm_clear_bo(rdev, vm->page_directory); + r = radeon_vm_clear_bo(rdev, vm->page_directory.robj); if (r) { - radeon_bo_unref(&vm->page_directory); - vm->page_directory = NULL; + radeon_bo_unref(&vm->page_directory.robj); + vm->page_directory.robj = NULL; return r; }
+ vm->page_directory.prefered_domains = RADEON_GEM_DOMAIN_VRAM; + vm->page_directory.allowed_domains = RADEON_GEM_DOMAIN_VRAM; + vm->page_directory.tv.bo = &vm->page_directory.robj->tbo; + vm->page_directory.tv.shared = true; + vm->page_directory.tiling_flags = 0; + return 0; }
@@ -1210,10 +1199,10 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) }
for (i = 0; i < radeon_vm_num_pdes(rdev); i++) - radeon_bo_unref(&vm->page_tables[i].bo); + radeon_bo_unref(&vm->page_tables[i].list.robj); kfree(vm->page_tables);
- radeon_bo_unref(&vm->page_directory); + radeon_bo_unref(&vm->page_directory.robj);
for (i = 0; i < RADEON_NUM_RINGS; ++i) { radeon_fence_unref(&vm->ids[i].flushed_updates);
dri-devel@lists.freedesktop.org