Merge tag 'for-linus-hmm' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[linux-2.6-block.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_ttm.c
index e51b48ac48eb151fcf72d11a4bdf15b9a06dda0e..dff41d0a85fe969b7bc96323ba66d235d210fed3 100644 (file)
@@ -227,7 +227,7 @@ static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp)
 
        if (amdgpu_ttm_tt_get_usermm(bo->ttm))
                return -EPERM;
-       return drm_vma_node_verify_access(&abo->gem_base.vma_node,
+       return drm_vma_node_verify_access(&abo->tbo.base.vma_node,
                                          filp->private_data);
 }
 
@@ -303,7 +303,7 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
                               struct amdgpu_copy_mem *src,
                               struct amdgpu_copy_mem *dst,
                               uint64_t size,
-                              struct reservation_object *resv,
+                              struct dma_resv *resv,
                               struct dma_fence **f)
 {
        struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
@@ -440,10 +440,26 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
 
        r = amdgpu_ttm_copy_mem_to_mem(adev, &src, &dst,
                                       new_mem->num_pages << PAGE_SHIFT,
-                                      bo->resv, &fence);
+                                      bo->base.resv, &fence);
        if (r)
                goto error;
 
+       /* clear the space being freed */
+       if (old_mem->mem_type == TTM_PL_VRAM &&
+           (ttm_to_amdgpu_bo(bo)->flags &
+            AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
+               struct dma_fence *wipe_fence = NULL;
+
+               r = amdgpu_fill_buffer(ttm_to_amdgpu_bo(bo), AMDGPU_POISON,
+                                      NULL, &wipe_fence);
+               if (r) {
+                       goto error;
+               } else if (wipe_fence) {
+                       dma_fence_put(fence);
+                       fence = wipe_fence;
+               }
+       }
+
        /* Always block for VM page tables before committing the new location */
        if (bo->type == ttm_bo_type_kernel)
                r = ttm_bo_move_accel_cleanup(bo, fence, true, new_mem);
@@ -778,7 +794,6 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
        struct hmm_range *range;
        unsigned long i;
        uint64_t *pfns;
-       int retry = 0;
        int r = 0;
 
        if (!mm) /* Happens during process shutdown */
@@ -819,10 +834,11 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
                                0 : range->flags[HMM_PFN_WRITE];
        range->pfn_flags_mask = 0;
        range->pfns = pfns;
-       hmm_range_register(range, mirror, start,
-                          start + ttm->num_pages * PAGE_SIZE, PAGE_SHIFT);
+       range->start = start;
+       range->end = start + ttm->num_pages * PAGE_SIZE;
+
+       hmm_range_register(range, mirror);
 
-retry:
        /*
         * Just wait for range to be valid, safe to ignore return value as we
         * will use the return value of hmm_range_fault() below under the
@@ -831,24 +847,12 @@ retry:
        hmm_range_wait_until_valid(range, HMM_RANGE_DEFAULT_TIMEOUT);
 
        down_read(&mm->mmap_sem);
-
-       r = hmm_range_fault(range, true);
-       if (unlikely(r < 0)) {
-               if (likely(r == -EAGAIN)) {
-                       /*
-                        * return -EAGAIN, mmap_sem is dropped
-                        */
-                       if (retry++ < MAX_RETRY_HMM_RANGE_FAULT)
-                               goto retry;
-                       else
-                               pr_err("Retry hmm fault too many times\n");
-               }
-
-               goto out_up_read;
-       }
-
+       r = hmm_range_fault(range, 0);
        up_read(&mm->mmap_sem);
 
+       if (unlikely(r < 0))
+               goto out_free_pfns;
+
        for (i = 0; i < ttm->num_pages; i++) {
                pages[i] = hmm_device_entry_to_page(range, pfns[i]);
                if (unlikely(!pages[i])) {
@@ -864,9 +868,6 @@ retry:
 
        return 0;
 
-out_up_read:
-       if (likely(r != -EAGAIN))
-               up_read(&mm->mmap_sem);
 out_free_pfns:
        hmm_range_unregister(range);
        kvfree(pfns);
@@ -1470,7 +1471,7 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
 {
        unsigned long num_pages = bo->mem.num_pages;
        struct drm_mm_node *node = bo->mem.mm_node;
-       struct reservation_object_list *flist;
+       struct dma_resv_list *flist;
        struct dma_fence *f;
        int i;
 
@@ -1478,18 +1479,18 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
         * cleanly handle page faults.
         */
        if (bo->type == ttm_bo_type_kernel &&
-           !reservation_object_test_signaled_rcu(bo->resv, true))
+           !dma_resv_test_signaled_rcu(bo->base.resv, true))
                return false;
 
        /* If bo is a KFD BO, check if the bo belongs to the current process.
         * If true, then return false as any KFD process needs all its BOs to
         * be resident to run successfully
         */
-       flist = reservation_object_get_list(bo->resv);
+       flist = dma_resv_get_list(bo->base.resv);
        if (flist) {
                for (i = 0; i < flist->shared_count; ++i) {
                        f = rcu_dereference_protected(flist->shared[i],
-                               reservation_object_held(bo->resv));
+                               dma_resv_held(bo->base.resv));
                        if (amdkfd_fence_check_mm(f, current->mm))
                                return false;
                }
@@ -1599,6 +1600,7 @@ static struct ttm_bo_driver amdgpu_bo_driver = {
        .move = &amdgpu_bo_move,
        .verify_access = &amdgpu_verify_access,
        .move_notify = &amdgpu_bo_move_notify,
+       .release_notify = &amdgpu_bo_release_notify,
        .fault_reserve_notify = &amdgpu_bo_fault_reserve_notify,
        .io_mem_reserve = &amdgpu_ttm_io_mem_reserve,
        .io_mem_free = &amdgpu_ttm_io_mem_free,
@@ -1721,6 +1723,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
        uint64_t gtt_size;
        int r;
        u64 vis_vram_limit;
+       void *stolen_vga_buf;
 
        mutex_init(&adev->mman.gtt_window_lock);
 
@@ -1728,7 +1731,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
        r = ttm_bo_device_init(&adev->mman.bdev,
                               &amdgpu_bo_driver,
                               adev->ddev->anon_inode->i_mapping,
-                              adev->need_dma32);
+                              dma_addressing_limited(adev->dev));
        if (r) {
                DRM_ERROR("failed initializing buffer object driver(%d).\n", r);
                return r;
@@ -1775,7 +1778,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
        r = amdgpu_bo_create_kernel(adev, adev->gmc.stolen_size, PAGE_SIZE,
                                    AMDGPU_GEM_DOMAIN_VRAM,
                                    &adev->stolen_vga_memory,
-                                   NULL, NULL);
+                                   NULL, &stolen_vga_buf);
        if (r)
                return r;
        DRM_INFO("amdgpu: %uM of VRAM memory ready\n",
@@ -1839,8 +1842,9 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
  */
 void amdgpu_ttm_late_init(struct amdgpu_device *adev)
 {
+       void *stolen_vga_buf;
        /* return the VGA stolen memory (if any) back to VRAM */
-       amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL);
+       amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, &stolen_vga_buf);
 }
 
 /**
@@ -1992,7 +1996,7 @@ error_free:
 
 int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
                       uint64_t dst_offset, uint32_t byte_count,
-                      struct reservation_object *resv,
+                      struct dma_resv *resv,
                       struct dma_fence **fence, bool direct_submit,
                       bool vm_needs_flush)
 {
@@ -2066,7 +2070,7 @@ error_free:
 
 int amdgpu_fill_buffer(struct amdgpu_bo *bo,
                       uint32_t src_data,
-                      struct reservation_object *resv,
+                      struct dma_resv *resv,
                       struct dma_fence **fence)
 {
        struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);