]> Git Repo - linux.git/blobdiff - drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
Merge tag 'drm-misc-next-fixes-2021-06-24' of git://anongit.freedesktop.org/drm/drm...
[linux.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_gem.c
index b443907afceadfebab03bec153292bff145d5a0a..b3404c43a9111ebc877b6f7273a7d5a05ebb15e9 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/dma-buf.h>
 
 #include <drm/amdgpu_drm.h>
-#include <drm/drm_debugfs.h>
+#include <drm/drm_drv.h>
 #include <drm/drm_gem_ttm_helper.h>
 
 #include "amdgpu.h"
 
 static const struct drm_gem_object_funcs amdgpu_gem_object_funcs;
 
+static vm_fault_t amdgpu_gem_fault(struct vm_fault *vmf)
+{
+       struct ttm_buffer_object *bo = vmf->vma->vm_private_data;
+       struct drm_device *ddev = bo->base.dev;
+       vm_fault_t ret;
+       int idx;
+
+       ret = ttm_bo_vm_reserve(bo, vmf);
+       if (ret)
+               return ret;
+
+       if (drm_dev_enter(ddev, &idx)) {
+               ret = amdgpu_bo_fault_reserve_notify(bo);
+               if (ret) {
+                       drm_dev_exit(idx);
+                       goto unlock;
+               }
+
+                ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
+                                               TTM_BO_VM_NUM_PREFAULT, 1);
+
+                drm_dev_exit(idx);
+       } else {
+               ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
+       }
+       if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
+               return ret;
+
+unlock:
+       dma_resv_unlock(bo->base.resv);
+       return ret;
+}
+
+static const struct vm_operations_struct amdgpu_gem_vm_ops = {
+       .fault = amdgpu_gem_fault,
+       .open = ttm_bo_vm_open,
+       .close = ttm_bo_vm_close,
+       .access = ttm_bo_vm_access
+};
+
 static void amdgpu_gem_object_free(struct drm_gem_object *gobj)
 {
        struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj);
@@ -59,6 +99,7 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
                             struct drm_gem_object **obj)
 {
        struct amdgpu_bo *bo;
+       struct amdgpu_bo_user *ubo;
        struct amdgpu_bo_param bp;
        int r;
 
@@ -72,10 +113,13 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
        bp.preferred_domain = initial_domain;
        bp.flags = flags;
        bp.domain = initial_domain;
-       r = amdgpu_bo_create(adev, &bp, &bo);
+       bp.bo_ptr_size = sizeof(struct amdgpu_bo);
+
+       r = amdgpu_bo_create_user(adev, &bp, &ubo);
        if (r)
                return r;
 
+       bo = &ubo->bo;
        *obj = &bo->tbo.base;
        (*obj)->funcs = &amdgpu_gem_object_funcs;
 
@@ -126,7 +170,7 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj,
                return -EPERM;
 
        if (abo->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID &&
-           abo->tbo.base.resv != vm->root.base.bo->tbo.base.resv)
+           abo->tbo.base.resv != vm->root.bo->tbo.base.resv)
                return -EPERM;
 
        r = amdgpu_bo_reserve(abo, false);
@@ -182,7 +226,7 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj,
        if (!amdgpu_vm_ready(vm))
                goto out_unlock;
 
-       fence = dma_resv_get_excl(bo->tbo.base.resv);
+       fence = dma_resv_excl_fence(bo->tbo.base.resv);
        if (fence) {
                amdgpu_bo_fence(bo, fence, true);
                fence = NULL;
@@ -202,6 +246,18 @@ out_unlock:
        ttm_eu_backoff_reservation(&ticket, &list);
 }
 
+static int amdgpu_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
+{
+       struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
+
+       if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm))
+               return -EPERM;
+       if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
+               return -EPERM;
+
+       return drm_gem_ttm_mmap(obj, vma);
+}
+
 static const struct drm_gem_object_funcs amdgpu_gem_object_funcs = {
        .free = amdgpu_gem_object_free,
        .open = amdgpu_gem_object_open,
@@ -209,6 +265,8 @@ static const struct drm_gem_object_funcs amdgpu_gem_object_funcs = {
        .export = amdgpu_gem_prime_export,
        .vmap = drm_gem_ttm_vmap,
        .vunmap = drm_gem_ttm_vunmap,
+       .mmap = amdgpu_gem_object_mmap,
+       .vm_ops = &amdgpu_gem_vm_ops,
 };
 
 /*
@@ -262,11 +320,11 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
        }
 
        if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) {
-               r = amdgpu_bo_reserve(vm->root.base.bo, false);
+               r = amdgpu_bo_reserve(vm->root.bo, false);
                if (r)
                        return r;
 
-               resv = vm->root.base.bo->tbo.base.resv;
+               resv = vm->root.bo->tbo.base.resv;
        }
 
        initial_domain = (u32)(0xffffffff & args->in.domains);
@@ -295,9 +353,9 @@ retry:
                if (!r) {
                        struct amdgpu_bo *abo = gem_to_amdgpu_bo(gobj);
 
-                       abo->parent = amdgpu_bo_ref(vm->root.base.bo);
+                       abo->parent = amdgpu_bo_ref(vm->root.bo);
                }
-               amdgpu_bo_unreserve(vm->root.base.bo);
+               amdgpu_bo_unreserve(vm->root.bo);
        }
        if (r)
                return r;
@@ -468,8 +526,7 @@ int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
                return -ENOENT;
        }
        robj = gem_to_amdgpu_bo(gobj);
-       ret = dma_resv_wait_timeout_rcu(robj->tbo.base.resv, true, true,
-                                                 timeout);
+       ret = dma_resv_wait_timeout(robj->tbo.base.resv, true, true, timeout);
 
        /* ret == 0 means not signaled,
         * ret > 0 means signaled
@@ -555,7 +612,7 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
 
        if (operation == AMDGPU_VA_OP_MAP ||
            operation == AMDGPU_VA_OP_REPLACE) {
-               r = amdgpu_vm_bo_update(adev, bo_va, false);
+               r = amdgpu_vm_bo_update(adev, bo_va, false, NULL);
                if (r)
                        goto error;
        }
@@ -763,7 +820,7 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
                void __user *out = u64_to_user_ptr(args->value);
 
                info.bo_size = robj->tbo.base.size;
-               info.alignment = robj->tbo.mem.page_alignment << PAGE_SHIFT;
+               info.alignment = robj->tbo.page_alignment << PAGE_SHIFT;
                info.domains = robj->preferred_domains;
                info.domain_flags = robj->flags;
                amdgpu_bo_unreserve(robj);
@@ -784,7 +841,7 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
                }
                for (base = robj->vm_bo; base; base = base->next)
                        if (amdgpu_xgmi_same_hive(amdgpu_ttm_adev(robj->tbo.bdev),
-                               amdgpu_ttm_adev(base->vm->root.base.bo->tbo.bdev))) {
+                               amdgpu_ttm_adev(base->vm->root.bo->tbo.bdev))) {
                                r = -EINVAL;
                                amdgpu_bo_unreserve(robj);
                                goto out;
@@ -855,10 +912,10 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
 }
 
 #if defined(CONFIG_DEBUG_FS)
-static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
+static int amdgpu_debugfs_gem_info_show(struct seq_file *m, void *unused)
 {
-       struct drm_info_node *node = (struct drm_info_node *)m->private;
-       struct drm_device *dev = node->minor->dev;
+       struct amdgpu_device *adev = (struct amdgpu_device *)m->private;
+       struct drm_device *dev = adev_to_drm(adev);
        struct drm_file *file;
        int r;
 
@@ -896,16 +953,17 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
        return 0;
 }
 
-static const struct drm_info_list amdgpu_debugfs_gem_list[] = {
-       {"amdgpu_gem_info", &amdgpu_debugfs_gem_info, 0, NULL},
-};
+DEFINE_SHOW_ATTRIBUTE(amdgpu_debugfs_gem_info);
+
 #endif
 
-int amdgpu_debugfs_gem_init(struct amdgpu_device *adev)
+void amdgpu_debugfs_gem_init(struct amdgpu_device *adev)
 {
 #if defined(CONFIG_DEBUG_FS)
-       return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_gem_list,
-                                       ARRAY_SIZE(amdgpu_debugfs_gem_list));
+       struct drm_minor *minor = adev_to_drm(adev)->primary;
+       struct dentry *root = minor->debugfs_root;
+
+       debugfs_create_file("amdgpu_gem_info", 0444, root, adev,
+                           &amdgpu_debugfs_gem_info_fops);
 #endif
-       return 0;
 }
This page took 0.044686 seconds and 4 git commands to generate.