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;