[PATCH v3 06/17] drm/i915/vm_bind: Support for VM private BOs

Matthew Auld matthew.auld at intel.com
Tue Oct 11 17:41:23 UTC 2022


On 11/10/2022 17:27, Matthew Auld wrote:
> On 10/10/2022 07:58, Niranjana Vishwanathapura wrote:
>> Each VM creates a root_obj and shares it with all of its private objects
>> to use it as dma_resv object. This has a performance advantage as it
>> requires a single dma_resv object update for all private BOs vs list of
>> dma_resv objects update for shared BOs, in the execbuf path.
>>
>> VM private BOs can be only mapped on specified VM and cannot be dmabuf
>> exported. Also, they are supported only in vm_bind mode.
>>
>> v2: Pad struct drm_i915_gem_create_ext_vm_private for 64bit alignment,
>>      add input validity checks.
>> v3: Create root_obj only for ppgtt.
>>
>> Signed-off-by: Niranjana Vishwanathapura 
>> <niranjana.vishwanathapura at intel.com>
>> Signed-off-by: Andi Shyti <andi.shyti at linux.intel.com>
>> ---
>>   drivers/gpu/drm/i915/gem/i915_gem_context.c   | 16 +++++-
>>   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 49 ++++++++++++++++++-
>>   drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c    |  6 +++
>>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  4 ++
>>   drivers/gpu/drm/i915/gem/i915_gem_object.c    |  3 ++
>>   .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
>>   drivers/gpu/drm/i915/gem/i915_gem_ttm.c       |  3 ++
>>   .../drm/i915/gem/i915_gem_vm_bind_object.c    |  9 ++++
>>   drivers/gpu/drm/i915/gt/intel_gtt.c           |  3 ++
>>   drivers/gpu/drm/i915/gt/intel_gtt.h           |  2 +
>>   drivers/gpu/drm/i915/i915_vma.c               |  1 +
>>   drivers/gpu/drm/i915/i915_vma_types.h         |  2 +
>>   include/uapi/drm/i915_drm.h                   | 33 +++++++++++++
>>   13 files changed, 131 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
>> b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> index 793345cbf99e..5ea7064805f3 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> @@ -83,6 +83,7 @@
>>   #include "i915_file_private.h"
>>   #include "i915_gem_context.h"
>> +#include "i915_gem_internal.h"
>>   #include "i915_trace.h"
>>   #include "i915_user_extensions.h"
>> @@ -1795,6 +1796,7 @@ int i915_gem_vm_create_ioctl(struct drm_device 
>> *dev, void *data,
>>       struct drm_i915_private *i915 = to_i915(dev);
>>       struct drm_i915_gem_vm_control *args = data;
>>       struct drm_i915_file_private *file_priv = file->driver_priv;
>> +    struct drm_i915_gem_object *obj;
>>       struct i915_ppgtt *ppgtt;
>>       u32 id;
>>       int err;
>> @@ -1817,15 +1819,27 @@ int i915_gem_vm_create_ioctl(struct drm_device 
>> *dev, void *data,
>>               goto err_put;
>>       }
>> +    obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
>> +    if (IS_ERR(obj)) {
>> +        err = PTR_ERR(obj);
>> +        goto err_put;
>> +    }
>> +
>> +    ppgtt->vm.root_obj = obj;
>> +    ppgtt->vm.vm_bind_mode = true;
> 
> Won't this temporarily break execbuf2? Only in the final patch does this 
> depend on the new flag? Perhaps the patch split could be improved, or 
> maybe we can just keep this as false here, until the final patch? Could 
> also maybe also keep root_obj = NULL, until the last patch also?
> 
>> +
>>       err = xa_alloc(&file_priv->vm_xa, &id, &ppgtt->vm,
>>                  xa_limit_32b, GFP_KERNEL);
>>       if (err)
>> -        goto err_put;
>> +        goto err_root_obj_put;
>>       GEM_BUG_ON(id == 0); /* reserved for invalid/unassigned ppgtt */
>>       args->vm_id = id;
>>       return 0;
>> +err_root_obj_put:
>> +    if (ppgtt->vm.root_obj)
>> +        i915_gem_object_put(ppgtt->vm.root_obj);
>>   err_put:
>>       i915_vm_put(&ppgtt->vm);
>>       return err;
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
>> b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> index 5c6e396ab74d..694d4638ac8b 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> @@ -11,6 +11,7 @@
>>   #include "pxp/intel_pxp.h"
>>   #include "i915_drv.h"
>> +#include "i915_gem_context.h"
>>   #include "i915_gem_create.h"
>>   #include "i915_trace.h"
>>   #include "i915_user_extensions.h"
>> @@ -251,6 +252,7 @@ struct create_ext {
>>       unsigned int n_placements;
>>       unsigned int placement_mask;
>>       unsigned long flags;
>> +    u32 vm_id;
>>   };
>>   static void repr_placements(char *buf, size_t size,
>> @@ -400,9 +402,32 @@ static int ext_set_protected(struct 
>> i915_user_extension __user *base, void *data
>>       return 0;
>>   }
>> +static int ext_set_vm_private(struct i915_user_extension __user *base,
>> +                  void *data)
>> +{
>> +    struct drm_i915_gem_create_ext_vm_private ext;
>> +    struct create_ext *ext_data = data;
>> +
>> +    if (copy_from_user(&ext, base, sizeof(ext)))
>> +        return -EFAULT;
>> +
>> +    /* Reserved fields must be 0 */
>> +    if (ext.rsvd)
>> +        return -EINVAL;
>> +
>> +    /* vm_id 0 is reserved */
>> +    if (!ext.vm_id)
>> +        return -ENOENT;
>> +
>> +    ext_data->vm_id = ext.vm_id;
>> +
>> +    return 0;
>> +}
>> +
>>   static const i915_user_extension_fn create_extensions[] = {
>>       [I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
>>       [I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
>> +    [I915_GEM_CREATE_EXT_VM_PRIVATE] = ext_set_vm_private,
>>   };
>>   /**
>> @@ -418,6 +443,7 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, 
>> void *data,
>>       struct drm_i915_private *i915 = to_i915(dev);
>>       struct drm_i915_gem_create_ext *args = data;
>>       struct create_ext ext_data = { .i915 = i915 };
>> +    struct i915_address_space *vm = NULL;
>>       struct drm_i915_gem_object *obj;
>>       int ret;
>> @@ -431,6 +457,12 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, 
>> void *data,
>>       if (ret)
>>           return ret;
>> +    if (ext_data.vm_id) {
>> +        vm = i915_gem_vm_lookup(file->driver_priv, ext_data.vm_id);
>> +        if (unlikely(!vm))
>> +            return -ENOENT;
>> +    }
>> +
>>       if (!ext_data.n_placements) {
>>           ext_data.placements[0] =
>>               intel_memory_region_by_type(i915, INTEL_MEMORY_SYSTEM);
>> @@ -457,8 +489,21 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, 
>> void *data,
>>                           ext_data.placements,
>>                           ext_data.n_placements,
>>                           ext_data.flags);
>> -    if (IS_ERR(obj))
>> -        return PTR_ERR(obj);
>> +    if (IS_ERR(obj)) {
>> +        ret = PTR_ERR(obj);
>> +        goto vm_put;
>> +    }
>> +
>> +    if (vm) {
>> +        obj->base.resv = vm->root_obj->base.resv;
>> +        obj->priv_root = i915_gem_object_get(vm->root_obj);
>> +        i915_vm_put(vm);
>> +    }
>>       return i915_gem_publish(obj, file, &args->size, &args->handle);
>> +vm_put:
>> +    if (vm)
>> +        i915_vm_put(vm);
>> +
>> +    return ret;
>>   }
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 
>> b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
>> index f5062d0c6333..6433173c3e84 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
>> @@ -218,6 +218,12 @@ struct dma_buf *i915_gem_prime_export(struct 
>> drm_gem_object *gem_obj, int flags)
>>       struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
>>       DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
>> +    if (obj->priv_root) {
>> +        drm_dbg(obj->base.dev,
>> +            "Exporting VM private objects is not allowed\n");
>> +        return ERR_PTR(-EINVAL);
>> +    }
>> +
>>       exp_info.ops = &i915_dmabuf_ops;
>>       exp_info.size = gem_obj->size;
>>       exp_info.flags = flags;
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
>> b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> index 9fb9f6faafd8..4673e0812277 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> @@ -864,6 +864,10 @@ static struct i915_vma *eb_lookup_vma(struct 
>> i915_execbuffer *eb, u32 handle)
>>           if (unlikely(!obj))
>>               return ERR_PTR(-ENOENT);
>> +        /* VM private objects are not supported here */
>> +        if (obj->priv_root)
>> +            return ERR_PTR(-EINVAL);
>> +
>>           /*
>>            * If the user has opted-in for protected-object tracking, make
>>            * sure the object encryption can be used.
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
>> b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> index 62495d5d0038..b799c53ac4b1 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> @@ -108,6 +108,9 @@ void i915_gem_object_init(struct 
>> drm_i915_gem_object *obj,
>>    */
>>   void __i915_gem_object_fini(struct drm_i915_gem_object *obj)
>>   {
>> +    if (obj->priv_root && !obj->ttm.created)
>> +        i915_gem_object_put(obj->priv_root);
> 
> Can we not ignore the ttm.created here? And then drop the object_put() 
> below?

Otherwise,
Reviewed-by: Matthew Auld <matthew.auld at intel.com>

> 
>> +
>>       mutex_destroy(&obj->mm.get_page.lock);
>>       mutex_destroy(&obj->mm.get_dma_page.lock);
>>       dma_resv_fini(&obj->base._resv);
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
>> b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> index d0d6772e6f36..b77bf0e07fe1 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> @@ -242,6 +242,9 @@ struct drm_i915_gem_object {
>>       const struct drm_i915_gem_object_ops *ops;
>> +    /* For VM private BO, points to root_obj in VM. NULL otherwise */
>> +    struct drm_i915_gem_object *priv_root;
>> +
>>       struct {
>>           /**
>>            * @vma.lock: protect the list/tree of vmas
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
>> b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
>> index d63f30efd631..233d670a91de 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
>> @@ -1200,6 +1200,9 @@ void i915_ttm_bo_destroy(struct 
>> ttm_buffer_object *bo)
>>       mutex_destroy(&obj->ttm.get_io_page.lock);
>>       if (obj->ttm.created) {
>> +        if (obj->priv_root)
>> +            i915_gem_object_put(obj->priv_root);
>> +


More information about the dri-devel mailing list