mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Danilo Krummrich <dakr@redhat.com>
To: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>,
	airlied@gmail.com, daniel@ffwll.ch, matthew.brost@intel.com,
	sarah.walker@imgtec.com, donald.robson@imgtec.com,
	boris.brezillon@collabora.com, christian.koenig@amd.com,
	faith.ekstrand@collabora.com
Cc: dri-devel@lists.freedesktop.org, nouveau@lists.freedesktop.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH drm-misc-next v3 6/7] drm/gpuvm: generalize dma_resv/extobj handling and GEM validation
Date: Thu, 14 Sep 2023 18:36:50 +0200	[thread overview]
Message-ID: <c620c142-ea38-415d-729e-2561f1f4bae3@redhat.com> (raw)
In-Reply-To: <62d9b00a-547a-2106-5ec3-6f6a88023496@linux.intel.com>

On 9/14/23 15:48, Thomas Hellström wrote:
> Hi, Danilo
> 
> Some additional minor comments as xe conversion progresses.
> 
> On 9/9/23 17:31, Danilo Krummrich wrote:
>> So far the DRM GPUVA manager offers common infrastructure to track GPU VA
>> allocations and mappings, generically connect GPU VA mappings to their
>> backing buffers and perform more complex mapping operations on the GPU VA
>> space.
>>
>> However, there are more design patterns commonly used by drivers, which
>> can potentially be generalized in order to make the DRM GPUVA manager
>> represent a basic GPU-VM implementation. In this context, this patch aims
>> at generalizing the following elements.
>>
>> 1) Provide a common dma-resv for GEM objects not being used outside of
>>     this GPU-VM.
>>
>> 2) Provide tracking of external GEM objects (GEM objects which are
>>     shared with other GPU-VMs).
>>
>> 3) Provide functions to efficiently lock all GEM objects dma-resv the
>>     GPU-VM contains mappings of.
>>
>> 4) Provide tracking of evicted GEM objects the GPU-VM contains mappings
>>     of, such that validation of evicted GEM objects is accelerated.
>>
>> 5) Provide some convinience functions for common patterns.
>>
>> Rather than being designed as a "framework", the target is to make all
>> features appear as a collection of optional helper functions, such that
>> drivers are free to make use of the DRM GPUVA managers basic
>> functionality and opt-in for other features without setting any feature
>> flags, just by making use of the corresponding functions.
>>
>> Big kudos to Boris Brezillon for his help to figure out locking for drivers
>> updating the GPU VA space within the fence signalling path.
>>
>> Suggested-by: Matthew Brost <matthew.brost@intel.com>
>> Signed-off-by: Danilo Krummrich <dakr@redhat.com>
>> ---
>>
>> +/**
>> + * drm_gpuvm_bo_evict() - add / remove a &drm_gem_object to / from a
>> + * &drm_gpuvms evicted list
>> + * @obj: the &drm_gem_object to add or remove
>> + * @evict: indicates whether the object is evicted
>> + *
>> + * Adds a &drm_gem_object to or removes it from all &drm_gpuvms evicted
>> + * list containing a mapping of this &drm_gem_object.
>> + */
>> +void
>> +drm_gpuvm_bo_evict(struct drm_gem_object *obj, bool evict)
>> +{
>> +    struct drm_gpuvm_bo *vm_bo;
>> +
>> +    drm_gem_for_each_gpuvm_bo(vm_bo, obj) {
>> +        if (evict)
>> +            drm_gpuvm_bo_list_add(vm_bo, evict);
>> +        else
>> +            drm_gpuvm_bo_list_del(vm_bo, evict);
>> +    }
>> +}
>> +EXPORT_SYMBOL_GPL(drm_gpuvm_bo_evict);
>> +
> 
> We need a drm_gpuvm_bo_evict(struct drm_gpuvm_bo *vm_bo, ...) that puts a single gpuvm_bo on the list, the above function could perhaps be renamed as drm_gpuvm_gem_obj_evict(obj, ....).

Makes sense - gonna change that.

> 
> Reason is some vm's are faulting vms which don't have an evict list, but validate from the pagefault handler. Also evict == false is dangerous because if called from within an exec, it might remove the obj from other vm's evict list before they've had a chance to rebind their VMAs.
> 
>>   static int
>>   __drm_gpuva_insert(struct drm_gpuvm *gpuvm,
>>              struct drm_gpuva *va)
>> diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h
>> index afa50b9059a2..834bb6d6617e 100644
>> --- a/include/drm/drm_gpuvm.h
>> +++ b/include/drm/drm_gpuvm.h
>> @@ -26,10 +26,12 @@
>>    */
>>   #include <linux/list.h>
>> +#include <linux/dma-resv.h>
>>   #include <linux/rbtree.h>
>>   #include <linux/types.h>
>>   #include <drm/drm_gem.h>
>> +#include <drm/drm_exec.h>
>>   struct drm_gpuvm;
>>   struct drm_gpuvm_bo;
>> @@ -259,6 +261,38 @@ struct drm_gpuvm {
>>        * space
>>        */
>>       struct dma_resv *resv;
>> +
>> +    /**
>> +     * @extobj: structure holding the extobj list
>> +     */
>> +    struct {
>> +        /**
>> +         * @list: &list_head storing &drm_gpuvm_bos serving as
>> +         * external object
>> +         */
>> +        struct list_head list;
>> +
>> +        /**
>> +         * @lock: spinlock to protect the extobj list
>> +         */
>> +        spinlock_t lock;
>> +    } extobj;
>> +
>> +    /**
>> +     * @evict: structure holding the evict list and evict list lock
>> +     */
>> +    struct {
>> +        /**
>> +         * @list: &list_head storing &drm_gpuvm_bos currently being
>> +         * evicted
>> +         */
>> +        struct list_head list;
>> +
>> +        /**
>> +         * @lock: spinlock to protect the evict list
>> +         */
>> +        spinlock_t lock;
>> +    } evict;
>>   };
>>   void drm_gpuvm_init(struct drm_gpuvm *gpuvm, struct drm_device *drm,
>> @@ -268,6 +302,21 @@ void drm_gpuvm_init(struct drm_gpuvm *gpuvm, struct drm_device *drm,
>>               const struct drm_gpuvm_ops *ops);
>>   void drm_gpuvm_destroy(struct drm_gpuvm *gpuvm);
>> +/**
>> + * drm_gpuvm_is_extobj() - indicates whether the given &drm_gem_object is an
>> + * external object
>> + * @gpuvm: the &drm_gpuvm to check
>> + * @obj: the &drm_gem_object to check
>> + *
>> + * Returns: true if the &drm_gem_object &dma_resv differs from the
>> + * &drm_gpuvms &dma_resv, false otherwise
>> + */
>> +static inline bool drm_gpuvm_is_extobj(struct drm_gpuvm *gpuvm,
>> +                       struct drm_gem_object *obj)
>> +{
>> +    return obj && obj->resv != gpuvm->resv;
>> +}
>> +
>>   static inline struct drm_gpuva *
>>   __drm_gpuva_next(struct drm_gpuva *va)
>>   {
>> @@ -346,6 +395,128 @@ __drm_gpuva_next(struct drm_gpuva *va)
>>   #define drm_gpuvm_for_each_va_safe(va__, next__, gpuvm__) \
>>       list_for_each_entry_safe(va__, next__, &(gpuvm__)->rb.list, rb.entry)
>> +/**
>> + * struct drm_gpuvm_exec - &drm_gpuvm abstraction of &drm_exec
>> + *
>> + * This structure should be created on the stack as &drm_exec should be.
>> + *
>> + * Optionally, @extra can be set in order to lock additional &drm_gem_objects.
>> + */
>> +struct drm_gpuvm_exec {
>> +    /**
>> +     * @exec: the &drm_exec structure
>> +     */
>> +    struct drm_exec exec;
>> +
>> +    /**
>> +     * @vm: the &drm_gpuvm to lock its DMA reservations
>> +     */
>> +    struct drm_gpuvm *vm;
>> +
>> +    /**
>> +     * @extra: Callback and corresponding private data for the driver to
>> +     * lock arbitrary additional &drm_gem_objects.
>> +     */
>> +    struct {
>> +        /**
>> +         * @fn: The driver callback to lock additional &drm_gem_objects.
>> +         */
>> +        int (*fn)(struct drm_gpuvm_exec *vm_exec,
>> +              unsigned int num_fences);
>> +
>> +        /**
>> +         * @priv: driver private data for the @fn callback
>> +         */
>> +        void *priv;
>> +    } extra;
>> +};
>> +
>> +/**
>> + * drm_gpuvm_prepare_vm() - prepare the GPUVMs common dma-resv
>> + * @gpuvm: the &drm_gpuvm
>> + * @exec: the &drm_exec context
>> + * @num_fences: the amount of &dma_fences to reserve
>> + *
>> + * Calls drm_exec_prepare_obj() for the GPUVMs dummy &drm_gem_object.
>> + *
>> + * Using this function directly, it is the drivers responsibility to call
>> + * drm_exec_init() and drm_exec_fini() accordingly.
>> + *
>> + * Returns: 0 on success, negative error code on failure.
>> + */
>> +static inline int
>> +drm_gpuvm_prepare_vm(struct drm_gpuvm *gpuvm,
>> +             struct drm_exec *exec,
>> +             unsigned int num_fences)
>> +{
>> +    return drm_exec_prepare_obj(exec, &gpuvm->d_obj, num_fences);
>> +}
>> +
>> +int drm_gpuvm_prepare_objects(struct drm_gpuvm *gpuvm,
>> +                  struct drm_exec *exec,
>> +                  unsigned int num_fences);
>> +
>> +int drm_gpuvm_prepare_range(struct drm_gpuvm *gpuvm,
>> +                struct drm_exec *exec,
>> +                u64 addr, u64 range,
>> +                unsigned int num_fences);
>> +
>> +int drm_gpuvm_exec_lock(struct drm_gpuvm_exec *vm_exec,
>> +            unsigned int num_fences,
>> +            bool interruptible);
>> +
>> +int drm_gpuvm_exec_lock_array(struct drm_gpuvm_exec *vm_exec,
>> +                  struct drm_gem_object **objs,
>> +                  unsigned int num_objs,
>> +                  unsigned int num_fences,
>> +                  bool interruptible);
>> +
>> +int drm_gpuvm_exec_lock_range(struct drm_gpuvm_exec *vm_exec,
>> +                  u64 addr, u64 range,
>> +                  unsigned int num_fences,
>> +                  bool interruptible);
>> +
>> +/**
>> + * drm_gpuvm_lock() - lock all dma-resv of all assoiciated BOs
>> + * @gpuvm: the &drm_gpuvm
>> + *
>> + * Releases all dma-resv locks of all &drm_gem_objects previously acquired
>> + * through drm_gpuvm_lock() or its variants.
>> + *
>> + * Returns: 0 on success, negative error code on failure.
>> + */
>> +static inline void
>> +drm_gpuvm_exec_unlock(struct drm_gpuvm_exec *vm_exec)
>> +{
>> +    drm_exec_fini(&vm_exec->exec);
>> +}
>> +
>> +int drm_gpuvm_validate(struct drm_gpuvm *gpuvm);
>> +void drm_gpuvm_resv_add_fence(struct drm_gpuvm *gpuvm,
>> +                  struct drm_exec *exec,
>> +                  struct dma_fence *fence,
>> +                  enum dma_resv_usage private_usage,
>> +                  enum dma_resv_usage extobj_usage);
>> +
>> +/**
>> + * drm_gpuvm_exec_resv_add_fence()
>> + * @vm_exec: the &drm_gpuvm_exec abstraction
>> + * @fence: fence to add
>> + * @private_usage: private dma-resv usage
>> + * @extobj_usage: extobj dma-resv usage
>> + *
>> + * See drm_gpuvm_resv_add_fence().
>> + */
>> +static inline void
>> +drm_gpuvm_exec_resv_add_fence(struct drm_gpuvm_exec *vm_exec,
>> +                  struct dma_fence *fence,
>> +                  enum dma_resv_usage private_usage,
>> +                  enum dma_resv_usage extobj_usage)
>> +{
>> +    drm_gpuvm_resv_add_fence(vm_exec->vm, &vm_exec->exec, fence,
>> +                 private_usage, extobj_usage);
>> +}
>> +
>>   /**
>>    * struct drm_gpuvm_bo - structure representing a &drm_gpuvm and
>>    * &drm_gem_object combination
>> @@ -398,6 +569,18 @@ struct drm_gpuvm_bo {
>>                * gpuva list.
>>                */
>>               struct list_head gem;
>> +
>> +            /**
>> +             * @evict: List entry to attach to the &drm_gpuvms
>> +             * extobj list.
>> +             */
>> +            struct list_head extobj;
>> +
>> +            /**
>> +             * @evict: List entry to attach to the &drm_gpuvms evict
>> +             * list.
>> +             */
>> +            struct list_head evict;
>>           } entry;
>>       } list;
>>   };
>> @@ -432,6 +615,9 @@ struct drm_gpuvm_bo *
>>   drm_gpuvm_bo_find(struct drm_gpuvm *gpuvm,
>>             struct drm_gem_object *obj);
>> +void drm_gpuvm_bo_evict(struct drm_gem_object *obj, bool evict);
>> +void drm_gpuvm_bo_extobj_add(struct drm_gpuvm_bo *vm_bo);
>> +
>>   /**
>>    * drm_gpuvm_bo_for_each_va() - iterator to walk over a list of &drm_gpuva
>>    * @va__: &drm_gpuva structure to assign to in each iteration step
>> @@ -837,6 +1023,17 @@ struct drm_gpuvm_ops {
>>        * used.
>>        */
>>       int (*sm_step_unmap)(struct drm_gpuva_op *op, void *priv);
>> +
>> +    /**
>> +     * @bo_validate: called from drm_gpuvm_validate()
>> +     *
>> +     * Drivers receive this callback for every evicted &drm_gem_object being
>> +     * mapped in the corresponding &drm_gpuvm.
>> +     *
>> +     * Typically, drivers would call their driver specific variant of
>> +     * ttm_bo_validate() from within this callback.
>> +     */
>> +    int (*bo_validate)(struct drm_gem_object *obj);
> 
> Same here. Could we have a vm_bo as an argument instead, so that the callback knows what gpuvm we're targeting and can mark all its gpu_vas for revalidation? Or is that intended to be done elsewhere?

Makes sense as well. I'll change that too.

> 
>>   };
>>   int drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, void *priv,
> 
> Thanks,
> 
> Thomas
> 
> 


  reply	other threads:[~2023-09-14 16:37 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-09 15:31 [PATCH drm-misc-next v3 0/7] [RFC] DRM GPUVA Manager GPU-VM features Danilo Krummrich
2023-09-09 15:31 ` [PATCH drm-misc-next v3 1/7] drm/gpuvm: rename struct drm_gpuva_manager to struct drm_gpuvm Danilo Krummrich
2023-09-09 18:23   ` kernel test robot
2023-09-09 15:31 ` [PATCH drm-misc-next v3 2/7] drm/gpuvm: allow building as module Danilo Krummrich
2023-09-11 13:09   ` Christian König
2023-09-09 15:31 ` [PATCH drm-misc-next v3 3/7] drm/nouveau: uvmm: rename 'umgr' to 'base' Danilo Krummrich
2023-09-09 15:31 ` [PATCH drm-misc-next v3 4/7] drm/gpuvm: common dma-resv per struct drm_gpuvm Danilo Krummrich
2023-09-11 12:00   ` Boris Brezillon
2023-09-11 16:16     ` Danilo Krummrich
2023-09-09 15:31 ` [PATCH drm-misc-next v3 5/7] drm/gpuvm: add an abstraction for a VM / BO combination Danilo Krummrich
2023-09-11 17:19   ` Thomas Hellström
2023-09-11 17:49     ` Danilo Krummrich
2023-09-11 18:37       ` Thomas Hellström
2023-09-12  7:42       ` Thomas Hellström
2023-09-12 10:06         ` Danilo Krummrich
2023-09-12 10:33           ` Thomas Hellström
2023-09-12 11:05             ` Danilo Krummrich
2023-09-09 15:31 ` [PATCH drm-misc-next v3 6/7] drm/gpuvm: generalize dma_resv/extobj handling and GEM validation Danilo Krummrich
2023-09-09 20:16   ` kernel test robot
2023-09-11 10:35   ` Boris Brezillon
2023-09-11 16:23     ` Danilo Krummrich
2023-09-11 12:54   ` Boris Brezillon
2023-09-11 14:45   ` Boris Brezillon
2023-09-11 16:30     ` Danilo Krummrich
2023-09-12 16:20   ` Thomas Hellström
2023-09-12 16:50     ` Danilo Krummrich
2023-09-12 19:23       ` Thomas Hellström
2023-09-12 23:36         ` Danilo Krummrich
2023-09-13  9:14           ` Thomas Hellström
2023-09-13 12:16             ` Danilo Krummrich
2023-09-13 14:26               ` Christian König
2023-09-13 15:13                 ` Thomas Hellström
2023-09-13 15:26                   ` Christian König
2023-09-13 15:15                 ` Danilo Krummrich
2023-09-13 15:33                   ` Christian König
2023-09-13 15:46                     ` Danilo Krummrich
2023-09-19 12:07                       ` Christian König
2023-09-19 12:21                         ` Thomas Hellström
2023-09-19 15:16                           ` Danilo Krummrich
2023-09-19 15:23                             ` Thomas Hellström
2023-09-20  5:37                               ` Christian König
2023-09-20  7:44                                 ` Thomas Hellström
2023-09-20  8:29                                   ` Thomas Hellström
2023-09-20 10:51                                   ` Christian König
2023-09-20 12:06                                     ` Thomas Hellström
2023-09-20 13:06                                       ` Christian König
2023-09-20 13:38                                         ` Thomas Hellström
2023-09-20 13:48                                           ` Christian König
2023-09-20 14:02                                             ` Thomas Hellström
2023-09-20 14:11                                               ` Christian König
2023-09-14 10:57               ` [Nouveau] " Danilo Krummrich
2023-09-14 11:32                 ` Thomas Hellström
2023-09-14 15:27                   ` Danilo Krummrich
2023-09-14 17:13                     ` Thomas Hellström
2023-09-14 17:15                       ` Danilo Krummrich
2023-09-18 11:21                         ` Danilo Krummrich
2023-09-13  7:03     ` Boris Brezillon
2023-09-13  7:05       ` Dave Airlie
2023-09-13  7:19         ` Boris Brezillon
2023-09-13 10:39           ` Thomas Hellström
2023-09-13 11:33             ` Boris Brezillon
2023-09-13 12:01               ` Danilo Krummrich
2023-09-13 13:22               ` Thomas Hellström
2023-09-13 14:01                 ` Boris Brezillon
2023-09-13 14:29                   ` Thomas Hellström
2023-09-13 15:17                     ` Boris Brezillon
2023-09-14  8:20                 ` Boris Brezillon
2023-09-14 10:45                   ` Thomas Hellström
2023-09-14 11:54                     ` Boris Brezillon
2023-09-14 13:33                       ` Thomas Hellström
2023-09-14 15:37                         ` Boris Brezillon
2023-09-14 13:48   ` Thomas Hellström
2023-09-14 16:36     ` Danilo Krummrich [this message]
2023-09-14 17:21       ` Thomas Hellström
2023-09-14 17:25         ` Danilo Krummrich
2023-09-14 19:14           ` Thomas Hellström
2023-09-09 15:31 ` [PATCH drm-misc-next v3 7/7] drm/nouveau: GPUVM dma-resv/extobj handling, " Danilo Krummrich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c620c142-ea38-415d-729e-2561f1f4bae3@redhat.com \
    --to=dakr@redhat.com \
    --cc=airlied@gmail.com \
    --cc=boris.brezillon@collabora.com \
    --cc=christian.koenig@amd.com \
    --cc=daniel@ffwll.ch \
    --cc=donald.robson@imgtec.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=faith.ekstrand@collabora.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=matthew.brost@intel.com \
    --cc=nouveau@lists.freedesktop.org \
    --cc=sarah.walker@imgtec.com \
    --cc=thomas.hellstrom@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®