On 5/26/26 18:06, Tvrtko Ursulin wrote:
> Add a new flag (AMDGPU_GEM_LIST_HANDLES_FLAG_IS_USERPTR) to the
> DRM_IOCTL_AMDGPU_GEM_LIST_CONTEXTS ioctl.
> 
> This is required to allow for checkpoint and restore of userptr objects.
> 
> The existing struct drm_amdgpu_gem_list_handles_entry is used with the
> userptr creation flags places in alloc_flags, while the alignment field
> contains the userspace address.
> 
> Signed-off-by: Tvrtko Ursulin <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 18 +++++++----
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 40 +++++++++++++++++--------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 19 +++++++++++-
>  include/uapi/drm/amdgpu_drm.h           |  7 +++--
>  4 files changed, 61 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> index 0259d81e5157..5eb8433229b4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> @@ -1186,14 +1186,20 @@ int amdgpu_gem_list_handles_ioctl(struct drm_device 
> *dev, void *data,
>  
>               bo_entry = &bo_entries[bo_index];
>  
> -             bo_entry->size = amdgpu_bo_size(bo);
> -             bo_entry->alloc_flags = bo->flags & 
> AMDGPU_GEM_CREATE_SETTABLE_MASK;
> -             bo_entry->preferred_domains = bo->preferred_domains;
>               bo_entry->gem_handle = id;
> -             bo_entry->alignment = bo->tbo.page_alignment;
> +             bo_entry->size = amdgpu_bo_size(bo);
> +             if (amdgpu_ttm_tt_is_userptr(bo->tbo.ttm)) {
> +                     bo_entry->flags = 
> AMDGPU_GEM_LIST_HANDLES_FLAG_IS_USERPTR;
> +                     bo_entry->alloc_flags = 
> amdgpu_ttm_tt_get_userptr_flags(bo->tbo.ttm);
> +                     bo_entry->alignment = 
> amdgpu_ttm_tt_get_userptr_addr(bo->tbo.ttm);
> +             } else {
> +                     bo_entry->alloc_flags = bo->flags & 
> AMDGPU_GEM_CREATE_SETTABLE_MASK;
> +                     bo_entry->preferred_domains = bo->preferred_domains;
> +                     bo_entry->alignment = bo->tbo.page_alignment;
>  
> -             if (bo->tbo.base.import_attach)
> -                     bo_entry->flags |= 
> AMDGPU_GEM_LIST_HANDLES_FLAG_IS_IMPORT;
> +                     if (bo->tbo.base.import_attach)
> +                             bo_entry->flags = 
> AMDGPU_GEM_LIST_HANDLES_FLAG_IS_IMPORT;
> +             }
>  
>               bo_index += 1;
>       }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 3d2e00efc741..4023c84fe29d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -767,6 +767,33 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo,
>       return r;
>  }
>  
> +/*
> + * amdgpu_ttm_tt_is_userptr - Have the pages backing by userptr?
> + */
> +bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm)
> +{
> +     struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
> +
> +     if (gtt == NULL || !gtt->userptr)
> +             return false;
> +
> +     return true;
> +}
> +
> +u32 amdgpu_ttm_tt_get_userptr_flags(struct ttm_tt *ttm)
> +{
> +     struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
> +
> +     return gtt->userflags;
> +}
> +
> +u64 amdgpu_ttm_tt_get_userptr_addr(struct ttm_tt *ttm)
> +{
> +     struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
> +
> +     return gtt->userptr;
> +}
> +
>  #endif
>  
>  /*
> @@ -1374,19 +1401,6 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, 
> unsigned long start,
>       return true;
>  }
>  
> -/*
> - * amdgpu_ttm_tt_is_userptr - Have the pages backing by userptr?
> - */
> -bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm)
> -{
> -     struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
> -
> -     if (gtt == NULL || !gtt->userptr)
> -             return false;
> -
> -     return true;
> -}
> -
>  /*
>   * amdgpu_ttm_tt_is_readonly - Is the ttm_tt object read only?
>   */
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> index f2f23a42b3cc..8c0424577dea 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> @@ -211,12 +211,30 @@ uint64_t amdgpu_ttm_domain_start(struct amdgpu_device 
> *adev, uint32_t type);
>  #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>  int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo,
>                                struct amdgpu_hmm_range *range);
> +bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm);
> +u32 amdgpu_ttm_tt_get_userptr_flags(struct ttm_tt *ttm);
> +u64 amdgpu_ttm_tt_get_userptr_addr(struct ttm_tt *ttm);
>  #else
>  static inline int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo,
>                                              struct amdgpu_hmm_range *range)
>  {
>       return -EPERM;
>  }
> +
> +static inline bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm)
> +{
> +     return false;
> +}
> +
> +static inline u32 amdgpu_ttm_tt_get_userptr_flags(struct ttm_tt *ttm)
> +{
> +     return -1;
> +}
> +
> +static inline u64 amdgpu_ttm_tt_get_userptr_addr(struct ttm_tt *ttm)
> +{
> +     return 0;
> +}
>  #endif
>  
>  /**
> @@ -251,7 +269,6 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, 
> unsigned long start,
>                                 unsigned long end, unsigned long *userptr);
>  bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm,
>                                      int *last_invalidated);
> -bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm);
>  bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm);
>  uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource 
> *mem);
>  uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt 
> *ttm,
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
> index 9f3090db2f16..3069560ac26e 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -836,6 +836,7 @@ struct drm_amdgpu_gem_op {
>  };
>  
>  #define AMDGPU_GEM_LIST_HANDLES_FLAG_IS_IMPORT       (1 << 0)
> +#define AMDGPU_GEM_LIST_HANDLES_FLAG_IS_USERPTR      (1 << 1)
>  
>  struct drm_amdgpu_gem_list_handles {
>       /* User pointer to array of drm_amdgpu_gem_bo_info_entry */
> @@ -851,7 +852,7 @@ struct drm_amdgpu_gem_list_handles_entry {
>       /* gem handle of buffer object */
>       __u32 gem_handle;
>  
> -     /* Currently just one flag: IS_IMPORT */
> +     /* AMDGPU_GEM_LIST_HANDLES_FLAG_* */
>       __u32 flags;
>  
>       /* Size of bo */
> @@ -860,10 +861,10 @@ struct drm_amdgpu_gem_list_handles_entry {
>       /* Preferred domains for GEM_CREATE */
>       __u64 preferred_domains;
>  
> -     /* GEM_CREATE flags for re-creation of buffer */
> +     /* GEM_CREATE flags for re-creation of buffer or 
> drm_amdgpu_gem_userptr.flags */
>       __u64 alloc_flags;
>  
> -     /* physical start_addr alignment in bytes for some HW requirements */
> +     /* physical start_addr alignment in bytes for some HW requirements or 
> drm_amdgpu_gem_userptr.addr */
>       __u64 alignment;

Make that an union, e.g. union { __u64 alignment; __u64 userptr; }, apart looks 
pretty good to me.

Regards,
Christian.

>  };
>  

Reply via email to