diff mbox

[2/3] drm/radeon: add the infrastructure for concurrent buffer access

Message ID 1409853714-2612-2-git-send-email-deathsimple@vodafone.de (mailing list archive)
State New, archived
Headers show

Commit Message

Christian König Sept. 4, 2014, 6:01 p.m. UTC
From: Christian König <christian.koenig@amd.com>

This allows us to specify if we want to sync to
the shared fences of a reservation object or not.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/radeon/cik.c              | 25 ++++++-----
 drivers/gpu/drm/radeon/cik_sdma.c         | 25 ++++++-----
 drivers/gpu/drm/radeon/evergreen_dma.c    | 24 +++++-----
 drivers/gpu/drm/radeon/r100.c             | 21 +++++----
 drivers/gpu/drm/radeon/r200.c             | 21 +++++----
 drivers/gpu/drm/radeon/r600.c             | 23 +++++-----
 drivers/gpu/drm/radeon/r600_dma.c         | 25 ++++++-----
 drivers/gpu/drm/radeon/radeon.h           | 43 +++++++++---------
 drivers/gpu/drm/radeon/radeon_asic.h      | 74 ++++++++++++++++---------------
 drivers/gpu/drm/radeon/radeon_benchmark.c | 30 ++++++-------
 drivers/gpu/drm/radeon/radeon_cs.c        |  8 +---
 drivers/gpu/drm/radeon/radeon_ib.c        |  2 +-
 drivers/gpu/drm/radeon/radeon_semaphore.c | 38 ++++++++++++++--
 drivers/gpu/drm/radeon/radeon_test.c      | 24 +++++++---
 drivers/gpu/drm/radeon/radeon_ttm.c       | 12 ++---
 drivers/gpu/drm/radeon/radeon_vm.c        | 16 ++-----
 drivers/gpu/drm/radeon/rv770_dma.c        | 25 ++++++-----
 drivers/gpu/drm/radeon/si_dma.c           | 25 ++++++-----
 18 files changed, 253 insertions(+), 208 deletions(-)

Comments

Alex Deucher Sept. 10, 2014, 3:19 p.m. UTC | #1
On Thu, Sep 4, 2014 at 2:01 PM, Christian König <deathsimple@vodafone.de> wrote:
> From: Christian König <christian.koenig@amd.com>
>
> This allows us to specify if we want to sync to
> the shared fences of a reservation object or not.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Just one minor copy/paste typo in the comments below.  With that fixed:

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/radeon/cik.c              | 25 ++++++-----
>  drivers/gpu/drm/radeon/cik_sdma.c         | 25 ++++++-----
>  drivers/gpu/drm/radeon/evergreen_dma.c    | 24 +++++-----
>  drivers/gpu/drm/radeon/r100.c             | 21 +++++----
>  drivers/gpu/drm/radeon/r200.c             | 21 +++++----
>  drivers/gpu/drm/radeon/r600.c             | 23 +++++-----
>  drivers/gpu/drm/radeon/r600_dma.c         | 25 ++++++-----
>  drivers/gpu/drm/radeon/radeon.h           | 43 +++++++++---------
>  drivers/gpu/drm/radeon/radeon_asic.h      | 74 ++++++++++++++++---------------
>  drivers/gpu/drm/radeon/radeon_benchmark.c | 30 ++++++-------
>  drivers/gpu/drm/radeon/radeon_cs.c        |  8 +---
>  drivers/gpu/drm/radeon/radeon_ib.c        |  2 +-
>  drivers/gpu/drm/radeon/radeon_semaphore.c | 38 ++++++++++++++--
>  drivers/gpu/drm/radeon/radeon_test.c      | 24 +++++++---
>  drivers/gpu/drm/radeon/radeon_ttm.c       | 12 ++---
>  drivers/gpu/drm/radeon/radeon_vm.c        | 16 ++-----
>  drivers/gpu/drm/radeon/rv770_dma.c        | 25 ++++++-----
>  drivers/gpu/drm/radeon/si_dma.c           | 25 ++++++-----
>  18 files changed, 253 insertions(+), 208 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
> index 1f598ab..0b5a230 100644
> --- a/drivers/gpu/drm/radeon/cik.c
> +++ b/drivers/gpu/drm/radeon/cik.c
> @@ -3959,18 +3959,19 @@ bool cik_semaphore_ring_emit(struct radeon_device *rdev,
>   * @src_offset: src GPU address
>   * @dst_offset: dst GPU address
>   * @num_gpu_pages: number of GPU pages to xfer
> - * @fence: radeon fence object
> + * @resv: reservation object to sync to
>   *
>   * Copy GPU paging using the CP DMA engine (CIK+).
>   * Used by the radeon ttm implementation to move pages if
>   * registered as the asic copy callback.
>   */
> -int cik_copy_cpdma(struct radeon_device *rdev,
> -                  uint64_t src_offset, uint64_t dst_offset,
> -                  unsigned num_gpu_pages,
> -                  struct radeon_fence **fence)
> +struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev,
> +                                   uint64_t src_offset, uint64_t dst_offset,
> +                                   unsigned num_gpu_pages,
> +                                   struct reservation_object *resv)
>  {
>         struct radeon_semaphore *sem = NULL;
> +       struct radeon_fence *fence;
>         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;
> @@ -3980,7 +3981,7 @@ int cik_copy_cpdma(struct radeon_device *rdev,
>         r = radeon_semaphore_create(rdev, &sem);
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
> @@ -3989,10 +3990,10 @@ int cik_copy_cpdma(struct radeon_device *rdev,
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
> -       radeon_semaphore_sync_to(sem, *fence);
> +       radeon_semaphore_sync_resv(sem, resv, false);
>         radeon_semaphore_sync_rings(rdev, sem, ring->idx);
>
>         for (i = 0; i < num_loops; i++) {
> @@ -4014,17 +4015,17 @@ int cik_copy_cpdma(struct radeon_device *rdev,
>                 dst_offset += cur_size_in_bytes;
>         }
>
> -       r = radeon_fence_emit(rdev, fence, ring->idx);
> +       r = radeon_fence_emit(rdev, &fence, ring->idx);
>         if (r) {
>                 radeon_ring_unlock_undo(rdev, ring);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         radeon_ring_unlock_commit(rdev, ring, false);
> -       radeon_semaphore_free(rdev, &sem, *fence);
> +       radeon_semaphore_free(rdev, &sem, fence);
>
> -       return r;
> +       return fence;
>  }
>
>  /*
> diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c
> index 192278b..c01a610 100644
> --- a/drivers/gpu/drm/radeon/cik_sdma.c
> +++ b/drivers/gpu/drm/radeon/cik_sdma.c
> @@ -537,18 +537,19 @@ void cik_sdma_fini(struct radeon_device *rdev)
>   * @src_offset: src GPU address
>   * @dst_offset: dst GPU address
>   * @num_gpu_pages: number of GPU pages to xfer
> - * @fence: radeon fence object
> + * @resv: reservation object to sync to
>   *
>   * Copy GPU paging using the DMA engine (CIK).
>   * Used by the radeon ttm implementation to move pages if
>   * registered as the asic copy callback.
>   */
> -int cik_copy_dma(struct radeon_device *rdev,
> -                uint64_t src_offset, uint64_t dst_offset,
> -                unsigned num_gpu_pages,
> -                struct radeon_fence **fence)
> +struct radeon_fence *cik_copy_dma(struct radeon_device *rdev,
> +                                 uint64_t src_offset, uint64_t dst_offset,
> +                                 unsigned num_gpu_pages,
> +                                 struct reservation_object *resv)
>  {
>         struct radeon_semaphore *sem = NULL;
> +       struct radeon_fence *fence;
>         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;
> @@ -558,7 +559,7 @@ int cik_copy_dma(struct radeon_device *rdev,
>         r = radeon_semaphore_create(rdev, &sem);
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
> @@ -567,10 +568,10 @@ int cik_copy_dma(struct radeon_device *rdev,
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
> -       radeon_semaphore_sync_to(sem, *fence);
> +       radeon_semaphore_sync_resv(sem, resv, false);
>         radeon_semaphore_sync_rings(rdev, sem, ring->idx);
>
>         for (i = 0; i < num_loops; i++) {
> @@ -589,17 +590,17 @@ int cik_copy_dma(struct radeon_device *rdev,
>                 dst_offset += cur_size_in_bytes;
>         }
>
> -       r = radeon_fence_emit(rdev, fence, ring->idx);
> +       r = radeon_fence_emit(rdev, &fence, ring->idx);
>         if (r) {
>                 radeon_ring_unlock_undo(rdev, ring);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         radeon_ring_unlock_commit(rdev, ring, false);
> -       radeon_semaphore_free(rdev, &sem, *fence);
> +       radeon_semaphore_free(rdev, &sem, fence);
>
> -       return r;
> +       return fence;
>  }
>
>  /**
> diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c
> index afaba38..946f37d 100644
> --- a/drivers/gpu/drm/radeon/evergreen_dma.c
> +++ b/drivers/gpu/drm/radeon/evergreen_dma.c
> @@ -104,12 +104,14 @@ void evergreen_dma_ring_ib_execute(struct radeon_device *rdev,
>   * Used by the radeon ttm implementation to move pages if
>   * registered as the asic copy callback.
>   */
> -int evergreen_copy_dma(struct radeon_device *rdev,
> -                      uint64_t src_offset, uint64_t dst_offset,
> -                      unsigned num_gpu_pages,
> -                      struct radeon_fence **fence)
> +struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev,
> +                                       uint64_t src_offset,
> +                                       uint64_t dst_offset,
> +                                       unsigned num_gpu_pages,
> +                                       struct reservation_object *resv)
>  {
>         struct radeon_semaphore *sem = NULL;
> +       struct radeon_fence *fence;
>         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;
> @@ -119,7 +121,7 @@ int evergreen_copy_dma(struct radeon_device *rdev,
>         r = radeon_semaphore_create(rdev, &sem);
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
> @@ -128,10 +130,10 @@ int evergreen_copy_dma(struct radeon_device *rdev,
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
> -       radeon_semaphore_sync_to(sem, *fence);
> +       radeon_semaphore_sync_resv(sem, resv, false);
>         radeon_semaphore_sync_rings(rdev, sem, ring->idx);
>
>         for (i = 0; i < num_loops; i++) {
> @@ -148,17 +150,17 @@ int evergreen_copy_dma(struct radeon_device *rdev,
>                 dst_offset += cur_size_in_dw * 4;
>         }
>
> -       r = radeon_fence_emit(rdev, fence, ring->idx);
> +       r = radeon_fence_emit(rdev, &fence, ring->idx);
>         if (r) {
>                 radeon_ring_unlock_undo(rdev, ring);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         radeon_ring_unlock_commit(rdev, ring, false);
> -       radeon_semaphore_free(rdev, &sem, *fence);
> +       radeon_semaphore_free(rdev, &sem, fence);
>
> -       return r;
> +       return fence;
>  }
>
>  /**
> diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
> index 4c5ec44..c6b486f 100644
> --- a/drivers/gpu/drm/radeon/r100.c
> +++ b/drivers/gpu/drm/radeon/r100.c
> @@ -855,13 +855,14 @@ bool r100_semaphore_ring_emit(struct radeon_device *rdev,
>         return false;
>  }
>
> -int r100_copy_blit(struct radeon_device *rdev,
> -                  uint64_t src_offset,
> -                  uint64_t dst_offset,
> -                  unsigned num_gpu_pages,
> -                  struct radeon_fence **fence)
> +struct radeon_fence *r100_copy_blit(struct radeon_device *rdev,
> +                                   uint64_t src_offset,
> +                                   uint64_t dst_offset,
> +                                   unsigned num_gpu_pages,
> +                                   struct reservation_object *resv)
>  {
>         struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
> +       struct radeon_fence *fence;
>         uint32_t cur_pages;
>         uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE;
>         uint32_t pitch;
> @@ -882,7 +883,7 @@ int r100_copy_blit(struct radeon_device *rdev,
>         r = radeon_ring_lock(rdev, ring, ndw);
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw);
> -               return -EINVAL;
> +               return ERR_PTR(-EINVAL);
>         }
>         while (num_gpu_pages > 0) {
>                 cur_pages = num_gpu_pages;
> @@ -922,11 +923,13 @@ int r100_copy_blit(struct radeon_device *rdev,
>                           RADEON_WAIT_2D_IDLECLEAN |
>                           RADEON_WAIT_HOST_IDLECLEAN |
>                           RADEON_WAIT_DMA_GUI_IDLE);
> -       if (fence) {
> -               r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX);
> +       r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
> +       if (r) {
> +               radeon_ring_unlock_undo(rdev, ring);
> +               return ERR_PTR(r);
>         }
>         radeon_ring_unlock_commit(rdev, ring, false);
> -       return r;
> +       return fence;
>  }
>
>  static int r100_cp_wait_for_idle(struct radeon_device *rdev)
> diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
> index 6778037..732d493 100644
> --- a/drivers/gpu/drm/radeon/r200.c
> +++ b/drivers/gpu/drm/radeon/r200.c
> @@ -80,13 +80,14 @@ static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
>         return vtx_size;
>  }
>
> -int r200_copy_dma(struct radeon_device *rdev,
> -                 uint64_t src_offset,
> -                 uint64_t dst_offset,
> -                 unsigned num_gpu_pages,
> -                 struct radeon_fence **fence)
> +struct radeon_fence *r200_copy_dma(struct radeon_device *rdev,
> +                                  uint64_t src_offset,
> +                                  uint64_t dst_offset,
> +                                  unsigned num_gpu_pages,
> +                                  struct reservation_object *resv)
>  {
>         struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
> +       struct radeon_fence *fence;
>         uint32_t size;
>         uint32_t cur_size;
>         int i, num_loops;
> @@ -98,7 +99,7 @@ int r200_copy_dma(struct radeon_device *rdev,
>         r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64);
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
> -               return r;
> +               return ERR_PTR(r);
>         }
>         /* Must wait for 2D idle & clean before DMA or hangs might happen */
>         radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
> @@ -118,11 +119,13 @@ int r200_copy_dma(struct radeon_device *rdev,
>         }
>         radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
>         radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE);
> -       if (fence) {
> -               r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX);
> +       r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
> +       if (r) {
> +               radeon_ring_unlock_undo(rdev, ring);
> +               return ERR_PTR(r);
>         }
>         radeon_ring_unlock_commit(rdev, ring, false);
> -       return r;
> +       return fence;
>  }
>
>
> diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
> index a95ced5..5e9146b 100644
> --- a/drivers/gpu/drm/radeon/r600.c
> +++ b/drivers/gpu/drm/radeon/r600.c
> @@ -2894,12 +2894,13 @@ bool r600_semaphore_ring_emit(struct radeon_device *rdev,
>   * Used by the radeon ttm implementation to move pages if
>   * registered as the asic copy callback.
>   */
> -int r600_copy_cpdma(struct radeon_device *rdev,
> -                   uint64_t src_offset, uint64_t dst_offset,
> -                   unsigned num_gpu_pages,
> -                   struct radeon_fence **fence)
> +struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev,
> +                                    uint64_t src_offset, uint64_t dst_offset,
> +                                    unsigned num_gpu_pages,
> +                                    struct reservation_object *resv)
>  {
>         struct radeon_semaphore *sem = NULL;
> +       struct radeon_fence *fence;
>         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;
> @@ -2909,7 +2910,7 @@ int r600_copy_cpdma(struct radeon_device *rdev,
>         r = radeon_semaphore_create(rdev, &sem);
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
> @@ -2918,10 +2919,10 @@ int r600_copy_cpdma(struct radeon_device *rdev,
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
> -       radeon_semaphore_sync_to(sem, *fence);
> +       radeon_semaphore_sync_resv(sem, resv, false);
>         radeon_semaphore_sync_rings(rdev, sem, ring->idx);
>
>         radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
> @@ -2948,17 +2949,17 @@ int r600_copy_cpdma(struct radeon_device *rdev,
>         radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
>         radeon_ring_write(ring, WAIT_CP_DMA_IDLE_bit);
>
> -       r = radeon_fence_emit(rdev, fence, ring->idx);
> +       r = radeon_fence_emit(rdev, &fence, ring->idx);
>         if (r) {
>                 radeon_ring_unlock_undo(rdev, ring);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         radeon_ring_unlock_commit(rdev, ring, false);
> -       radeon_semaphore_free(rdev, &sem, *fence);
> +       radeon_semaphore_free(rdev, &sem, fence);
>
> -       return r;
> +       return fence;
>  }
>
>  int r600_set_surface_reg(struct radeon_device *rdev, int reg,
> diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c
> index 51fd985..fc54224 100644
> --- a/drivers/gpu/drm/radeon/r600_dma.c
> +++ b/drivers/gpu/drm/radeon/r600_dma.c
> @@ -436,18 +436,19 @@ void r600_dma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
>   * @src_offset: src GPU address
>   * @dst_offset: dst GPU address
>   * @num_gpu_pages: number of GPU pages to xfer
> - * @fence: radeon fence object
> + * @resv: reservation object to sync to
>   *
>   * Copy GPU paging using the DMA engine (r6xx).
>   * Used by the radeon ttm implementation to move pages if
>   * registered as the asic copy callback.
>   */
> -int r600_copy_dma(struct radeon_device *rdev,
> -                 uint64_t src_offset, uint64_t dst_offset,
> -                 unsigned num_gpu_pages,
> -                 struct radeon_fence **fence)
> +struct radeon_fence *r600_copy_dma(struct radeon_device *rdev,
> +                                  uint64_t src_offset, uint64_t dst_offset,
> +                                  unsigned num_gpu_pages,
> +                                  struct reservation_object *resv)
>  {
>         struct radeon_semaphore *sem = NULL;
> +       struct radeon_fence *fence;
>         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;
> @@ -457,7 +458,7 @@ int r600_copy_dma(struct radeon_device *rdev,
>         r = radeon_semaphore_create(rdev, &sem);
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
> @@ -466,10 +467,10 @@ int r600_copy_dma(struct radeon_device *rdev,
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
> -       radeon_semaphore_sync_to(sem, *fence);
> +       radeon_semaphore_sync_resv(sem, resv, false);
>         radeon_semaphore_sync_rings(rdev, sem, ring->idx);
>
>         for (i = 0; i < num_loops; i++) {
> @@ -486,15 +487,15 @@ int r600_copy_dma(struct radeon_device *rdev,
>                 dst_offset += cur_size_in_dw * 4;
>         }
>
> -       r = radeon_fence_emit(rdev, fence, ring->idx);
> +       r = radeon_fence_emit(rdev, &fence, ring->idx);
>         if (r) {
>                 radeon_ring_unlock_undo(rdev, ring);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         radeon_ring_unlock_commit(rdev, ring, false);
> -       radeon_semaphore_free(rdev, &sem, *fence);
> +       radeon_semaphore_free(rdev, &sem, fence);
>
> -       return r;
> +       return fence;
>  }
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index d80dc54..fa27660 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -585,8 +585,11 @@ 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_to(struct radeon_semaphore *semaphore,
> -                             struct radeon_fence *fence);
> +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);
> @@ -1855,24 +1858,24 @@ struct radeon_asic {
>         } display;
>         /* copy functions for bo handling */
>         struct {
> -               int (*blit)(struct radeon_device *rdev,
> -                           uint64_t src_offset,
> -                           uint64_t dst_offset,
> -                           unsigned num_gpu_pages,
> -                           struct radeon_fence **fence);
> +               struct radeon_fence *(*blit)(struct radeon_device *rdev,
> +                                            uint64_t src_offset,
> +                                            uint64_t dst_offset,
> +                                            unsigned num_gpu_pages,
> +                                            struct reservation_object *resv);
>                 u32 blit_ring_index;
> -               int (*dma)(struct radeon_device *rdev,
> -                          uint64_t src_offset,
> -                          uint64_t dst_offset,
> -                          unsigned num_gpu_pages,
> -                          struct radeon_fence **fence);
> +               struct radeon_fence *(*dma)(struct radeon_device *rdev,
> +                                           uint64_t src_offset,
> +                                           uint64_t dst_offset,
> +                                           unsigned num_gpu_pages,
> +                                           struct reservation_object *resv);
>                 u32 dma_ring_index;
>                 /* method used for bo copy */
> -               int (*copy)(struct radeon_device *rdev,
> -                           uint64_t src_offset,
> -                           uint64_t dst_offset,
> -                           unsigned num_gpu_pages,
> -                           struct radeon_fence **fence);
> +               struct radeon_fence *(*copy)(struct radeon_device *rdev,
> +                                            uint64_t src_offset,
> +                                            uint64_t dst_offset,
> +                                            unsigned num_gpu_pages,
> +                                            struct reservation_object *resv);
>                 /* ring used for bo copies */
>                 u32 copy_ring_index;
>         } copy;
> @@ -2826,9 +2829,9 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
>  #define radeon_hdmi_setmode(rdev, e, m) (rdev)->asic->display.hdmi_setmode((e), (m))
>  #define radeon_fence_ring_emit(rdev, r, fence) (rdev)->asic->ring[(r)]->emit_fence((rdev), (fence))
>  #define radeon_semaphore_ring_emit(rdev, r, cp, semaphore, emit_wait) (rdev)->asic->ring[(r)]->emit_semaphore((rdev), (cp), (semaphore), (emit_wait))
> -#define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy.blit((rdev), (s), (d), (np), (f))
> -#define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy.dma((rdev), (s), (d), (np), (f))
> -#define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy.copy((rdev), (s), (d), (np), (f))
> +#define radeon_copy_blit(rdev, s, d, np, resv) (rdev)->asic->copy.blit((rdev), (s), (d), (np), (resv))
> +#define radeon_copy_dma(rdev, s, d, np, resv) (rdev)->asic->copy.dma((rdev), (s), (d), (np), (resv))
> +#define radeon_copy(rdev, s, d, np, resv) (rdev)->asic->copy.copy((rdev), (s), (d), (np), (resv))
>  #define radeon_copy_blit_ring_index(rdev) (rdev)->asic->copy.blit_ring_index
>  #define radeon_copy_dma_ring_index(rdev) (rdev)->asic->copy.dma_ring_index
>  #define radeon_copy_ring_index(rdev) (rdev)->asic->copy.copy_ring_index
> diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
> index 987a3b7..ca01bb8 100644
> --- a/drivers/gpu/drm/radeon/radeon_asic.h
> +++ b/drivers/gpu/drm/radeon/radeon_asic.h
> @@ -81,11 +81,11 @@ bool r100_semaphore_ring_emit(struct radeon_device *rdev,
>  int r100_cs_parse(struct radeon_cs_parser *p);
>  void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
>  uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg);
> -int r100_copy_blit(struct radeon_device *rdev,
> -                  uint64_t src_offset,
> -                  uint64_t dst_offset,
> -                  unsigned num_gpu_pages,
> -                  struct radeon_fence **fence);
> +struct radeon_fence *r100_copy_blit(struct radeon_device *rdev,
> +                                   uint64_t src_offset,
> +                                   uint64_t dst_offset,
> +                                   unsigned num_gpu_pages,
> +                                   struct reservation_object *resv);
>  int r100_set_surface_reg(struct radeon_device *rdev, int reg,
>                          uint32_t tiling_flags, uint32_t pitch,
>                          uint32_t offset, uint32_t obj_size);
> @@ -153,11 +153,11 @@ void r100_ring_hdp_flush(struct radeon_device *rdev,
>  /*
>   * r200,rv250,rs300,rv280
>   */
> -extern int r200_copy_dma(struct radeon_device *rdev,
> -                        uint64_t src_offset,
> -                        uint64_t dst_offset,
> -                        unsigned num_gpu_pages,
> -                        struct radeon_fence **fence);
> +struct radeon_fence *r200_copy_dma(struct radeon_device *rdev,
> +                                  uint64_t src_offset,
> +                                  uint64_t dst_offset,
> +                                  unsigned num_gpu_pages,
> +                                  struct reservation_object *resv);
>  void r200_set_safe_registers(struct radeon_device *rdev);
>
>  /*
> @@ -341,12 +341,14 @@ int r600_dma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
>  void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
>  int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *cp);
>  int r600_dma_ring_test(struct radeon_device *rdev, struct radeon_ring *cp);
> -int r600_copy_cpdma(struct radeon_device *rdev,
> -                   uint64_t src_offset, uint64_t dst_offset,
> -                   unsigned num_gpu_pages, struct radeon_fence **fence);
> -int r600_copy_dma(struct radeon_device *rdev,
> -                 uint64_t src_offset, uint64_t dst_offset,
> -                 unsigned num_gpu_pages, struct radeon_fence **fence);
> +struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev,
> +                                    uint64_t src_offset, uint64_t dst_offset,
> +                                    unsigned num_gpu_pages,
> +                                    struct reservation_object *resv);
> +struct radeon_fence *r600_copy_dma(struct radeon_device *rdev,
> +                                  uint64_t src_offset, uint64_t dst_offset,
> +                                  unsigned num_gpu_pages,
> +                                  struct reservation_object *resv);
>  void r600_hpd_init(struct radeon_device *rdev);
>  void r600_hpd_fini(struct radeon_device *rdev);
>  bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
> @@ -462,10 +464,10 @@ bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc);
>  void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
>  void r700_cp_stop(struct radeon_device *rdev);
>  void r700_cp_fini(struct radeon_device *rdev);
> -int rv770_copy_dma(struct radeon_device *rdev,
> -                 uint64_t src_offset, uint64_t dst_offset,
> -                 unsigned num_gpu_pages,
> -                  struct radeon_fence **fence);
> +struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev,
> +                                   uint64_t src_offset, uint64_t dst_offset,
> +                                   unsigned num_gpu_pages,
> +                                   struct reservation_object *resv);
>  u32 rv770_get_xclk(struct radeon_device *rdev);
>  int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
>  int rv770_get_temp(struct radeon_device *rdev);
> @@ -536,10 +538,10 @@ void evergreen_dma_fence_ring_emit(struct radeon_device *rdev,
>                                    struct radeon_fence *fence);
>  void evergreen_dma_ring_ib_execute(struct radeon_device *rdev,
>                                    struct radeon_ib *ib);
> -int evergreen_copy_dma(struct radeon_device *rdev,
> -                      uint64_t src_offset, uint64_t dst_offset,
> -                      unsigned num_gpu_pages,
> -                      struct radeon_fence **fence);
> +struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev,
> +                                       uint64_t src_offset, uint64_t dst_offset,
> +                                       unsigned num_gpu_pages,
> +                                       struct reservation_object *resv);
>  void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable);
>  void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
>  int evergreen_get_temp(struct radeon_device *rdev);
> @@ -701,10 +703,10 @@ int si_vm_init(struct radeon_device *rdev);
>  void si_vm_fini(struct radeon_device *rdev);
>  void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
>  int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
> -int si_copy_dma(struct radeon_device *rdev,
> -               uint64_t src_offset, uint64_t dst_offset,
> -               unsigned num_gpu_pages,
> -               struct radeon_fence **fence);
> +struct radeon_fence *si_copy_dma(struct radeon_device *rdev,
> +                                uint64_t src_offset, uint64_t dst_offset,
> +                                unsigned num_gpu_pages,
> +                                struct reservation_object *resv);
>
>  void si_dma_vm_copy_pages(struct radeon_device *rdev,
>                           struct radeon_ib *ib,
> @@ -760,14 +762,14 @@ bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
>                                   struct radeon_semaphore *semaphore,
>                                   bool emit_wait);
>  void cik_sdma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
> -int cik_copy_dma(struct radeon_device *rdev,
> -                uint64_t src_offset, uint64_t dst_offset,
> -                unsigned num_gpu_pages,
> -                struct radeon_fence **fence);
> -int cik_copy_cpdma(struct radeon_device *rdev,
> -                  uint64_t src_offset, uint64_t dst_offset,
> -                  unsigned num_gpu_pages,
> -                  struct radeon_fence **fence);
> +struct radeon_fence *cik_copy_dma(struct radeon_device *rdev,
> +                                 uint64_t src_offset, uint64_t dst_offset,
> +                                 unsigned num_gpu_pages,
> +                                 struct reservation_object *resv);
> +struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev,
> +                                   uint64_t src_offset, uint64_t dst_offset,
> +                                   unsigned num_gpu_pages,
> +                                   struct reservation_object *resv);
>  int cik_sdma_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
>  int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
>  bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
> diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c
> index 69f5695..1e88550 100644
> --- a/drivers/gpu/drm/radeon/radeon_benchmark.c
> +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c
> @@ -45,33 +45,29 @@ static int radeon_benchmark_do_move(struct radeon_device *rdev, unsigned size,
>         for (i = 0; i < n; i++) {
>                 switch (flag) {
>                 case RADEON_BENCHMARK_COPY_DMA:
> -                       r = radeon_copy_dma(rdev, saddr, daddr,
> -                                           size / RADEON_GPU_PAGE_SIZE,
> -                                           &fence);
> +                       fence = radeon_copy_dma(rdev, saddr, daddr,
> +                                               size / RADEON_GPU_PAGE_SIZE,
> +                                               NULL);
>                         break;
>                 case RADEON_BENCHMARK_COPY_BLIT:
> -                       r = radeon_copy_blit(rdev, saddr, daddr,
> -                                            size / RADEON_GPU_PAGE_SIZE,
> -                                            &fence);
> +                       fence = radeon_copy_blit(rdev, saddr, daddr,
> +                                                size / RADEON_GPU_PAGE_SIZE,
> +                                                NULL);
>                         break;
>                 default:
>                         DRM_ERROR("Unknown copy method\n");
> -                       r = -EINVAL;
> +                       return -EINVAL;
>                 }
> -               if (r)
> -                       goto exit_do_move;
> +               if (IS_ERR(fence))
> +                       return PTR_ERR(fence);
> +
>                 r = radeon_fence_wait(fence, false);
> -               if (r)
> -                       goto exit_do_move;
>                 radeon_fence_unref(&fence);
> +               if (r)
> +                       return r;
>         }
>         end_jiffies = jiffies;
> -       r = jiffies_to_msecs(end_jiffies - start_jiffies);
> -
> -exit_do_move:
> -       if (fence)
> -               radeon_fence_unref(&fence);
> -       return r;
> +       return jiffies_to_msecs(end_jiffies - start_jiffies);
>  }
>
>
> diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
> index cd517ab..ec4840c 100644
> --- a/drivers/gpu/drm/radeon/radeon_cs.c
> +++ b/drivers/gpu/drm/radeon/radeon_cs.c
> @@ -255,16 +255,12 @@ static void radeon_cs_sync_rings(struct radeon_cs_parser *p)
>
>         for (i = 0; i < p->nrelocs; i++) {
>                 struct reservation_object *resv;
> -               struct fence *fence;
>
>                 if (!p->relocs[i].robj)
>                         continue;
>
>                 resv = p->relocs[i].robj->tbo.resv;
> -               fence = reservation_object_get_excl(resv);
> -
> -               radeon_semaphore_sync_to(p->ib.semaphore,
> -                                        (struct radeon_fence *)fence);
> +               radeon_semaphore_sync_resv(p->ib.semaphore, resv, false);
>         }
>  }
>
> @@ -569,7 +565,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
>                 goto out;
>         }
>         radeon_cs_sync_rings(parser);
> -       radeon_semaphore_sync_to(parser->ib.semaphore, vm->fence);
> +       radeon_semaphore_sync_fence(parser->ib.semaphore, 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 6fc7461..3f39fcc 100644
> --- a/drivers/gpu/drm/radeon/radeon_ib.c
> +++ b/drivers/gpu/drm/radeon/radeon_ib.c
> @@ -145,7 +145,7 @@ 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_to(ib->semaphore, vm_id_fence);
> +               radeon_semaphore_sync_fence(ib->semaphore, vm_id_fence);
>         }
>
>         /* sync with other rings */
> diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c
> index 56d9fd6..5bfbd83 100644
> --- a/drivers/gpu/drm/radeon/radeon_semaphore.c
> +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
> @@ -96,15 +96,15 @@ bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ridx,
>  }
>
>  /**
> - * radeon_semaphore_sync_to - use the semaphore to sync to a fence
> + * 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_to(struct radeon_semaphore *semaphore,
> -                             struct radeon_fence *fence)
> +void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore,
> +                                struct radeon_fence *fence)
>  {
>          struct radeon_fence *other;
>
> @@ -116,6 +116,38 @@ void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore,
>  }
>
>  /**
> + * radeon_semaphore_sync_to - use the semaphore to sync to a reservation object
> + *

Copy-paste typo: radeon_semaphore_sync_to vs. radeon_semaphore_sync_resv


> + * @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
> diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
> index 17bc3dc..ce943e1 100644
> --- a/drivers/gpu/drm/radeon/radeon_test.c
> +++ b/drivers/gpu/drm/radeon/radeon_test.c
> @@ -116,11 +116,16 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag)
>                 radeon_bo_kunmap(gtt_obj[i]);
>
>                 if (ring == R600_RING_TYPE_DMA_INDEX)
> -                       r = radeon_copy_dma(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, &fence);
> +                       fence = radeon_copy_dma(rdev, gtt_addr, vram_addr,
> +                                               size / RADEON_GPU_PAGE_SIZE,
> +                                               NULL);
>                 else
> -                       r = radeon_copy_blit(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, &fence);
> -               if (r) {
> +                       fence = radeon_copy_blit(rdev, gtt_addr, vram_addr,
> +                                                size / RADEON_GPU_PAGE_SIZE,
> +                                                NULL);
> +               if (IS_ERR(fence)) {
>                         DRM_ERROR("Failed GTT->VRAM copy %d\n", i);
> +                       r = PTR_ERR(fence);
>                         goto out_lclean_unpin;
>                 }
>
> @@ -162,11 +167,16 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag)
>                 radeon_bo_kunmap(vram_obj);
>
>                 if (ring == R600_RING_TYPE_DMA_INDEX)
> -                       r = radeon_copy_dma(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, &fence);
> +                       fence = radeon_copy_dma(rdev, vram_addr, gtt_addr,
> +                                               size / RADEON_GPU_PAGE_SIZE,
> +                                               NULL);
>                 else
> -                       r = radeon_copy_blit(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, &fence);
> -               if (r) {
> +                       fence = radeon_copy_blit(rdev, vram_addr, gtt_addr,
> +                                                size / RADEON_GPU_PAGE_SIZE,
> +                                                NULL);
> +               if (IS_ERR(fence)) {
>                         DRM_ERROR("Failed VRAM->GTT copy %d\n", i);
> +                       r = PTR_ERR(fence);
>                         goto out_lclean_unpin;
>                 }
>
> @@ -222,7 +232,7 @@ out_lclean:
>                         radeon_bo_unreserve(gtt_obj[i]);
>                         radeon_bo_unref(&gtt_obj[i]);
>                 }
> -               if (fence)
> +               if (fence && !IS_ERR(fence))
>                         radeon_fence_unref(&fence);
>                 break;
>         }
> diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
> index 62d1f4d..eca2ce6 100644
> --- a/drivers/gpu/drm/radeon/radeon_ttm.c
> +++ b/drivers/gpu/drm/radeon/radeon_ttm.c
> @@ -233,6 +233,7 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
>         struct radeon_device *rdev;
>         uint64_t old_start, new_start;
>         struct radeon_fence *fence;
> +       unsigned num_pages;
>         int r, ridx;
>
>         rdev = radeon_get_rdev(bo->bdev);
> @@ -269,12 +270,11 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
>
>         BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0);
>
> -       /* sync other rings */
> -       fence = (struct radeon_fence *)reservation_object_get_excl(bo->resv);
> -       r = radeon_copy(rdev, old_start, new_start,
> -                       new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE), /* GPU pages */
> -                       &fence);
> -       /* FIXME: handle copy error */
> +       num_pages = new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE);
> +       fence = radeon_copy(rdev, old_start, new_start, num_pages, bo->resv);
> +       if (IS_ERR(fence))
> +               return PTR_ERR(fence);
> +
>         r = ttm_bo_move_accel_cleanup(bo, &fence->base,
>                                       evict, no_wait_gpu, new_mem);
>         radeon_fence_unref(&fence);
> diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
> index 1cce446..ce87095 100644
> --- a/drivers/gpu/drm/radeon/radeon_vm.c
> +++ b/drivers/gpu/drm/radeon/radeon_vm.c
> @@ -696,15 +696,10 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
>                                     incr, R600_PTE_VALID);
>
>         if (ib.length_dw != 0) {
> -               struct fence *fence;
> -
>                 radeon_asic_vm_pad_ib(rdev, &ib);
>
> -               fence = reservation_object_get_excl(pd->tbo.resv);
> -               radeon_semaphore_sync_to(ib.semaphore,
> -                                        (struct radeon_fence *)fence);
> -
> -               radeon_semaphore_sync_to(ib.semaphore, vm->last_id_use);
> +               radeon_semaphore_sync_resv(ib.semaphore, pd->tbo.resv, false);
> +               radeon_semaphore_sync_fence(ib.semaphore, vm->last_id_use);
>                 WARN_ON(ib.length_dw > ndw);
>                 r = radeon_ib_schedule(rdev, &ib, NULL, false);
>                 if (r) {
> @@ -829,11 +824,8 @@ 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;
> -               struct fence *fence;
>
> -               fence = reservation_object_get_excl(pt->tbo.resv);
> -               radeon_semaphore_sync_to(ib->semaphore,
> -                                        (struct radeon_fence *)fence);
> +               radeon_semaphore_sync_resv(ib->semaphore, pt->tbo.resv, false);
>
>                 if ((addr & ~mask) == (end & ~mask))
>                         nptes = end - addr;
> @@ -975,7 +967,7 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
>         radeon_asic_vm_pad_ib(rdev, &ib);
>         WARN_ON(ib.length_dw > ndw);
>
> -       radeon_semaphore_sync_to(ib.semaphore, vm->fence);
> +       radeon_semaphore_sync_fence(ib.semaphore, vm->fence);
>         r = radeon_ib_schedule(rdev, &ib, NULL, false);
>         if (r) {
>                 radeon_ib_free(rdev, &ib);
> diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c
> index 74426ac..c112764 100644
> --- a/drivers/gpu/drm/radeon/rv770_dma.c
> +++ b/drivers/gpu/drm/radeon/rv770_dma.c
> @@ -33,18 +33,19 @@
>   * @src_offset: src GPU address
>   * @dst_offset: dst GPU address
>   * @num_gpu_pages: number of GPU pages to xfer
> - * @fence: radeon fence object
> + * @resv: reservation object to sync to
>   *
>   * Copy GPU paging using the DMA engine (r7xx).
>   * Used by the radeon ttm implementation to move pages if
>   * registered as the asic copy callback.
>   */
> -int rv770_copy_dma(struct radeon_device *rdev,
> -                 uint64_t src_offset, uint64_t dst_offset,
> -                 unsigned num_gpu_pages,
> -                 struct radeon_fence **fence)
> +struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev,
> +                                   uint64_t src_offset, uint64_t dst_offset,
> +                                   unsigned num_gpu_pages,
> +                                   struct reservation_object *resv)
>  {
>         struct radeon_semaphore *sem = NULL;
> +       struct radeon_fence *fence;
>         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;
> @@ -54,7 +55,7 @@ int rv770_copy_dma(struct radeon_device *rdev,
>         r = radeon_semaphore_create(rdev, &sem);
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
> @@ -63,10 +64,10 @@ int rv770_copy_dma(struct radeon_device *rdev,
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
> -       radeon_semaphore_sync_to(sem, *fence);
> +       radeon_semaphore_sync_resv(sem, resv, false);
>         radeon_semaphore_sync_rings(rdev, sem, ring->idx);
>
>         for (i = 0; i < num_loops; i++) {
> @@ -83,15 +84,15 @@ int rv770_copy_dma(struct radeon_device *rdev,
>                 dst_offset += cur_size_in_dw * 4;
>         }
>
> -       r = radeon_fence_emit(rdev, fence, ring->idx);
> +       r = radeon_fence_emit(rdev, &fence, ring->idx);
>         if (r) {
>                 radeon_ring_unlock_undo(rdev, ring);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         radeon_ring_unlock_commit(rdev, ring, false);
> -       radeon_semaphore_free(rdev, &sem, *fence);
> +       radeon_semaphore_free(rdev, &sem, fence);
>
> -       return r;
> +       return fence;
>  }
> diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c
> index 7c22baa..9b0dfbc 100644
> --- a/drivers/gpu/drm/radeon/si_dma.c
> +++ b/drivers/gpu/drm/radeon/si_dma.c
> @@ -218,18 +218,19 @@ void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
>   * @src_offset: src GPU address
>   * @dst_offset: dst GPU address
>   * @num_gpu_pages: number of GPU pages to xfer
> - * @fence: radeon fence object
> + * @resv: reservation object to sync to
>   *
>   * Copy GPU paging using the DMA engine (SI).
>   * Used by the radeon ttm implementation to move pages if
>   * registered as the asic copy callback.
>   */
> -int si_copy_dma(struct radeon_device *rdev,
> -               uint64_t src_offset, uint64_t dst_offset,
> -               unsigned num_gpu_pages,
> -               struct radeon_fence **fence)
> +struct radeon_fence *si_copy_dma(struct radeon_device *rdev,
> +                                uint64_t src_offset, uint64_t dst_offset,
> +                                unsigned num_gpu_pages,
> +                                struct reservation_object *resv)
>  {
>         struct radeon_semaphore *sem = NULL;
> +       struct radeon_fence *fence;
>         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;
> @@ -239,7 +240,7 @@ int si_copy_dma(struct radeon_device *rdev,
>         r = radeon_semaphore_create(rdev, &sem);
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
> @@ -248,10 +249,10 @@ int si_copy_dma(struct radeon_device *rdev,
>         if (r) {
>                 DRM_ERROR("radeon: moving bo (%d).\n", r);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
> -       radeon_semaphore_sync_to(sem, *fence);
> +       radeon_semaphore_sync_resv(sem, resv, false);
>         radeon_semaphore_sync_rings(rdev, sem, ring->idx);
>
>         for (i = 0; i < num_loops; i++) {
> @@ -268,16 +269,16 @@ int si_copy_dma(struct radeon_device *rdev,
>                 dst_offset += cur_size_in_bytes;
>         }
>
> -       r = radeon_fence_emit(rdev, fence, ring->idx);
> +       r = radeon_fence_emit(rdev, &fence, ring->idx);
>         if (r) {
>                 radeon_ring_unlock_undo(rdev, ring);
>                 radeon_semaphore_free(rdev, &sem, NULL);
> -               return r;
> +               return ERR_PTR(r);
>         }
>
>         radeon_ring_unlock_commit(rdev, ring, false);
> -       radeon_semaphore_free(rdev, &sem, *fence);
> +       radeon_semaphore_free(rdev, &sem, fence);
>
> -       return r;
> +       return fence;
>  }
>
> --
> 1.9.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
diff mbox

Patch

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 1f598ab..0b5a230 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -3959,18 +3959,19 @@  bool cik_semaphore_ring_emit(struct radeon_device *rdev,
  * @src_offset: src GPU address
  * @dst_offset: dst GPU address
  * @num_gpu_pages: number of GPU pages to xfer
- * @fence: radeon fence object
+ * @resv: reservation object to sync to
  *
  * Copy GPU paging using the CP DMA engine (CIK+).
  * Used by the radeon ttm implementation to move pages if
  * registered as the asic copy callback.
  */
-int cik_copy_cpdma(struct radeon_device *rdev,
-		   uint64_t src_offset, uint64_t dst_offset,
-		   unsigned num_gpu_pages,
-		   struct radeon_fence **fence)
+struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev,
+				    uint64_t src_offset, uint64_t dst_offset,
+				    unsigned num_gpu_pages,
+				    struct reservation_object *resv)
 {
 	struct radeon_semaphore *sem = NULL;
+	struct radeon_fence *fence;
 	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;
@@ -3980,7 +3981,7 @@  int cik_copy_cpdma(struct radeon_device *rdev,
 	r = radeon_semaphore_create(rdev, &sem);
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
@@ -3989,10 +3990,10 @@  int cik_copy_cpdma(struct radeon_device *rdev,
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
-	radeon_semaphore_sync_to(sem, *fence);
+	radeon_semaphore_sync_resv(sem, resv, false);
 	radeon_semaphore_sync_rings(rdev, sem, ring->idx);
 
 	for (i = 0; i < num_loops; i++) {
@@ -4014,17 +4015,17 @@  int cik_copy_cpdma(struct radeon_device *rdev,
 		dst_offset += cur_size_in_bytes;
 	}
 
-	r = radeon_fence_emit(rdev, fence, ring->idx);
+	r = radeon_fence_emit(rdev, &fence, ring->idx);
 	if (r) {
 		radeon_ring_unlock_undo(rdev, ring);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	radeon_ring_unlock_commit(rdev, ring, false);
-	radeon_semaphore_free(rdev, &sem, *fence);
+	radeon_semaphore_free(rdev, &sem, fence);
 
-	return r;
+	return fence;
 }
 
 /*
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c
index 192278b..c01a610 100644
--- a/drivers/gpu/drm/radeon/cik_sdma.c
+++ b/drivers/gpu/drm/radeon/cik_sdma.c
@@ -537,18 +537,19 @@  void cik_sdma_fini(struct radeon_device *rdev)
  * @src_offset: src GPU address
  * @dst_offset: dst GPU address
  * @num_gpu_pages: number of GPU pages to xfer
- * @fence: radeon fence object
+ * @resv: reservation object to sync to
  *
  * Copy GPU paging using the DMA engine (CIK).
  * Used by the radeon ttm implementation to move pages if
  * registered as the asic copy callback.
  */
-int cik_copy_dma(struct radeon_device *rdev,
-		 uint64_t src_offset, uint64_t dst_offset,
-		 unsigned num_gpu_pages,
-		 struct radeon_fence **fence)
+struct radeon_fence *cik_copy_dma(struct radeon_device *rdev,
+				  uint64_t src_offset, uint64_t dst_offset,
+				  unsigned num_gpu_pages,
+				  struct reservation_object *resv)
 {
 	struct radeon_semaphore *sem = NULL;
+	struct radeon_fence *fence;
 	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;
@@ -558,7 +559,7 @@  int cik_copy_dma(struct radeon_device *rdev,
 	r = radeon_semaphore_create(rdev, &sem);
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
@@ -567,10 +568,10 @@  int cik_copy_dma(struct radeon_device *rdev,
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
-	radeon_semaphore_sync_to(sem, *fence);
+	radeon_semaphore_sync_resv(sem, resv, false);
 	radeon_semaphore_sync_rings(rdev, sem, ring->idx);
 
 	for (i = 0; i < num_loops; i++) {
@@ -589,17 +590,17 @@  int cik_copy_dma(struct radeon_device *rdev,
 		dst_offset += cur_size_in_bytes;
 	}
 
-	r = radeon_fence_emit(rdev, fence, ring->idx);
+	r = radeon_fence_emit(rdev, &fence, ring->idx);
 	if (r) {
 		radeon_ring_unlock_undo(rdev, ring);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	radeon_ring_unlock_commit(rdev, ring, false);
-	radeon_semaphore_free(rdev, &sem, *fence);
+	radeon_semaphore_free(rdev, &sem, fence);
 
-	return r;
+	return fence;
 }
 
 /**
diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c
index afaba38..946f37d 100644
--- a/drivers/gpu/drm/radeon/evergreen_dma.c
+++ b/drivers/gpu/drm/radeon/evergreen_dma.c
@@ -104,12 +104,14 @@  void evergreen_dma_ring_ib_execute(struct radeon_device *rdev,
  * Used by the radeon ttm implementation to move pages if
  * registered as the asic copy callback.
  */
-int evergreen_copy_dma(struct radeon_device *rdev,
-		       uint64_t src_offset, uint64_t dst_offset,
-		       unsigned num_gpu_pages,
-		       struct radeon_fence **fence)
+struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev,
+					uint64_t src_offset,
+					uint64_t dst_offset,
+					unsigned num_gpu_pages,
+					struct reservation_object *resv)
 {
 	struct radeon_semaphore *sem = NULL;
+	struct radeon_fence *fence;
 	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;
@@ -119,7 +121,7 @@  int evergreen_copy_dma(struct radeon_device *rdev,
 	r = radeon_semaphore_create(rdev, &sem);
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
@@ -128,10 +130,10 @@  int evergreen_copy_dma(struct radeon_device *rdev,
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
-	radeon_semaphore_sync_to(sem, *fence);
+	radeon_semaphore_sync_resv(sem, resv, false);
 	radeon_semaphore_sync_rings(rdev, sem, ring->idx);
 
 	for (i = 0; i < num_loops; i++) {
@@ -148,17 +150,17 @@  int evergreen_copy_dma(struct radeon_device *rdev,
 		dst_offset += cur_size_in_dw * 4;
 	}
 
-	r = radeon_fence_emit(rdev, fence, ring->idx);
+	r = radeon_fence_emit(rdev, &fence, ring->idx);
 	if (r) {
 		radeon_ring_unlock_undo(rdev, ring);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	radeon_ring_unlock_commit(rdev, ring, false);
-	radeon_semaphore_free(rdev, &sem, *fence);
+	radeon_semaphore_free(rdev, &sem, fence);
 
-	return r;
+	return fence;
 }
 
 /**
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 4c5ec44..c6b486f 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -855,13 +855,14 @@  bool r100_semaphore_ring_emit(struct radeon_device *rdev,
 	return false;
 }
 
-int r100_copy_blit(struct radeon_device *rdev,
-		   uint64_t src_offset,
-		   uint64_t dst_offset,
-		   unsigned num_gpu_pages,
-		   struct radeon_fence **fence)
+struct radeon_fence *r100_copy_blit(struct radeon_device *rdev,
+				    uint64_t src_offset,
+				    uint64_t dst_offset,
+				    unsigned num_gpu_pages,
+				    struct reservation_object *resv)
 {
 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+	struct radeon_fence *fence;
 	uint32_t cur_pages;
 	uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE;
 	uint32_t pitch;
@@ -882,7 +883,7 @@  int r100_copy_blit(struct radeon_device *rdev,
 	r = radeon_ring_lock(rdev, ring, ndw);
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw);
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 	}
 	while (num_gpu_pages > 0) {
 		cur_pages = num_gpu_pages;
@@ -922,11 +923,13 @@  int r100_copy_blit(struct radeon_device *rdev,
 			  RADEON_WAIT_2D_IDLECLEAN |
 			  RADEON_WAIT_HOST_IDLECLEAN |
 			  RADEON_WAIT_DMA_GUI_IDLE);
-	if (fence) {
-		r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX);
+	r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
+	if (r) {
+		radeon_ring_unlock_undo(rdev, ring);
+		return ERR_PTR(r);
 	}
 	radeon_ring_unlock_commit(rdev, ring, false);
-	return r;
+	return fence;
 }
 
 static int r100_cp_wait_for_idle(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
index 6778037..732d493 100644
--- a/drivers/gpu/drm/radeon/r200.c
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -80,13 +80,14 @@  static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
 	return vtx_size;
 }
 
-int r200_copy_dma(struct radeon_device *rdev,
-		  uint64_t src_offset,
-		  uint64_t dst_offset,
-		  unsigned num_gpu_pages,
-		  struct radeon_fence **fence)
+struct radeon_fence *r200_copy_dma(struct radeon_device *rdev,
+				   uint64_t src_offset,
+				   uint64_t dst_offset,
+				   unsigned num_gpu_pages,
+				   struct reservation_object *resv)
 {
 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+	struct radeon_fence *fence;
 	uint32_t size;
 	uint32_t cur_size;
 	int i, num_loops;
@@ -98,7 +99,7 @@  int r200_copy_dma(struct radeon_device *rdev,
 	r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64);
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
-		return r;
+		return ERR_PTR(r);
 	}
 	/* Must wait for 2D idle & clean before DMA or hangs might happen */
 	radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
@@ -118,11 +119,13 @@  int r200_copy_dma(struct radeon_device *rdev,
 	}
 	radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
 	radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE);
-	if (fence) {
-		r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX);
+	r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
+	if (r) {
+		radeon_ring_unlock_undo(rdev, ring);
+		return ERR_PTR(r);
 	}
 	radeon_ring_unlock_commit(rdev, ring, false);
-	return r;
+	return fence;
 }
 
 
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index a95ced5..5e9146b 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2894,12 +2894,13 @@  bool r600_semaphore_ring_emit(struct radeon_device *rdev,
  * Used by the radeon ttm implementation to move pages if
  * registered as the asic copy callback.
  */
-int r600_copy_cpdma(struct radeon_device *rdev,
-		    uint64_t src_offset, uint64_t dst_offset,
-		    unsigned num_gpu_pages,
-		    struct radeon_fence **fence)
+struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev,
+				     uint64_t src_offset, uint64_t dst_offset,
+				     unsigned num_gpu_pages,
+				     struct reservation_object *resv)
 {
 	struct radeon_semaphore *sem = NULL;
+	struct radeon_fence *fence;
 	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;
@@ -2909,7 +2910,7 @@  int r600_copy_cpdma(struct radeon_device *rdev,
 	r = radeon_semaphore_create(rdev, &sem);
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
@@ -2918,10 +2919,10 @@  int r600_copy_cpdma(struct radeon_device *rdev,
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
-	radeon_semaphore_sync_to(sem, *fence);
+	radeon_semaphore_sync_resv(sem, resv, false);
 	radeon_semaphore_sync_rings(rdev, sem, ring->idx);
 
 	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
@@ -2948,17 +2949,17 @@  int r600_copy_cpdma(struct radeon_device *rdev,
 	radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
 	radeon_ring_write(ring, WAIT_CP_DMA_IDLE_bit);
 
-	r = radeon_fence_emit(rdev, fence, ring->idx);
+	r = radeon_fence_emit(rdev, &fence, ring->idx);
 	if (r) {
 		radeon_ring_unlock_undo(rdev, ring);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	radeon_ring_unlock_commit(rdev, ring, false);
-	radeon_semaphore_free(rdev, &sem, *fence);
+	radeon_semaphore_free(rdev, &sem, fence);
 
-	return r;
+	return fence;
 }
 
 int r600_set_surface_reg(struct radeon_device *rdev, int reg,
diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c
index 51fd985..fc54224 100644
--- a/drivers/gpu/drm/radeon/r600_dma.c
+++ b/drivers/gpu/drm/radeon/r600_dma.c
@@ -436,18 +436,19 @@  void r600_dma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
  * @src_offset: src GPU address
  * @dst_offset: dst GPU address
  * @num_gpu_pages: number of GPU pages to xfer
- * @fence: radeon fence object
+ * @resv: reservation object to sync to
  *
  * Copy GPU paging using the DMA engine (r6xx).
  * Used by the radeon ttm implementation to move pages if
  * registered as the asic copy callback.
  */
-int r600_copy_dma(struct radeon_device *rdev,
-		  uint64_t src_offset, uint64_t dst_offset,
-		  unsigned num_gpu_pages,
-		  struct radeon_fence **fence)
+struct radeon_fence *r600_copy_dma(struct radeon_device *rdev,
+				   uint64_t src_offset, uint64_t dst_offset,
+				   unsigned num_gpu_pages,
+				   struct reservation_object *resv)
 {
 	struct radeon_semaphore *sem = NULL;
+	struct radeon_fence *fence;
 	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;
@@ -457,7 +458,7 @@  int r600_copy_dma(struct radeon_device *rdev,
 	r = radeon_semaphore_create(rdev, &sem);
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
@@ -466,10 +467,10 @@  int r600_copy_dma(struct radeon_device *rdev,
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
-	radeon_semaphore_sync_to(sem, *fence);
+	radeon_semaphore_sync_resv(sem, resv, false);
 	radeon_semaphore_sync_rings(rdev, sem, ring->idx);
 
 	for (i = 0; i < num_loops; i++) {
@@ -486,15 +487,15 @@  int r600_copy_dma(struct radeon_device *rdev,
 		dst_offset += cur_size_in_dw * 4;
 	}
 
-	r = radeon_fence_emit(rdev, fence, ring->idx);
+	r = radeon_fence_emit(rdev, &fence, ring->idx);
 	if (r) {
 		radeon_ring_unlock_undo(rdev, ring);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	radeon_ring_unlock_commit(rdev, ring, false);
-	radeon_semaphore_free(rdev, &sem, *fence);
+	radeon_semaphore_free(rdev, &sem, fence);
 
-	return r;
+	return fence;
 }
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index d80dc54..fa27660 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -585,8 +585,11 @@  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_to(struct radeon_semaphore *semaphore,
-			      struct radeon_fence *fence);
+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);
@@ -1855,24 +1858,24 @@  struct radeon_asic {
 	} display;
 	/* copy functions for bo handling */
 	struct {
-		int (*blit)(struct radeon_device *rdev,
-			    uint64_t src_offset,
-			    uint64_t dst_offset,
-			    unsigned num_gpu_pages,
-			    struct radeon_fence **fence);
+		struct radeon_fence *(*blit)(struct radeon_device *rdev,
+					     uint64_t src_offset,
+					     uint64_t dst_offset,
+					     unsigned num_gpu_pages,
+					     struct reservation_object *resv);
 		u32 blit_ring_index;
-		int (*dma)(struct radeon_device *rdev,
-			   uint64_t src_offset,
-			   uint64_t dst_offset,
-			   unsigned num_gpu_pages,
-			   struct radeon_fence **fence);
+		struct radeon_fence *(*dma)(struct radeon_device *rdev,
+					    uint64_t src_offset,
+					    uint64_t dst_offset,
+					    unsigned num_gpu_pages,
+					    struct reservation_object *resv);
 		u32 dma_ring_index;
 		/* method used for bo copy */
-		int (*copy)(struct radeon_device *rdev,
-			    uint64_t src_offset,
-			    uint64_t dst_offset,
-			    unsigned num_gpu_pages,
-			    struct radeon_fence **fence);
+		struct radeon_fence *(*copy)(struct radeon_device *rdev,
+					     uint64_t src_offset,
+					     uint64_t dst_offset,
+					     unsigned num_gpu_pages,
+					     struct reservation_object *resv);
 		/* ring used for bo copies */
 		u32 copy_ring_index;
 	} copy;
@@ -2826,9 +2829,9 @@  void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
 #define radeon_hdmi_setmode(rdev, e, m) (rdev)->asic->display.hdmi_setmode((e), (m))
 #define radeon_fence_ring_emit(rdev, r, fence) (rdev)->asic->ring[(r)]->emit_fence((rdev), (fence))
 #define radeon_semaphore_ring_emit(rdev, r, cp, semaphore, emit_wait) (rdev)->asic->ring[(r)]->emit_semaphore((rdev), (cp), (semaphore), (emit_wait))
-#define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy.blit((rdev), (s), (d), (np), (f))
-#define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy.dma((rdev), (s), (d), (np), (f))
-#define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy.copy((rdev), (s), (d), (np), (f))
+#define radeon_copy_blit(rdev, s, d, np, resv) (rdev)->asic->copy.blit((rdev), (s), (d), (np), (resv))
+#define radeon_copy_dma(rdev, s, d, np, resv) (rdev)->asic->copy.dma((rdev), (s), (d), (np), (resv))
+#define radeon_copy(rdev, s, d, np, resv) (rdev)->asic->copy.copy((rdev), (s), (d), (np), (resv))
 #define radeon_copy_blit_ring_index(rdev) (rdev)->asic->copy.blit_ring_index
 #define radeon_copy_dma_ring_index(rdev) (rdev)->asic->copy.dma_ring_index
 #define radeon_copy_ring_index(rdev) (rdev)->asic->copy.copy_ring_index
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 987a3b7..ca01bb8 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -81,11 +81,11 @@  bool r100_semaphore_ring_emit(struct radeon_device *rdev,
 int r100_cs_parse(struct radeon_cs_parser *p);
 void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg);
-int r100_copy_blit(struct radeon_device *rdev,
-		   uint64_t src_offset,
-		   uint64_t dst_offset,
-		   unsigned num_gpu_pages,
-		   struct radeon_fence **fence);
+struct radeon_fence *r100_copy_blit(struct radeon_device *rdev,
+				    uint64_t src_offset,
+				    uint64_t dst_offset,
+				    unsigned num_gpu_pages,
+				    struct reservation_object *resv);
 int r100_set_surface_reg(struct radeon_device *rdev, int reg,
 			 uint32_t tiling_flags, uint32_t pitch,
 			 uint32_t offset, uint32_t obj_size);
@@ -153,11 +153,11 @@  void r100_ring_hdp_flush(struct radeon_device *rdev,
 /*
  * r200,rv250,rs300,rv280
  */
-extern int r200_copy_dma(struct radeon_device *rdev,
-			 uint64_t src_offset,
-			 uint64_t dst_offset,
-			 unsigned num_gpu_pages,
-			 struct radeon_fence **fence);
+struct radeon_fence *r200_copy_dma(struct radeon_device *rdev,
+				   uint64_t src_offset,
+				   uint64_t dst_offset,
+				   unsigned num_gpu_pages,
+				   struct reservation_object *resv);
 void r200_set_safe_registers(struct radeon_device *rdev);
 
 /*
@@ -341,12 +341,14 @@  int r600_dma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
 void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
 int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *cp);
 int r600_dma_ring_test(struct radeon_device *rdev, struct radeon_ring *cp);
-int r600_copy_cpdma(struct radeon_device *rdev,
-		    uint64_t src_offset, uint64_t dst_offset,
-		    unsigned num_gpu_pages, struct radeon_fence **fence);
-int r600_copy_dma(struct radeon_device *rdev,
-		  uint64_t src_offset, uint64_t dst_offset,
-		  unsigned num_gpu_pages, struct radeon_fence **fence);
+struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev,
+				     uint64_t src_offset, uint64_t dst_offset,
+				     unsigned num_gpu_pages,
+				     struct reservation_object *resv);
+struct radeon_fence *r600_copy_dma(struct radeon_device *rdev,
+				   uint64_t src_offset, uint64_t dst_offset,
+				   unsigned num_gpu_pages,
+				   struct reservation_object *resv);
 void r600_hpd_init(struct radeon_device *rdev);
 void r600_hpd_fini(struct radeon_device *rdev);
 bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
@@ -462,10 +464,10 @@  bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc);
 void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
 void r700_cp_stop(struct radeon_device *rdev);
 void r700_cp_fini(struct radeon_device *rdev);
-int rv770_copy_dma(struct radeon_device *rdev,
-		  uint64_t src_offset, uint64_t dst_offset,
-		  unsigned num_gpu_pages,
-		   struct radeon_fence **fence);
+struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev,
+				    uint64_t src_offset, uint64_t dst_offset,
+				    unsigned num_gpu_pages,
+				    struct reservation_object *resv);
 u32 rv770_get_xclk(struct radeon_device *rdev);
 int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
 int rv770_get_temp(struct radeon_device *rdev);
@@ -536,10 +538,10 @@  void evergreen_dma_fence_ring_emit(struct radeon_device *rdev,
 				   struct radeon_fence *fence);
 void evergreen_dma_ring_ib_execute(struct radeon_device *rdev,
 				   struct radeon_ib *ib);
-int evergreen_copy_dma(struct radeon_device *rdev,
-		       uint64_t src_offset, uint64_t dst_offset,
-		       unsigned num_gpu_pages,
-		       struct radeon_fence **fence);
+struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev,
+					uint64_t src_offset, uint64_t dst_offset,
+					unsigned num_gpu_pages,
+					struct reservation_object *resv);
 void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable);
 void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
 int evergreen_get_temp(struct radeon_device *rdev);
@@ -701,10 +703,10 @@  int si_vm_init(struct radeon_device *rdev);
 void si_vm_fini(struct radeon_device *rdev);
 void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
 int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
-int si_copy_dma(struct radeon_device *rdev,
-		uint64_t src_offset, uint64_t dst_offset,
-		unsigned num_gpu_pages,
-		struct radeon_fence **fence);
+struct radeon_fence *si_copy_dma(struct radeon_device *rdev,
+				 uint64_t src_offset, uint64_t dst_offset,
+				 unsigned num_gpu_pages,
+				 struct reservation_object *resv);
 
 void si_dma_vm_copy_pages(struct radeon_device *rdev,
 			  struct radeon_ib *ib,
@@ -760,14 +762,14 @@  bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
 				  struct radeon_semaphore *semaphore,
 				  bool emit_wait);
 void cik_sdma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
-int cik_copy_dma(struct radeon_device *rdev,
-		 uint64_t src_offset, uint64_t dst_offset,
-		 unsigned num_gpu_pages,
-		 struct radeon_fence **fence);
-int cik_copy_cpdma(struct radeon_device *rdev,
-		   uint64_t src_offset, uint64_t dst_offset,
-		   unsigned num_gpu_pages,
-		   struct radeon_fence **fence);
+struct radeon_fence *cik_copy_dma(struct radeon_device *rdev,
+				  uint64_t src_offset, uint64_t dst_offset,
+				  unsigned num_gpu_pages,
+				  struct reservation_object *resv);
+struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev,
+				    uint64_t src_offset, uint64_t dst_offset,
+				    unsigned num_gpu_pages,
+				    struct reservation_object *resv);
 int cik_sdma_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
 int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
 bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c
index 69f5695..1e88550 100644
--- a/drivers/gpu/drm/radeon/radeon_benchmark.c
+++ b/drivers/gpu/drm/radeon/radeon_benchmark.c
@@ -45,33 +45,29 @@  static int radeon_benchmark_do_move(struct radeon_device *rdev, unsigned size,
 	for (i = 0; i < n; i++) {
 		switch (flag) {
 		case RADEON_BENCHMARK_COPY_DMA:
-			r = radeon_copy_dma(rdev, saddr, daddr,
-					    size / RADEON_GPU_PAGE_SIZE,
-					    &fence);
+			fence = radeon_copy_dma(rdev, saddr, daddr,
+						size / RADEON_GPU_PAGE_SIZE,
+						NULL);
 			break;
 		case RADEON_BENCHMARK_COPY_BLIT:
-			r = radeon_copy_blit(rdev, saddr, daddr,
-					     size / RADEON_GPU_PAGE_SIZE,
-					     &fence);
+			fence = radeon_copy_blit(rdev, saddr, daddr,
+						 size / RADEON_GPU_PAGE_SIZE,
+						 NULL);
 			break;
 		default:
 			DRM_ERROR("Unknown copy method\n");
-			r = -EINVAL;
+			return -EINVAL;
 		}
-		if (r)
-			goto exit_do_move;
+		if (IS_ERR(fence))
+			return PTR_ERR(fence);
+
 		r = radeon_fence_wait(fence, false);
-		if (r)
-			goto exit_do_move;
 		radeon_fence_unref(&fence);
+		if (r)
+			return r;
 	}
 	end_jiffies = jiffies;
-	r = jiffies_to_msecs(end_jiffies - start_jiffies);
-
-exit_do_move:
-	if (fence)
-		radeon_fence_unref(&fence);
-	return r;
+	return jiffies_to_msecs(end_jiffies - start_jiffies);
 }
 
 
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index cd517ab..ec4840c 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -255,16 +255,12 @@  static void radeon_cs_sync_rings(struct radeon_cs_parser *p)
 
 	for (i = 0; i < p->nrelocs; i++) {
 		struct reservation_object *resv;
-		struct fence *fence;
 
 		if (!p->relocs[i].robj)
 			continue;
 
 		resv = p->relocs[i].robj->tbo.resv;
-		fence = reservation_object_get_excl(resv);
-
-		radeon_semaphore_sync_to(p->ib.semaphore,
-					 (struct radeon_fence *)fence);
+		radeon_semaphore_sync_resv(p->ib.semaphore, resv, false);
 	}
 }
 
@@ -569,7 +565,7 @@  static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
 		goto out;
 	}
 	radeon_cs_sync_rings(parser);
-	radeon_semaphore_sync_to(parser->ib.semaphore, vm->fence);
+	radeon_semaphore_sync_fence(parser->ib.semaphore, 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 6fc7461..3f39fcc 100644
--- a/drivers/gpu/drm/radeon/radeon_ib.c
+++ b/drivers/gpu/drm/radeon/radeon_ib.c
@@ -145,7 +145,7 @@  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_to(ib->semaphore, vm_id_fence);
+		radeon_semaphore_sync_fence(ib->semaphore, vm_id_fence);
 	}
 
 	/* sync with other rings */
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c
index 56d9fd6..5bfbd83 100644
--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -96,15 +96,15 @@  bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ridx,
 }
 
 /**
- * radeon_semaphore_sync_to - use the semaphore to sync to a fence
+ * 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_to(struct radeon_semaphore *semaphore,
-			      struct radeon_fence *fence)
+void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore,
+				 struct radeon_fence *fence)
 {
         struct radeon_fence *other;
 
@@ -116,6 +116,38 @@  void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore,
 }
 
 /**
+ * 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
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
index 17bc3dc..ce943e1 100644
--- a/drivers/gpu/drm/radeon/radeon_test.c
+++ b/drivers/gpu/drm/radeon/radeon_test.c
@@ -116,11 +116,16 @@  static void radeon_do_test_moves(struct radeon_device *rdev, int flag)
 		radeon_bo_kunmap(gtt_obj[i]);
 
 		if (ring == R600_RING_TYPE_DMA_INDEX)
-			r = radeon_copy_dma(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, &fence);
+			fence = radeon_copy_dma(rdev, gtt_addr, vram_addr,
+						size / RADEON_GPU_PAGE_SIZE,
+						NULL);
 		else
-			r = radeon_copy_blit(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, &fence);
-		if (r) {
+			fence = radeon_copy_blit(rdev, gtt_addr, vram_addr,
+						 size / RADEON_GPU_PAGE_SIZE,
+						 NULL);
+		if (IS_ERR(fence)) {
 			DRM_ERROR("Failed GTT->VRAM copy %d\n", i);
+			r = PTR_ERR(fence);
 			goto out_lclean_unpin;
 		}
 
@@ -162,11 +167,16 @@  static void radeon_do_test_moves(struct radeon_device *rdev, int flag)
 		radeon_bo_kunmap(vram_obj);
 
 		if (ring == R600_RING_TYPE_DMA_INDEX)
-			r = radeon_copy_dma(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, &fence);
+			fence = radeon_copy_dma(rdev, vram_addr, gtt_addr,
+						size / RADEON_GPU_PAGE_SIZE,
+						NULL);
 		else
-			r = radeon_copy_blit(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, &fence);
-		if (r) {
+			fence = radeon_copy_blit(rdev, vram_addr, gtt_addr,
+						 size / RADEON_GPU_PAGE_SIZE,
+						 NULL);
+		if (IS_ERR(fence)) {
 			DRM_ERROR("Failed VRAM->GTT copy %d\n", i);
+			r = PTR_ERR(fence);
 			goto out_lclean_unpin;
 		}
 
@@ -222,7 +232,7 @@  out_lclean:
 			radeon_bo_unreserve(gtt_obj[i]);
 			radeon_bo_unref(&gtt_obj[i]);
 		}
-		if (fence)
+		if (fence && !IS_ERR(fence))
 			radeon_fence_unref(&fence);
 		break;
 	}
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 62d1f4d..eca2ce6 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -233,6 +233,7 @@  static int radeon_move_blit(struct ttm_buffer_object *bo,
 	struct radeon_device *rdev;
 	uint64_t old_start, new_start;
 	struct radeon_fence *fence;
+	unsigned num_pages;
 	int r, ridx;
 
 	rdev = radeon_get_rdev(bo->bdev);
@@ -269,12 +270,11 @@  static int radeon_move_blit(struct ttm_buffer_object *bo,
 
 	BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0);
 
-	/* sync other rings */
-	fence = (struct radeon_fence *)reservation_object_get_excl(bo->resv);
-	r = radeon_copy(rdev, old_start, new_start,
-			new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE), /* GPU pages */
-			&fence);
-	/* FIXME: handle copy error */
+	num_pages = new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE);
+	fence = radeon_copy(rdev, old_start, new_start, num_pages, bo->resv);
+	if (IS_ERR(fence))
+		return PTR_ERR(fence);
+
 	r = ttm_bo_move_accel_cleanup(bo, &fence->base,
 				      evict, no_wait_gpu, new_mem);
 	radeon_fence_unref(&fence);
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
index 1cce446..ce87095 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -696,15 +696,10 @@  int radeon_vm_update_page_directory(struct radeon_device *rdev,
 				    incr, R600_PTE_VALID);
 
 	if (ib.length_dw != 0) {
-		struct fence *fence;
-
 		radeon_asic_vm_pad_ib(rdev, &ib);
 
-		fence = reservation_object_get_excl(pd->tbo.resv);
-		radeon_semaphore_sync_to(ib.semaphore,
-					 (struct radeon_fence *)fence);
-
-		radeon_semaphore_sync_to(ib.semaphore, vm->last_id_use);
+		radeon_semaphore_sync_resv(ib.semaphore, pd->tbo.resv, false);
+		radeon_semaphore_sync_fence(ib.semaphore, vm->last_id_use);
 		WARN_ON(ib.length_dw > ndw);
 		r = radeon_ib_schedule(rdev, &ib, NULL, false);
 		if (r) {
@@ -829,11 +824,8 @@  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;
-		struct fence *fence;
 
-		fence = reservation_object_get_excl(pt->tbo.resv);
-		radeon_semaphore_sync_to(ib->semaphore,
-					 (struct radeon_fence *)fence);
+		radeon_semaphore_sync_resv(ib->semaphore, pt->tbo.resv, false);
 
 		if ((addr & ~mask) == (end & ~mask))
 			nptes = end - addr;
@@ -975,7 +967,7 @@  int radeon_vm_bo_update(struct radeon_device *rdev,
 	radeon_asic_vm_pad_ib(rdev, &ib);
 	WARN_ON(ib.length_dw > ndw);
 
-	radeon_semaphore_sync_to(ib.semaphore, vm->fence);
+	radeon_semaphore_sync_fence(ib.semaphore, vm->fence);
 	r = radeon_ib_schedule(rdev, &ib, NULL, false);
 	if (r) {
 		radeon_ib_free(rdev, &ib);
diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c
index 74426ac..c112764 100644
--- a/drivers/gpu/drm/radeon/rv770_dma.c
+++ b/drivers/gpu/drm/radeon/rv770_dma.c
@@ -33,18 +33,19 @@ 
  * @src_offset: src GPU address
  * @dst_offset: dst GPU address
  * @num_gpu_pages: number of GPU pages to xfer
- * @fence: radeon fence object
+ * @resv: reservation object to sync to
  *
  * Copy GPU paging using the DMA engine (r7xx).
  * Used by the radeon ttm implementation to move pages if
  * registered as the asic copy callback.
  */
-int rv770_copy_dma(struct radeon_device *rdev,
-		  uint64_t src_offset, uint64_t dst_offset,
-		  unsigned num_gpu_pages,
-		  struct radeon_fence **fence)
+struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev,
+				    uint64_t src_offset, uint64_t dst_offset,
+				    unsigned num_gpu_pages,
+				    struct reservation_object *resv)
 {
 	struct radeon_semaphore *sem = NULL;
+	struct radeon_fence *fence;
 	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;
@@ -54,7 +55,7 @@  int rv770_copy_dma(struct radeon_device *rdev,
 	r = radeon_semaphore_create(rdev, &sem);
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
@@ -63,10 +64,10 @@  int rv770_copy_dma(struct radeon_device *rdev,
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
-	radeon_semaphore_sync_to(sem, *fence);
+	radeon_semaphore_sync_resv(sem, resv, false);
 	radeon_semaphore_sync_rings(rdev, sem, ring->idx);
 
 	for (i = 0; i < num_loops; i++) {
@@ -83,15 +84,15 @@  int rv770_copy_dma(struct radeon_device *rdev,
 		dst_offset += cur_size_in_dw * 4;
 	}
 
-	r = radeon_fence_emit(rdev, fence, ring->idx);
+	r = radeon_fence_emit(rdev, &fence, ring->idx);
 	if (r) {
 		radeon_ring_unlock_undo(rdev, ring);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	radeon_ring_unlock_commit(rdev, ring, false);
-	radeon_semaphore_free(rdev, &sem, *fence);
+	radeon_semaphore_free(rdev, &sem, fence);
 
-	return r;
+	return fence;
 }
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c
index 7c22baa..9b0dfbc 100644
--- a/drivers/gpu/drm/radeon/si_dma.c
+++ b/drivers/gpu/drm/radeon/si_dma.c
@@ -218,18 +218,19 @@  void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
  * @src_offset: src GPU address
  * @dst_offset: dst GPU address
  * @num_gpu_pages: number of GPU pages to xfer
- * @fence: radeon fence object
+ * @resv: reservation object to sync to
  *
  * Copy GPU paging using the DMA engine (SI).
  * Used by the radeon ttm implementation to move pages if
  * registered as the asic copy callback.
  */
-int si_copy_dma(struct radeon_device *rdev,
-		uint64_t src_offset, uint64_t dst_offset,
-		unsigned num_gpu_pages,
-		struct radeon_fence **fence)
+struct radeon_fence *si_copy_dma(struct radeon_device *rdev,
+				 uint64_t src_offset, uint64_t dst_offset,
+				 unsigned num_gpu_pages,
+				 struct reservation_object *resv)
 {
 	struct radeon_semaphore *sem = NULL;
+	struct radeon_fence *fence;
 	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;
@@ -239,7 +240,7 @@  int si_copy_dma(struct radeon_device *rdev,
 	r = radeon_semaphore_create(rdev, &sem);
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
@@ -248,10 +249,10 @@  int si_copy_dma(struct radeon_device *rdev,
 	if (r) {
 		DRM_ERROR("radeon: moving bo (%d).\n", r);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
-	radeon_semaphore_sync_to(sem, *fence);
+	radeon_semaphore_sync_resv(sem, resv, false);
 	radeon_semaphore_sync_rings(rdev, sem, ring->idx);
 
 	for (i = 0; i < num_loops; i++) {
@@ -268,16 +269,16 @@  int si_copy_dma(struct radeon_device *rdev,
 		dst_offset += cur_size_in_bytes;
 	}
 
-	r = radeon_fence_emit(rdev, fence, ring->idx);
+	r = radeon_fence_emit(rdev, &fence, ring->idx);
 	if (r) {
 		radeon_ring_unlock_undo(rdev, ring);
 		radeon_semaphore_free(rdev, &sem, NULL);
-		return r;
+		return ERR_PTR(r);
 	}
 
 	radeon_ring_unlock_commit(rdev, ring, false);
-	radeon_semaphore_free(rdev, &sem, *fence);
+	radeon_semaphore_free(rdev, &sem, fence);
 
-	return r;
+	return fence;
 }