From: Jonathan Cavitt <jonathan.cavitt@intel.com>
To: intel-xe@lists.freedesktop.org
Cc: saurabhg.gupta@intel.com, alex.zuo@intel.com,
jonathan.cavitt@intel.com, joonas.lahtinen@linux.intel.com,
matthew.brost@intel.com, jianxun.zhang@intel.com,
shuicheng.lin@intel.com, dri-devel@lists.freedesktop.org,
Michal.Wajdeczko@intel.com, michal.mrozek@intel.com
Subject: [PATCH v10 5/5] drm/xe/xe_vm: Implement xe_vm_get_property_ioctl
Date: Thu, 20 Mar 2025 15:26:15 +0000 [thread overview]
Message-ID: <20250320152616.74587-6-jonathan.cavitt@intel.com> (raw)
In-Reply-To: <20250320152616.74587-1-jonathan.cavitt@intel.com>
Add support for userspace to request a list of observed faults
from a specified VM.
v2:
- Only allow querying of failed pagefaults (Matt Brost)
v3:
- Remove unnecessary size parameter from helper function, as it
is a property of the arguments. (jcavitt)
- Remove unnecessary copy_from_user (Jainxun)
- Set address_precision to 1 (Jainxun)
- Report max size instead of dynamic size for memory allocation
purposes. Total memory usage is reported separately.
v4:
- Return int from xe_vm_get_property_size (Shuicheng)
- Fix memory leak (Shuicheng)
- Remove unnecessary size variable (jcavitt)
v5:
- Rename ioctl to xe_vm_get_faults_ioctl (jcavitt)
- Update fill_property_pfs to eliminate need for kzalloc (Jianxun)
v6:
- Repair and move fill_faults break condition (Dan Carpenter)
- Free vm after use (jcavitt)
- Combine assertions (jcavitt)
- Expand size check in xe_vm_get_faults_ioctl (jcavitt)
- Remove return mask from fill_faults, as return is already -EFAULT or 0
(jcavitt)
v7:
- Revert back to using xe_vm_get_property_ioctl
- Apply better copy_to_user logic (jcavitt)
v8:
- Fix and clean up error value handling in ioctl (jcavitt)
- Reapply return mask for fill_faults (jcavitt)
v9:
- Future-proof size logic for zero-size properties (jcavitt)
- Add access and fault types (Jianxun)
- Remove address type (Jianxun)
Signed-off-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
Suggested-by: Matthew Brost <matthew.brost@intel.com>
Cc: Jainxun Zhang <jianxun.zhang@intel.com>
Cc: Shuicheng Lin <shuicheng.lin@intel.com>
---
drivers/gpu/drm/xe/xe_device.c | 3 +
drivers/gpu/drm/xe/xe_vm.c | 134 +++++++++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_vm.h | 2 +
3 files changed, 139 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index b2f656b2a563..74e510cb0e47 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -194,6 +194,9 @@ static const struct drm_ioctl_desc xe_ioctls[] = {
DRM_IOCTL_DEF_DRV(XE_WAIT_USER_FENCE, xe_wait_user_fence_ioctl,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(XE_OBSERVATION, xe_observation_ioctl, DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(XE_VM_GET_PROPERTY, xe_vm_get_property_ioctl,
+ DRM_RENDER_ALLOW),
+
};
static long xe_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 9a627ba17f55..6b0ac81ae8c5 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -43,6 +43,14 @@
#include "xe_wa.h"
#include "xe_hmm.h"
+static const u16 xe_to_user_engine_class[] = {
+ [XE_ENGINE_CLASS_RENDER] = DRM_XE_ENGINE_CLASS_RENDER,
+ [XE_ENGINE_CLASS_COPY] = DRM_XE_ENGINE_CLASS_COPY,
+ [XE_ENGINE_CLASS_VIDEO_DECODE] = DRM_XE_ENGINE_CLASS_VIDEO_DECODE,
+ [XE_ENGINE_CLASS_VIDEO_ENHANCE] = DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE,
+ [XE_ENGINE_CLASS_COMPUTE] = DRM_XE_ENGINE_CLASS_COMPUTE,
+};
+
static struct drm_gem_object *xe_vm_obj(struct xe_vm *vm)
{
return vm->gpuvm.r_obj;
@@ -3553,6 +3561,132 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
return err;
}
+static int xe_vm_get_property_size(struct xe_vm *vm, u32 property)
+{
+ int size = -EINVAL;
+
+ switch (property) {
+ case DRM_XE_VM_GET_PROPERTY_FAULTS:
+ spin_lock(&vm->faults.lock);
+ size = vm->faults.len * sizeof(struct xe_vm_fault);
+ spin_unlock(&vm->faults.lock);
+ break;
+ default:
+ break;
+ }
+ return size;
+}
+
+static int xe_vm_get_property_verify_size(struct xe_vm *vm, u32 property,
+ int expected, int actual)
+{
+ switch (property) {
+ case DRM_XE_VM_GET_PROPERTY_FAULTS:
+ /*
+ * Number of faults may increase between calls to
+ * xe_vm_get_property_ioctl, so just report the
+ * number of faults the user requests if it's less
+ * than or equal to the number of faults in the VM
+ * fault array.
+ */
+ if (actual < expected)
+ return -EINVAL;
+ break;
+ default:
+ if (actual != expected)
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+static int fill_faults(struct xe_vm *vm,
+ struct drm_xe_vm_get_property *args)
+{
+ struct xe_vm_fault __user *usr_ptr = u64_to_user_ptr(args->data);
+ struct xe_vm_fault store = { 0 };
+ struct xe_vm_fault_entry *entry;
+ int ret = 0, i = 0, count, entry_size;
+
+ entry_size = sizeof(struct xe_vm_fault);
+ count = args->size / entry_size;
+
+ spin_lock(&vm->faults.lock);
+ list_for_each_entry(entry, &vm->faults.list, list) {
+ if (i++ == count)
+ break;
+
+ memset(&store, 0, entry_size);
+
+ store.address = entry->address;
+ store.address_precision = entry->address_precision;
+ store.access_type = entry->access_type;
+ store.fault_type = entry->fault_type;
+ store.fault_level = entry->fault_level;
+ store.engine_class = xe_to_user_engine_class[entry->engine_class];
+ store.engine_instance = entry->engine_instance;
+
+ ret = copy_to_user(usr_ptr, &store, entry_size);
+ if (ret)
+ break;
+
+ usr_ptr++;
+ }
+ spin_unlock(&vm->faults.lock);
+
+ return ret ? -EFAULT : 0;
+}
+
+static int xe_vm_get_property_fill_data(struct xe_vm *vm,
+ struct drm_xe_vm_get_property *args)
+{
+ switch (args->property) {
+ case DRM_XE_VM_GET_PROPERTY_FAULTS:
+ return fill_faults(vm, args);
+ default:
+ break;
+ }
+ return -EINVAL;
+}
+
+int xe_vm_get_property_ioctl(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct xe_device *xe = to_xe_device(drm);
+ struct xe_file *xef = to_xe_file(file);
+ struct drm_xe_vm_get_property *args = data;
+ struct xe_vm *vm;
+ int size, ret = 0;
+
+ if (XE_IOCTL_DBG(xe, args->reserved[0] || args->reserved[1]))
+ return -EINVAL;
+
+ vm = xe_vm_lookup(xef, args->vm_id);
+ if (XE_IOCTL_DBG(xe, !vm))
+ return -ENOENT;
+
+ size = xe_vm_get_property_size(vm, args->property);
+
+ if (size < 0) {
+ ret = size;
+ goto put_vm;
+ } else if (!args->size && size) {
+ args->size = size;
+ goto put_vm;
+ }
+
+ ret = xe_vm_get_property_verify_size(vm, args->property,
+ args->size, size);
+ if (XE_IOCTL_DBG(xe, ret))
+ goto put_vm;
+
+ ret = xe_vm_get_property_fill_data(vm, args);
+
+put_vm:
+ xe_vm_put(vm);
+ return ret;
+}
+
/**
* xe_vm_bind_kernel_bo - bind a kernel BO to a VM
* @vm: VM to bind the BO to
diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
index 9bd7e93824da..63ec22458e04 100644
--- a/drivers/gpu/drm/xe/xe_vm.h
+++ b/drivers/gpu/drm/xe/xe_vm.h
@@ -196,6 +196,8 @@ int xe_vm_destroy_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
int xe_vm_bind_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
+int xe_vm_get_property_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file);
void xe_vm_close_and_put(struct xe_vm *vm);
--
2.43.0
next prev parent reply other threads:[~2025-03-20 15:26 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-20 15:26 [PATCH v10 0/5] drm/xe/xe_vm: Implement xe_vm_get_property_ioctl Jonathan Cavitt
2025-03-20 15:26 ` [PATCH v10 1/5] drm/xe/xe_gt_pagefault: Disallow writes to read-only VMAs Jonathan Cavitt
2025-03-20 15:26 ` [PATCH v10 2/5] drm/xe/xe_gt_pagefault: Move pagefault struct to header Jonathan Cavitt
2025-03-20 15:26 ` [PATCH v10 3/5] drm/xe/uapi: Define drm_xe_vm_get_property Jonathan Cavitt
2025-03-20 15:26 ` [PATCH v10 4/5] drm/xe/xe_vm: Add per VM fault info Jonathan Cavitt
2025-03-20 15:26 ` Jonathan Cavitt [this message]
2025-03-21 23:36 ` [PATCH v10 5/5] drm/xe/xe_vm: Implement xe_vm_get_property_ioctl Raag Jadav
2025-03-24 16:57 ` Cavitt, Jonathan
2025-03-24 21:25 ` Raag Jadav
2025-03-24 21:31 ` Cavitt, Jonathan
2025-03-25 7:19 ` Raag Jadav
2025-03-25 14:44 ` Cavitt, Jonathan
2025-03-25 23:36 ` Raag Jadav
2025-03-20 16:27 ` ✓ CI.Patch_applied: success for drm/xe/xe_vm: Implement xe_vm_get_property_ioctl (rev11) Patchwork
2025-03-20 16:27 ` ✗ CI.checkpatch: warning " Patchwork
2025-03-20 16:28 ` ✓ CI.KUnit: success " Patchwork
2025-03-20 16:45 ` ✓ CI.Build: " Patchwork
2025-03-20 16:47 ` ✗ CI.Hooks: failure " Patchwork
2025-03-20 16:48 ` ✓ CI.checksparse: success " Patchwork
2025-03-20 17:08 ` ✓ Xe.CI.BAT: " Patchwork
2025-03-20 18:01 ` ✗ Xe.CI.Full: failure " Patchwork
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=20250320152616.74587-6-jonathan.cavitt@intel.com \
--to=jonathan.cavitt@intel.com \
--cc=Michal.Wajdeczko@intel.com \
--cc=alex.zuo@intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=jianxun.zhang@intel.com \
--cc=joonas.lahtinen@linux.intel.com \
--cc=matthew.brost@intel.com \
--cc=michal.mrozek@intel.com \
--cc=saurabhg.gupta@intel.com \
--cc=shuicheng.lin@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.