On Fri, Sep 12, 2014 at 7:52 AM, Christian König <deathsimple@xxxxxxxxxxx> wrote: > From: Christian König <christian.koenig@xxxxxxx> > > Previously we just allocated space for four hardware semaphores > in each software semaphore object. Make software semaphore objects > represent only one hardware semaphore address again by splitting > the sync code into it's own object. > > Signed-off-by: Christian König <christian.koenig@xxxxxxx> Minor typo noted below. Alex > --- > drivers/gpu/drm/radeon/Makefile | 3 +- > drivers/gpu/drm/radeon/cik.c | 18 ++- > drivers/gpu/drm/radeon/cik_sdma.c | 18 ++- > drivers/gpu/drm/radeon/evergreen_dma.c | 18 ++- > drivers/gpu/drm/radeon/r600.c | 18 ++- > drivers/gpu/drm/radeon/r600_dma.c | 18 ++- > drivers/gpu/drm/radeon/radeon.h | 40 +++--- > drivers/gpu/drm/radeon/radeon_cs.c | 7 +- > drivers/gpu/drm/radeon/radeon_ib.c | 13 +- > drivers/gpu/drm/radeon/radeon_semaphore.c | 139 +-------------------- > drivers/gpu/drm/radeon/radeon_sync.c | 198 ++++++++++++++++++++++++++++++ > drivers/gpu/drm/radeon/radeon_vm.c | 4 +- > drivers/gpu/drm/radeon/rv770_dma.c | 18 ++- > drivers/gpu/drm/radeon/si_dma.c | 18 ++- > 14 files changed, 286 insertions(+), 244 deletions(-) > create mode 100644 drivers/gpu/drm/radeon/radeon_sync.c > > diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile > index 7d7aed5..8cc9f68 100644 > --- a/drivers/gpu/drm/radeon/Makefile > +++ b/drivers/gpu/drm/radeon/Makefile > @@ -80,7 +80,8 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ > r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ > rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \ > trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \ > - ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o radeon_mn.o > + ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o radeon_mn.o \ > + radeon_sync.o > > # add async DMA block > radeon-y += \ > diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c > index 16a861d..6dd55ea 100644 > --- a/drivers/gpu/drm/radeon/cik.c > +++ b/drivers/gpu/drm/radeon/cik.c > @@ -3970,31 +3970,27 @@ struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev, > unsigned num_gpu_pages, > struct reservation_object *resv) > { > - struct radeon_semaphore *sem = NULL; > struct radeon_fence *fence; > + struct radeon_sync sync; > int ring_index = rdev->asic->copy.blit_ring_index; > struct radeon_ring *ring = &rdev->ring[ring_index]; > u32 size_in_bytes, cur_size_in_bytes, control; > int i, num_loops; > int r = 0; > > - r = radeon_semaphore_create(rdev, &sem); > - if (r) { > - DRM_ERROR("radeon: moving bo (%d).\n", r); > - return ERR_PTR(r); > - } > + radeon_sync_create(&sync); > > size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); > num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); > r = radeon_ring_lock(rdev, ring, num_loops * 7 + 18); > if (r) { > DRM_ERROR("radeon: moving bo (%d).\n", r); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > - radeon_semaphore_sync_resv(sem, resv, false); > - radeon_semaphore_sync_rings(rdev, sem, ring->idx); > + radeon_sync_resv(&sync, resv, false); > + radeon_sync_rings(rdev, &sync, ring->idx); > > for (i = 0; i < num_loops; i++) { > cur_size_in_bytes = size_in_bytes; > @@ -4018,12 +4014,12 @@ struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev, > r = radeon_fence_emit(rdev, &fence, ring->idx); > if (r) { > radeon_ring_unlock_undo(rdev, ring); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > radeon_ring_unlock_commit(rdev, ring, false); > - radeon_semaphore_free(rdev, &sem, fence); > + radeon_sync_free(rdev, &sync, fence); > > return fence; > } > diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c > index dd73246..06602e4 100644 > --- a/drivers/gpu/drm/radeon/cik_sdma.c > +++ b/drivers/gpu/drm/radeon/cik_sdma.c > @@ -548,31 +548,27 @@ struct radeon_fence *cik_copy_dma(struct radeon_device *rdev, > unsigned num_gpu_pages, > struct reservation_object *resv) > { > - struct radeon_semaphore *sem = NULL; > struct radeon_fence *fence; > + struct radeon_sync sync; > int ring_index = rdev->asic->copy.dma_ring_index; > struct radeon_ring *ring = &rdev->ring[ring_index]; > u32 size_in_bytes, cur_size_in_bytes; > int i, num_loops; > int r = 0; > > - r = radeon_semaphore_create(rdev, &sem); > - if (r) { > - DRM_ERROR("radeon: moving bo (%d).\n", r); > - return ERR_PTR(r); > - } > + radeon_sync_create(&sync); > > size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); > num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); > r = radeon_ring_lock(rdev, ring, num_loops * 7 + 14); > if (r) { > DRM_ERROR("radeon: moving bo (%d).\n", r); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > - radeon_semaphore_sync_resv(sem, resv, false); > - radeon_semaphore_sync_rings(rdev, sem, ring->idx); > + radeon_sync_resv(&sync, resv, false); > + radeon_sync_rings(rdev, &sync, ring->idx); > > for (i = 0; i < num_loops; i++) { > cur_size_in_bytes = size_in_bytes; > @@ -593,12 +589,12 @@ struct radeon_fence *cik_copy_dma(struct radeon_device *rdev, > r = radeon_fence_emit(rdev, &fence, ring->idx); > if (r) { > radeon_ring_unlock_undo(rdev, ring); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > radeon_ring_unlock_commit(rdev, ring, false); > - radeon_semaphore_free(rdev, &sem, fence); > + radeon_sync_free(rdev, &sync, fence); > > return fence; > } > diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c > index 946f37d..2958fa8 100644 > --- a/drivers/gpu/drm/radeon/evergreen_dma.c > +++ b/drivers/gpu/drm/radeon/evergreen_dma.c > @@ -110,31 +110,27 @@ struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev, > unsigned num_gpu_pages, > struct reservation_object *resv) > { > - struct radeon_semaphore *sem = NULL; > struct radeon_fence *fence; > + struct radeon_sync sync; > int ring_index = rdev->asic->copy.dma_ring_index; > struct radeon_ring *ring = &rdev->ring[ring_index]; > u32 size_in_dw, cur_size_in_dw; > int i, num_loops; > int r = 0; > > - r = radeon_semaphore_create(rdev, &sem); > - if (r) { > - DRM_ERROR("radeon: moving bo (%d).\n", r); > - return ERR_PTR(r); > - } > + radeon_sync_create(&sync); > > size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; > num_loops = DIV_ROUND_UP(size_in_dw, 0xfffff); > r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11); > if (r) { > DRM_ERROR("radeon: moving bo (%d).\n", r); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > - radeon_semaphore_sync_resv(sem, resv, false); > - radeon_semaphore_sync_rings(rdev, sem, ring->idx); > + radeon_sync_resv(&sync, resv, false); > + radeon_sync_rings(rdev, &sync, ring->idx); > > for (i = 0; i < num_loops; i++) { > cur_size_in_dw = size_in_dw; > @@ -153,12 +149,12 @@ struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev, > r = radeon_fence_emit(rdev, &fence, ring->idx); > if (r) { > radeon_ring_unlock_undo(rdev, ring); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > radeon_ring_unlock_commit(rdev, ring, false); > - radeon_semaphore_free(rdev, &sem, fence); > + radeon_sync_free(rdev, &sync, fence); > > return fence; > } > diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c > index 5e9146b..5205070 100644 > --- a/drivers/gpu/drm/radeon/r600.c > +++ b/drivers/gpu/drm/radeon/r600.c > @@ -2899,31 +2899,27 @@ struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev, > unsigned num_gpu_pages, > struct reservation_object *resv) > { > - struct radeon_semaphore *sem = NULL; > struct radeon_fence *fence; > + struct radeon_sync sync; > int ring_index = rdev->asic->copy.blit_ring_index; > struct radeon_ring *ring = &rdev->ring[ring_index]; > u32 size_in_bytes, cur_size_in_bytes, tmp; > int i, num_loops; > int r = 0; > > - r = radeon_semaphore_create(rdev, &sem); > - if (r) { > - DRM_ERROR("radeon: moving bo (%d).\n", r); > - return ERR_PTR(r); > - } > + radeon_sync_create(&sync); > > size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); > num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); > r = radeon_ring_lock(rdev, ring, num_loops * 6 + 24); > if (r) { > DRM_ERROR("radeon: moving bo (%d).\n", r); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > - radeon_semaphore_sync_resv(sem, resv, false); > - radeon_semaphore_sync_rings(rdev, sem, ring->idx); > + radeon_sync_resv(&sync, resv, false); > + radeon_sync_rings(rdev, &sync, ring->idx); > > radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); > radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); > @@ -2952,12 +2948,12 @@ struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev, > r = radeon_fence_emit(rdev, &fence, ring->idx); > if (r) { > radeon_ring_unlock_undo(rdev, ring); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > radeon_ring_unlock_commit(rdev, ring, false); > - radeon_semaphore_free(rdev, &sem, fence); > + radeon_sync_free(rdev, &sync, fence); > > return fence; > } > diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c > index fc54224..8c39659 100644 > --- a/drivers/gpu/drm/radeon/r600_dma.c > +++ b/drivers/gpu/drm/radeon/r600_dma.c > @@ -447,31 +447,27 @@ struct radeon_fence *r600_copy_dma(struct radeon_device *rdev, > unsigned num_gpu_pages, > struct reservation_object *resv) > { > - struct radeon_semaphore *sem = NULL; > struct radeon_fence *fence; > + struct radeon_sync sync; > int ring_index = rdev->asic->copy.dma_ring_index; > struct radeon_ring *ring = &rdev->ring[ring_index]; > u32 size_in_dw, cur_size_in_dw; > int i, num_loops; > int r = 0; > > - r = radeon_semaphore_create(rdev, &sem); > - if (r) { > - DRM_ERROR("radeon: moving bo (%d).\n", r); > - return ERR_PTR(r); > - } > + radeon_sync_create(&sync); > > size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; > num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFE); > r = radeon_ring_lock(rdev, ring, num_loops * 4 + 8); > if (r) { > DRM_ERROR("radeon: moving bo (%d).\n", r); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > - radeon_semaphore_sync_resv(sem, resv, false); > - radeon_semaphore_sync_rings(rdev, sem, ring->idx); > + radeon_sync_resv(&sync, resv, false); > + radeon_sync_rings(rdev, &sync, ring->idx); > > for (i = 0; i < num_loops; i++) { > cur_size_in_dw = size_in_dw; > @@ -490,12 +486,12 @@ struct radeon_fence *r600_copy_dma(struct radeon_device *rdev, > r = radeon_fence_emit(rdev, &fence, ring->idx); > if (r) { > radeon_ring_unlock_undo(rdev, ring); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > radeon_ring_unlock_commit(rdev, ring, false); > - radeon_semaphore_free(rdev, &sem, fence); > + radeon_sync_free(rdev, &sync, fence); > > return fence; > } > diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h > index a93c9d9..c326fae 100644 > --- a/drivers/gpu/drm/radeon/radeon.h > +++ b/drivers/gpu/drm/radeon/radeon.h > @@ -147,9 +147,6 @@ extern int radeon_bapm; > /* number of hw syncs before falling back on blocking */ > #define RADEON_NUM_SYNCS 4 > > -/* number of hw syncs before falling back on blocking */ > -#define RADEON_NUM_SYNCS 4 > - > /* hardcode those limit for now */ > #define RADEON_VA_IB_OFFSET (1 << 20) > #define RADEON_VA_RESERVED_SIZE (8 << 20) > @@ -573,10 +570,9 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, > * Semaphores. > */ > struct radeon_semaphore { > - struct radeon_sa_bo *sa_bo; > - signed waiters; > - uint64_t gpu_addr; > - struct radeon_fence *sync_to[RADEON_NUM_RINGS]; > + struct radeon_sa_bo *sa_bo; > + signed waiters; > + uint64_t gpu_addr; > }; > > int radeon_semaphore_create(struct radeon_device *rdev, > @@ -585,19 +581,31 @@ bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, > struct radeon_semaphore *semaphore); > bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, > struct radeon_semaphore *semaphore); > -void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, > - struct radeon_fence *fence); > -void radeon_semaphore_sync_resv(struct radeon_semaphore *semaphore, > - struct reservation_object *resv, > - bool shared); > -int radeon_semaphore_sync_rings(struct radeon_device *rdev, > - struct radeon_semaphore *semaphore, > - int waiting_ring); > void radeon_semaphore_free(struct radeon_device *rdev, > struct radeon_semaphore **semaphore, > struct radeon_fence *fence); > > /* > + * Synchronization > + */ > +struct radeon_sync { > + struct radeon_semaphore *semaphores[RADEON_NUM_SYNCS]; > + struct radeon_fence *sync_to[RADEON_NUM_RINGS]; > +}; > + > +void radeon_sync_create(struct radeon_sync *sync); > +void radeon_sync_fence(struct radeon_sync *sync, > + struct radeon_fence *fence); > +void radeon_sync_resv(struct radeon_sync *sync, > + struct reservation_object *resv, > + bool shared); > +int radeon_sync_rings(struct radeon_device *rdev, > + struct radeon_sync *sync, > + int waiting_ring); > +void radeon_sync_free(struct radeon_device *rdev, struct radeon_sync *sync, > + struct radeon_fence *fence); > + > +/* > * GART structures, functions & helpers > */ > struct radeon_mc; > @@ -810,7 +818,7 @@ struct radeon_ib { > struct radeon_fence *fence; > struct radeon_vm *vm; > bool is_const_ib; > - struct radeon_semaphore *semaphore; > + struct radeon_sync sync; > }; > > struct radeon_ring { > diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c > index f662de4..0619c32 100644 > --- a/drivers/gpu/drm/radeon/radeon_cs.c > +++ b/drivers/gpu/drm/radeon/radeon_cs.c > @@ -260,8 +260,7 @@ static void radeon_cs_sync_rings(struct radeon_cs_parser *p) > continue; > > resv = p->relocs[i].robj->tbo.resv; > - radeon_semaphore_sync_resv(p->ib.semaphore, resv, > - p->relocs[i].tv.shared); > + radeon_sync_resv(&p->ib.sync, resv, p->relocs[i].tv.shared); > } > } > > @@ -281,9 +280,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) > INIT_LIST_HEAD(&p->validated); > p->idx = 0; > p->ib.sa_bo = NULL; > - p->ib.semaphore = NULL; > p->const_ib.sa_bo = NULL; > - p->const_ib.semaphore = NULL; > p->chunk_ib_idx = -1; > p->chunk_relocs_idx = -1; > p->chunk_flags_idx = -1; > @@ -566,7 +563,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, > goto out; > } > radeon_cs_sync_rings(parser); > - radeon_semaphore_sync_fence(parser->ib.semaphore, vm->fence); > + radeon_sync_fence(&parser->ib.sync, vm->fence); > > if ((rdev->family >= CHIP_TAHITI) && > (parser->chunk_const_ib_idx != -1)) { > diff --git a/drivers/gpu/drm/radeon/radeon_ib.c b/drivers/gpu/drm/radeon/radeon_ib.c > index 3f39fcc..56a1704 100644 > --- a/drivers/gpu/drm/radeon/radeon_ib.c > +++ b/drivers/gpu/drm/radeon/radeon_ib.c > @@ -64,10 +64,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, > return r; > } > > - r = radeon_semaphore_create(rdev, &ib->semaphore); > - if (r) { > - return r; > - } > + radeon_sync_create(&ib->sync); > > ib->ring = ring; > ib->fence = NULL; > @@ -96,7 +93,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, > */ > void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib) > { > - radeon_semaphore_free(rdev, &ib->semaphore, ib->fence); > + radeon_sync_free(rdev, &ib->sync, ib->fence); > radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence); > radeon_fence_unref(&ib->fence); > } > @@ -145,11 +142,11 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, > if (ib->vm) { > struct radeon_fence *vm_id_fence; > vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring); > - radeon_semaphore_sync_fence(ib->semaphore, vm_id_fence); > + radeon_sync_fence(&ib->sync, vm_id_fence); > } > > /* sync with other rings */ > - r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring); > + r = radeon_sync_rings(rdev, &ib->sync, ib->ring); > if (r) { > dev_err(rdev->dev, "failed to sync rings (%d)\n", r); > radeon_ring_unlock_undo(rdev, ring); > @@ -161,7 +158,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, > > if (const_ib) { > radeon_ring_ib_execute(rdev, const_ib->ring, const_ib); > - radeon_semaphore_free(rdev, &const_ib->semaphore, NULL); > + radeon_sync_free(rdev, &const_ib->sync, NULL); > } > radeon_ring_ib_execute(rdev, ib->ring, ib); > r = radeon_fence_emit(rdev, &ib->fence, ib->ring); > diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c > index 5bfbd83..e6ad54c 100644 > --- a/drivers/gpu/drm/radeon/radeon_semaphore.c > +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c > @@ -34,15 +34,14 @@ > int radeon_semaphore_create(struct radeon_device *rdev, > struct radeon_semaphore **semaphore) > { > - uint32_t *cpu_addr; > - int i, r; > + int r; > > *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); > if (*semaphore == NULL) { > return -ENOMEM; > } > - r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &(*semaphore)->sa_bo, > - 8 * RADEON_NUM_SYNCS, 8); > + r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, > + &(*semaphore)->sa_bo, 8, 8); > if (r) { > kfree(*semaphore); > *semaphore = NULL; > @@ -51,12 +50,7 @@ int radeon_semaphore_create(struct radeon_device *rdev, > (*semaphore)->waiters = 0; > (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo); > > - cpu_addr = radeon_sa_bo_cpu_addr((*semaphore)->sa_bo); > - for (i = 0; i < RADEON_NUM_SYNCS; ++i) > - cpu_addr[i] = 0; > - > - for (i = 0; i < RADEON_NUM_RINGS; ++i) > - (*semaphore)->sync_to[i] = NULL; > + *((uint64_t *)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0; > > return 0; > } > @@ -95,131 +89,6 @@ bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ridx, > return false; > } > > -/** > - * radeon_semaphore_sync_fence - use the semaphore to sync to a fence > - * > - * @semaphore: semaphore object to add fence to > - * @fence: fence to sync to > - * > - * Sync to the fence using this semaphore object > - */ > -void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, > - struct radeon_fence *fence) > -{ > - struct radeon_fence *other; > - > - if (!fence) > - return; > - > - other = semaphore->sync_to[fence->ring]; > - semaphore->sync_to[fence->ring] = radeon_fence_later(fence, other); > -} > - > -/** > - * radeon_semaphore_sync_to - use the semaphore to sync to a reservation object > - * > - * @sema: semaphore object to add fence from reservation object to > - * @resv: reservation object with embedded fence > - * @shared: true if we should onyl sync to the exclusive fence > - * > - * Sync to the fence using this semaphore object > - */ > -void radeon_semaphore_sync_resv(struct radeon_semaphore *sema, > - struct reservation_object *resv, > - bool shared) > -{ > - struct reservation_object_list *flist; > - struct fence *f; > - unsigned i; > - > - /* always sync to the exclusive fence */ > - f = reservation_object_get_excl(resv); > - radeon_semaphore_sync_fence(sema, (struct radeon_fence*)f); > - > - flist = reservation_object_get_list(resv); > - if (shared || !flist) > - return; > - > - for (i = 0; i < flist->shared_count; ++i) { > - f = rcu_dereference_protected(flist->shared[i], > - reservation_object_held(resv)); > - radeon_semaphore_sync_fence(sema, (struct radeon_fence*)f); > - } > -} > - > -/** > - * radeon_semaphore_sync_rings - sync ring to all registered fences > - * > - * @rdev: radeon_device pointer > - * @semaphore: semaphore object to use for sync > - * @ring: ring that needs sync > - * > - * Ensure that all registered fences are signaled before letting > - * the ring continue. The caller must hold the ring lock. > - */ > -int radeon_semaphore_sync_rings(struct radeon_device *rdev, > - struct radeon_semaphore *semaphore, > - int ring) > -{ > - unsigned count = 0; > - int i, r; > - > - for (i = 0; i < RADEON_NUM_RINGS; ++i) { > - struct radeon_fence *fence = semaphore->sync_to[i]; > - > - /* check if we really need to sync */ > - if (!radeon_fence_need_sync(fence, ring)) > - continue; > - > - /* prevent GPU deadlocks */ > - if (!rdev->ring[i].ready) { > - dev_err(rdev->dev, "Syncing to a disabled ring!"); > - return -EINVAL; > - } > - > - if (++count > RADEON_NUM_SYNCS) { > - /* not enough room, wait manually */ > - r = radeon_fence_wait(fence, false); > - if (r) > - return r; > - continue; > - } > - > - /* allocate enough space for sync command */ > - r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); > - if (r) { > - return r; > - } > - > - /* emit the signal semaphore */ > - if (!radeon_semaphore_emit_signal(rdev, i, semaphore)) { > - /* signaling wasn't successful wait manually */ > - radeon_ring_undo(&rdev->ring[i]); > - r = radeon_fence_wait(fence, false); > - if (r) > - return r; > - continue; > - } > - > - /* we assume caller has already allocated space on waiters ring */ > - if (!radeon_semaphore_emit_wait(rdev, ring, semaphore)) { > - /* waiting wasn't successful wait manually */ > - radeon_ring_undo(&rdev->ring[i]); > - r = radeon_fence_wait(fence, false); > - if (r) > - return r; > - continue; > - } > - > - radeon_ring_commit(rdev, &rdev->ring[i], false); > - radeon_fence_note_sync(fence, ring); > - > - semaphore->gpu_addr += 8; > - } > - > - return 0; > -} > - > void radeon_semaphore_free(struct radeon_device *rdev, > struct radeon_semaphore **semaphore, > struct radeon_fence *fence) > diff --git a/drivers/gpu/drm/radeon/radeon_sync.c b/drivers/gpu/drm/radeon/radeon_sync.c > new file mode 100644 > index 0000000..77b7401 > --- /dev/null > +++ b/drivers/gpu/drm/radeon/radeon_sync.c > @@ -0,0 +1,198 @@ > +/* > + * Copyright 2014 Advanced Micro Devices, Inc. > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, including > + * without limitation the rights to use, copy, modify, merge, publish, > + * distribute, sub license, and/or sell copies of the Software, and to > + * permit persons to whom the Software is furnished to do so, subject to > + * the following conditions: > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, > + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR > + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE > + * USE OR OTHER DEALINGS IN THE SOFTWARE. > + * > + * The above copyright notice and this permission notice (including the > + * next paragraph) shall be included in all copies or substantial portions > + * of the Software. > + * > + */ > +/* > + * Authors: > + * Christian König <christian.koenig@xxxxxxx> > + */ > + > +#include <drm/drmP.h> > +#include "radeon.h" > +#include "radeon_trace.h" > + > +/** > + * radeon_sync_create - zero init sync object > + * > + * @sync: sync object to initialize > + * > + * Just clear the sync object for now. > + */ > +void radeon_sync_create(struct radeon_sync *sync) > +{ > + unsigned i; > + > + for (i = 0; i < RADEON_NUM_SYNCS; ++i) > + sync->semaphores[i] = NULL; > + > + for (i = 0; i < RADEON_NUM_RINGS; ++i) > + sync->sync_to[i] = NULL; > +} > + > +/** > + * radeon_sync_fence - use the semaphore to sync to a fence > + * > + * @sync: sync object to add fence to > + * @fence: fence to sync to > + * > + * Sync to the fence using the semaphore objects > + */ > +void radeon_sync_fence(struct radeon_sync *sync, > + struct radeon_fence *fence) > +{ > + struct radeon_fence *other; > + > + if (!fence) > + return; > + > + other = sync->sync_to[fence->ring]; > + sync->sync_to[fence->ring] = radeon_fence_later(fence, other); > +} > + > +/** > + * radeon_sync_resv - use the semaphores to sync to a reservation object > + * > + * @sync: sync object to add fences from reservation object to > + * @resv: reservation object with embedded fence > + * @shared: true if we should onyl sync to the exclusive fence typo: only > + * > + * Sync to the fence using the semaphore objects > + */ > +void radeon_sync_resv(struct radeon_sync *sync, > + struct reservation_object *resv, > + bool shared) > +{ > + struct reservation_object_list *flist; > + struct fence *f; > + unsigned i; > + > + /* always sync to the exclusive fence */ > + f = reservation_object_get_excl(resv); > + radeon_sync_fence(sync, (struct radeon_fence*)f); > + > + flist = reservation_object_get_list(resv); > + if (shared || !flist) > + return; > + > + for (i = 0; i < flist->shared_count; ++i) { > + f = rcu_dereference_protected(flist->shared[i], > + reservation_object_held(resv)); > + radeon_sync_fence(sync, (struct radeon_fence*)f); > + } > +} > + > +/** > + * radeon_sync_rings - sync ring to all registered fences > + * > + * @rdev: radeon_device pointer > + * @sync: sync object to use > + * @ring: ring that needs sync > + * > + * Ensure that all registered fences are signaled before letting > + * the ring continue. The caller must hold the ring lock. > + */ > +int radeon_sync_rings(struct radeon_device *rdev, > + struct radeon_sync *sync, > + int ring) > +{ > + unsigned count = 0; > + int i, r; > + > + for (i = 0; i < RADEON_NUM_RINGS; ++i) { > + struct radeon_fence *fence = sync->sync_to[i]; > + struct radeon_semaphore *semaphore; > + > + /* check if we really need to sync */ > + if (!radeon_fence_need_sync(fence, ring)) > + continue; > + > + /* prevent GPU deadlocks */ > + if (!rdev->ring[i].ready) { > + dev_err(rdev->dev, "Syncing to a disabled ring!"); > + return -EINVAL; > + } > + > + if (count >= RADEON_NUM_SYNCS) { > + /* not enough room, wait manually */ > + r = radeon_fence_wait(fence, false); > + if (r) > + return r; > + continue; > + } > + r = radeon_semaphore_create(rdev, &semaphore); > + if (r) > + return r; > + > + sync->semaphores[count++] = semaphore; > + > + /* allocate enough space for sync command */ > + r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); > + if (r) > + return r; > + > + /* emit the signal semaphore */ > + if (!radeon_semaphore_emit_signal(rdev, i, semaphore)) { > + /* signaling wasn't successful wait manually */ > + radeon_ring_undo(&rdev->ring[i]); > + r = radeon_fence_wait(fence, false); > + if (r) > + return r; > + continue; > + } > + > + /* we assume caller has already allocated space on waiters ring */ > + if (!radeon_semaphore_emit_wait(rdev, ring, semaphore)) { > + /* waiting wasn't successful wait manually */ > + radeon_ring_undo(&rdev->ring[i]); > + r = radeon_fence_wait(fence, false); > + if (r) > + return r; > + continue; > + } > + > + radeon_ring_commit(rdev, &rdev->ring[i], false); > + radeon_fence_note_sync(fence, ring); > + } > + > + return 0; > +} > + > +/** > + * radeon_sync_free - free the sync object > + * > + * @rdev: radeon_device pointer > + * @sync: sync object to use > + * @fence: fence to use for the free > + * > + * Free the sync object by freeing all semaphores in it. > + */ > +void radeon_sync_free(struct radeon_device *rdev, > + struct radeon_sync *sync, > + struct radeon_fence *fence) > +{ > + unsigned i; > + > + for (i = 0; i < RADEON_NUM_SYNCS; ++i) > + radeon_semaphore_free(rdev, &sync->semaphores[i], fence); > +} > diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c > index f684c18..411146a 100644 > --- a/drivers/gpu/drm/radeon/radeon_vm.c > +++ b/drivers/gpu/drm/radeon/radeon_vm.c > @@ -699,7 +699,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, > if (ib.length_dw != 0) { > radeon_asic_vm_pad_ib(rdev, &ib); > > - radeon_semaphore_sync_resv(ib.semaphore, pd->tbo.resv, false); > + radeon_sync_resv(&ib.sync, pd->tbo.resv, false); > WARN_ON(ib.length_dw > ndw); > r = radeon_ib_schedule(rdev, &ib, NULL, false); > if (r) { > @@ -825,7 +825,7 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, > unsigned nptes; > uint64_t pte; > > - radeon_semaphore_sync_resv(ib->semaphore, pt->tbo.resv, false); > + radeon_sync_resv(&ib->sync, pt->tbo.resv, false); > > if ((addr & ~mask) == (end & ~mask)) > nptes = end - addr; > diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c > index c112764..564822c 100644 > --- a/drivers/gpu/drm/radeon/rv770_dma.c > +++ b/drivers/gpu/drm/radeon/rv770_dma.c > @@ -44,31 +44,27 @@ struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev, > unsigned num_gpu_pages, > struct reservation_object *resv) > { > - struct radeon_semaphore *sem = NULL; > struct radeon_fence *fence; > + struct radeon_sync sync; > int ring_index = rdev->asic->copy.dma_ring_index; > struct radeon_ring *ring = &rdev->ring[ring_index]; > u32 size_in_dw, cur_size_in_dw; > int i, num_loops; > int r = 0; > > - r = radeon_semaphore_create(rdev, &sem); > - if (r) { > - DRM_ERROR("radeon: moving bo (%d).\n", r); > - return ERR_PTR(r); > - } > + radeon_sync_create(&sync); > > size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; > num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFF); > r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8); > if (r) { > DRM_ERROR("radeon: moving bo (%d).\n", r); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > - radeon_semaphore_sync_resv(sem, resv, false); > - radeon_semaphore_sync_rings(rdev, sem, ring->idx); > + radeon_sync_resv(&sync, resv, false); > + radeon_sync_rings(rdev, &sync, ring->idx); > > for (i = 0; i < num_loops; i++) { > cur_size_in_dw = size_in_dw; > @@ -87,12 +83,12 @@ struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev, > r = radeon_fence_emit(rdev, &fence, ring->idx); > if (r) { > radeon_ring_unlock_undo(rdev, ring); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > radeon_ring_unlock_commit(rdev, ring, false); > - radeon_semaphore_free(rdev, &sem, fence); > + radeon_sync_free(rdev, &sync, fence); > > return fence; > } > diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c > index 6573843..0b7d3c5 100644 > --- a/drivers/gpu/drm/radeon/si_dma.c > +++ b/drivers/gpu/drm/radeon/si_dma.c > @@ -226,31 +226,27 @@ struct radeon_fence *si_copy_dma(struct radeon_device *rdev, > unsigned num_gpu_pages, > struct reservation_object *resv) > { > - struct radeon_semaphore *sem = NULL; > struct radeon_fence *fence; > + struct radeon_sync sync; > int ring_index = rdev->asic->copy.dma_ring_index; > struct radeon_ring *ring = &rdev->ring[ring_index]; > u32 size_in_bytes, cur_size_in_bytes; > int i, num_loops; > int r = 0; > > - r = radeon_semaphore_create(rdev, &sem); > - if (r) { > - DRM_ERROR("radeon: moving bo (%d).\n", r); > - return ERR_PTR(r); > - } > + radeon_sync_create(&sync); > > size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); > num_loops = DIV_ROUND_UP(size_in_bytes, 0xfffff); > r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11); > if (r) { > DRM_ERROR("radeon: moving bo (%d).\n", r); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > - radeon_semaphore_sync_resv(sem, resv, false); > - radeon_semaphore_sync_rings(rdev, sem, ring->idx); > + radeon_sync_resv(&sync, resv, false); > + radeon_sync_rings(rdev, &sync, ring->idx); > > for (i = 0; i < num_loops; i++) { > cur_size_in_bytes = size_in_bytes; > @@ -269,12 +265,12 @@ struct radeon_fence *si_copy_dma(struct radeon_device *rdev, > r = radeon_fence_emit(rdev, &fence, ring->idx); > if (r) { > radeon_ring_unlock_undo(rdev, ring); > - radeon_semaphore_free(rdev, &sem, NULL); > + radeon_sync_free(rdev, &sync, NULL); > return ERR_PTR(r); > } > > radeon_ring_unlock_commit(rdev, ring, false); > - radeon_semaphore_free(rdev, &sem, fence); > + radeon_sync_free(rdev, &sync, fence); > > return fence; > } > -- > 1.9.1 > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/dri-devel _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel