[igt-dev] [RFC i-g-t 2/7] lib: Add interface to support SVM

Niranjana Vishwanathapura niranjana.vishwanathapura at intel.com
Fri Dec 13 21:54:24 UTC 2019


Add required interfaces to support Shared Virtual Memory (SVM)
functionality. It includes SVM capability handling functions
and the bind and prefetch ioctl wrappers.

Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
Cc: Jon Bloomfield <jon.bloomfield at intel.com>
Cc: Daniel Vetter <daniel.vetter at intel.com>
Cc: Sudeep Dutt <sudeep.dutt at intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura at intel.com>
Signed-off-by: Venkata Sandeep Dhanalakota <venkata.s.dhanalakota at intel.com>
---
 lib/i915/gem_context.c |  27 ++++++++
 lib/i915/gem_context.h |   2 +
 lib/i915/gem_vm.c      |  48 +++++++++++++
 lib/i915/gem_vm.h      |   6 ++
 lib/ioctl_wrappers.c   | 154 +++++++++++++++++++++++++++++++++++++++++
 lib/ioctl_wrappers.h   |  14 ++++
 6 files changed, 251 insertions(+)

diff --git a/lib/i915/gem_context.c b/lib/i915/gem_context.c
index 1fae5191..e202b47a 100644
--- a/lib/i915/gem_context.c
+++ b/lib/i915/gem_context.c
@@ -403,3 +403,30 @@ bool gem_context_has_engine(int fd, uint32_t ctx, uint64_t engine)
 
 	return __gem_execbuf(fd, &execbuf) == -ENOENT;
 }
+
+uint32_t gem_ctx_get_vm(int fd, uint32_t ctx_id)
+{
+	struct drm_i915_gem_context_param arg;
+
+	memset(&arg, 0, sizeof(arg));
+	arg.param = I915_CONTEXT_PARAM_VM;
+	arg.ctx_id = ctx_id;
+	gem_context_get_param(fd, &arg);
+	igt_assert(arg.value);
+
+	return arg.value;
+}
+
+uint32_t gem_ctx_set_vm(int fd, uint32_t ctx_id, uint32_t vm_id)
+{
+	struct drm_i915_gem_context_param arg;
+
+	memset(&arg, 0, sizeof(arg));
+	arg.param = I915_CONTEXT_PARAM_VM;
+	arg.ctx_id = ctx_id;
+	arg.value = vm_id;
+	gem_context_set_param(fd, &arg);
+	igt_assert(arg.value);
+
+	return arg.value;
+}
diff --git a/lib/i915/gem_context.h b/lib/i915/gem_context.h
index c0d4c961..4cfc6ed8 100644
--- a/lib/i915/gem_context.h
+++ b/lib/i915/gem_context.h
@@ -68,4 +68,6 @@ void gem_context_set_persistence(int i915, uint32_t ctx, bool state);
 
 bool gem_context_has_engine(int fd, uint32_t ctx, uint64_t engine);
 
+uint32_t gem_ctx_get_vm(int fd, uint32_t ctx_id);
+uint32_t gem_ctx_set_vm(int fd, uint32_t ctx_id, uint32_t vm_id);
 #endif /* GEM_CONTEXT_H */
diff --git a/lib/i915/gem_vm.c b/lib/i915/gem_vm.c
index 9a022a56..64e6a319 100644
--- a/lib/i915/gem_vm.c
+++ b/lib/i915/gem_vm.c
@@ -128,3 +128,51 @@ void gem_vm_destroy(int i915, uint32_t vm_id)
 {
 	igt_assert_eq(__gem_vm_destroy(i915, vm_id), 0);
 }
+
+int __gem_vm_set_param(int fd, struct drm_i915_gem_vm_param *p)
+{
+	int err = 0;
+
+	if (igt_ioctl(fd, DRM_IOCTL_I915_GEM_VM_SETPARAM, p)) {
+		err = -errno;
+		igt_assume(err);
+	}
+
+	errno = 0;
+	return err;
+}
+
+/**
+ * gem_vm_set_param:
+ * @fd: open i915 drm file descriptor
+ * @param: i915 vm parameter
+ *
+ * Feature test macro to query whether context parameter support for @param
+ * is available. Automatically skips through igt_require() if not.
+ */
+void gem_vm_set_param(int fd, struct drm_i915_gem_vm_param *p)
+{
+	igt_assert_eq(__gem_vm_set_param(fd, p), 0);
+}
+
+void gem_vm_enable_svm(int fd, uint32_t vm_id)
+{
+	struct drm_i915_gem_vm_param arg;
+
+	memset(&arg, 0, sizeof(arg));
+	arg.param = (I915_VM_PARAM | I915_GEM_VM_PARAM_SVM);
+	arg.vm_id = vm_id;
+	arg.value = 1;
+	gem_vm_set_param(fd, &arg);
+}
+
+void gem_vm_disable_svm(int fd, uint32_t vm_id)
+{
+	struct drm_i915_gem_vm_param arg;
+
+	memset(&arg, 0, sizeof(arg));
+	arg.param = (I915_VM_PARAM | I915_GEM_VM_PARAM_SVM);
+	arg.vm_id = vm_id;
+	arg.value = 0;
+	gem_vm_set_param(fd, &arg);
+}
diff --git a/lib/i915/gem_vm.h b/lib/i915/gem_vm.h
index 27af899d..bb279483 100644
--- a/lib/i915/gem_vm.h
+++ b/lib/i915/gem_vm.h
@@ -35,4 +35,10 @@ int __gem_vm_create(int i915, uint32_t *vm_id);
 void gem_vm_destroy(int i915, uint32_t vm_id);
 int __gem_vm_destroy(int i915, uint32_t vm_id);
 
+void gem_vm_set_param(int fd, struct drm_i915_gem_vm_param *p);
+int __gem_vm_set_param(int fd, struct drm_i915_gem_vm_param *p);
+
+void gem_vm_enable_svm(int fd, uint32_t vm_id);
+void gem_vm_disable_svm(int fd, uint32_t vm_id);
+
 #endif /* GEM_VM_H */
diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 627717d2..3c42581d 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -1454,3 +1454,157 @@ int __kms_addfb(int fd, uint32_t handle,
 
 	return ret < 0 ? -errno : ret;
 }
+
+/* SVM */
+
+bool igt_has_svm(int fd)
+{
+	int val = -1;
+	struct drm_i915_getparam gp = {
+		.param = I915_PARAM_HAS_SVM,
+		.value = &val,
+	};
+	ioctl(fd, DRM_IOCTL_I915_GETPARAM , &gp);
+	return val > 0;
+}
+
+void igt_require_svm(int fd)
+{
+	igt_require(igt_has_svm(fd));
+}
+
+int __gem_svm_bind(int fd, uint64_t start, uint32_t handle,
+		   uint32_t vm_id, uint32_t flags)
+{
+	struct drm_i915_gem_vm_bind bind;
+	int err = 0;
+
+	memset(&bind, 0, sizeof(bind));
+	bind.start = start;
+	bind.type = I915_GEM_VM_BIND_SVM_OBJ;
+	bind.handle = handle;
+	bind.vm_id = vm_id;
+	bind.flags = flags;
+
+	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_VM_BIND, &bind))
+		err = -errno;
+	return err;
+}
+
+/**
+ * gem_svm_bind:
+ * @fd: open i915 drm file descriptor
+ * @start: VA to bind
+ * @handle: object handle
+ * @vm_id: address space id
+ * @rdonly: read only
+ *
+ * This wraps the BIND ioctl to bind an object to the specified address space.
+ */
+void gem_svm_bind(int fd, uint64_t start, uint32_t handle,
+		  uint32_t vm_id, bool rdonly)
+{
+	uint32_t flags = rdonly ? I915_GEM_VM_BIND_READONLY : 0;
+
+	igt_assert_eq(__gem_svm_bind(fd, start, handle, vm_id, flags), 0);
+}
+
+/**
+ * gem_svm_unbind:
+ * @fd: open i915 drm file descriptor
+ * @handle: object handle
+ * @vm_id: address space id
+ *
+ * This wraps the BIND ioctl to unbind an object from the
+ * specified address space.
+ */
+void gem_svm_unbind(int fd, uint32_t handle, uint32_t vm_id)
+{
+	igt_assert_eq(__gem_svm_bind(fd, 0, handle, vm_id,
+				     I915_GEM_VM_BIND_UNBIND), 0);
+}
+
+int __svm_bind(int fd, const void *buf, uint64_t length,
+	       uint32_t vm_id, uint32_t flags)
+{
+	struct drm_i915_gem_vm_bind bind;
+	int err = 0;
+
+	memset(&bind, 0, sizeof(bind));
+	bind.start = (uint64_t)buf;
+	bind.length = length;
+	bind.type = I915_GEM_VM_BIND_SVM_BUFFER;
+	bind.vm_id = vm_id;
+	bind.flags = flags;
+
+	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_VM_BIND, &bind))
+		err = -errno;
+	return err;
+}
+
+/**
+ * svm_bind:
+ * @fd: open i915 drm file descriptor
+ * @buf: pointer to the data to write into the buffer
+ * @length: size of the subrange
+ * @vm_id: address space id
+ * @rdonly: read only
+ *
+ * This wraps the BIND ioctl to bind an address range to the
+ * specified address space.
+ */
+void svm_bind(int fd, const void *buf, uint64_t length,
+	      uint32_t vm_id, bool rdonly)
+{
+	uint32_t flags = rdonly ? I915_GEM_VM_BIND_READONLY : 0;
+
+	igt_assert_eq(__svm_bind(fd, buf, length, vm_id, flags), 0);
+}
+
+/**
+ * svm_unbind:
+ * @fd: open i915 drm file descriptor
+ * @start: VA to bind
+ * @buf: pointer to the data to write into the buffer
+ * @length: size of the subrange
+ * @vm_id: address space id
+ *
+ * This wraps the BIND ioctl to unbind an address range from the
+ * specified address space.
+ */
+void svm_unbind(int fd, const void *buf, uint64_t length, uint32_t vm_id)
+{
+	igt_assert_eq(__svm_bind(fd, buf, length, vm_id,
+				 I915_GEM_VM_BIND_UNBIND), 0);
+}
+
+int __svm_prefetch(int fd, const void *buf, uint64_t length, uint32_t region)
+{
+	struct drm_i915_gem_vm_prefetch prefetch;
+	int err = 0;
+
+	memset(&prefetch, 0, sizeof(prefetch));
+	prefetch.type = I915_GEM_VM_PREFETCH_SVM_BUFFER;
+	prefetch.start = (uint64_t)buf;
+	prefetch.length = length;
+	prefetch.region = region;
+
+	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_VM_PREFETCH, &prefetch))
+		err = -errno;
+	return err;
+}
+
+/**
+ * svm_prefetch:
+ * @fd: open i915 drm file descriptor
+ * @buf: pointer to the data to write into the buffer
+ * @length: size of the subrange
+ * @region: memory region
+ *
+ * This wraps the VM_PREFETCH ioctl, which is to prefetch specified
+ * memory range to the specified memory region.
+ */
+void svm_prefetch(int fd, const void *buf, uint64_t length, uint32_t region)
+{
+	igt_assert_eq(__svm_prefetch(fd, buf, length, region), 0);
+}
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index 86743ace..14736a20 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -85,6 +85,18 @@ void gem_execbuf_wr(int fd, struct drm_i915_gem_execbuffer2 *execbuf);
 int __gem_execbuf_wr(int fd, struct drm_i915_gem_execbuffer2 *execbuf);
 void gem_execbuf(int fd, struct drm_i915_gem_execbuffer2 *execbuf);
 int __gem_execbuf(int fd, struct drm_i915_gem_execbuffer2 *execbuf);
+int __gem_svm_bind(int fd, uint64_t start, uint32_t handle,
+		   uint32_t vm_id, uint32_t flags);
+void gem_svm_bind(int fd, uint64_t start, uint32_t handle,
+		  uint32_t vm_id, bool rdonly);
+void gem_svm_unbind(int fd, uint32_t handle, uint32_t vm_id);
+int __svm_bind(int fd, const void *buf, uint64_t length,
+	       uint32_t vm_id, uint32_t flags);
+void svm_bind(int fd, const void *buf, uint64_t length,
+	      uint32_t vm_id, bool rdonly);
+void svm_unbind(int fd, const void *buf, uint64_t length, uint32_t vm_id);
+int __svm_prefetch(int fd, const void *buf, uint64_t length, uint32_t region);
+void svm_prefetch(int fd, const void *buf, uint64_t length, uint32_t region);
 
 #ifndef I915_GEM_DOMAIN_WC
 #define I915_GEM_DOMAIN_WC 0x80
@@ -141,6 +153,8 @@ uint64_t gem_global_aperture_size(int fd);
 uint64_t gem_mappable_aperture_size(void);
 bool gem_has_softpin(int fd);
 bool gem_has_exec_fence(int fd);
+bool igt_has_svm(int fd);
+void igt_require_svm(int fd);
 
 /* check functions which auto-skip tests by calling igt_skip() */
 void gem_require_caching(int fd);
-- 
2.21.0.rc0.32.g243a4c7e27



More information about the igt-dev mailing list