diff mbox series

[v2,8/8] drm/xe/xe_vm: Implement xe_vm_get_property_ioctl

Message ID 20250227191457.84035-9-jonathan.cavitt@intel.com (mailing list archive)
State New
Headers show
Series drm/xe/xe_vm: Implement xe_vm_get_property_ioctl | expand

Commit Message

Jonathan Cavitt Feb. 27, 2025, 7:14 p.m. UTC
Add support for userspace to get various properties from a specified VM.
The currently supported properties are:

- The number of engine resets the VM has observed
- The number of exec queue bans the VM has observed, up to the last 50
  relevant ones, in total.
- The number of exec queue bans the VM has observed, up to the last 50
  relevant ones, that were caused by faults.

The latter two requests also include information on the exec queue bans
themselves, such as the ID of the banned exec queue and, when relevant,
the faulting address, address type, and address precision.

Signed-off-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
---
 drivers/gpu/drm/xe/xe_device.c |   3 +
 drivers/gpu/drm/xe/xe_vm.c     | 102 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/xe/xe_vm.h     |   2 +
 3 files changed, 107 insertions(+)

Comments

kernel test robot Feb. 28, 2025, 3:44 a.m. UTC | #1
Hi Jonathan,

kernel test robot noticed the following build warnings:

[auto build test WARNING on drm-xe/drm-xe-next]
[also build test WARNING on next-20250227]
[cannot apply to linus/master v6.14-rc4]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Jonathan-Cavitt/drm-xe-xe_gt_pagefault-Disallow-writes-to-read-only-VMAs/20250228-032204
base:   https://gitlab.freedesktop.org/drm/xe/kernel.git drm-xe-next
patch link:    https://lore.kernel.org/r/20250227191457.84035-9-jonathan.cavitt%40intel.com
patch subject: [PATCH v2 8/8] drm/xe/xe_vm: Implement xe_vm_get_property_ioctl
config: i386-buildonly-randconfig-002-20250228 (https://download.01.org/0day-ci/archive/20250228/202502281118.XNrfLzlo-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250228/202502281118.XNrfLzlo-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202502281118.XNrfLzlo-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/xe/xe_vm.c:3267:3: warning: label followed by a declaration is a C23 extension [-Wc23-extensions]
    3267 |                 struct xe_exec_queue_ban_entry *entry;
         |                 ^
   1 warning generated.


vim +3267 drivers/gpu/drm/xe/xe_vm.c

  3260	
  3261	static u32 xe_vm_get_property_size(struct xe_vm *vm, u32 property)
  3262	{
  3263		u32 size = 0;
  3264	
  3265		switch (property) {
  3266		case DRM_XE_VM_GET_PROPERTY_FAULTS:
> 3267			struct xe_exec_queue_ban_entry *entry;
  3268	
  3269			spin_lock(&vm->bans.lock);
  3270			list_for_each_entry(entry, &vm->bans.list, list) {
  3271				struct xe_pagefault *pf = entry->pf;
  3272	
  3273				size += pf ? sizeof(struct drm_xe_ban) : 0;
  3274			}
  3275			spin_unlock(&vm->bans.lock);
  3276			return size;
  3277		case DRM_XE_VM_GET_PROPERTY_BANS:
  3278			spin_lock(&vm->bans.lock);
  3279			size = vm->bans.len * sizeof(struct drm_xe_ban);
  3280			spin_unlock(&vm->bans.lock);
  3281			return size;
  3282		case DRM_XE_VM_GET_PROPERTY_NUM_RESETS:
  3283			return 0;
  3284		default:
  3285			return -EINVAL;
  3286		}
  3287	}
  3288
diff mbox series

Patch

diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 9454b51f7ad8..43accae152ff 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -193,6 +193,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 3e88652670e6..8ac54aaca51a 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -3258,6 +3258,108 @@  int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 	return err;
 }
 
+static u32 xe_vm_get_property_size(struct xe_vm *vm, u32 property)
+{
+	u32 size = 0;
+
+	switch (property) {
+	case DRM_XE_VM_GET_PROPERTY_FAULTS:
+		struct xe_exec_queue_ban_entry *entry;
+
+		spin_lock(&vm->bans.lock);
+		list_for_each_entry(entry, &vm->bans.list, list) {
+			struct xe_pagefault *pf = entry->pf;
+
+			size += pf ? sizeof(struct drm_xe_ban) : 0;
+		}
+		spin_unlock(&vm->bans.lock);
+		return size;
+	case DRM_XE_VM_GET_PROPERTY_BANS:
+		spin_lock(&vm->bans.lock);
+		size = vm->bans.len * sizeof(struct drm_xe_ban);
+		spin_unlock(&vm->bans.lock);
+		return size;
+	case DRM_XE_VM_GET_PROPERTY_NUM_RESETS:
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int fill_property_bans(struct xe_vm *vm,
+			      struct drm_xe_vm_get_property *args,
+			      u32 size, bool faults_only)
+{
+	struct drm_xe_ban __user *usr_ptr = u64_to_user_ptr(args->ptr);
+	struct drm_xe_ban *ban_list;
+	struct drm_xe_ban *ban;
+	struct xe_exec_queue_ban_entry *entry;
+	int i = 0;
+
+	if (copy_from_user(&ban_list, usr_ptr, size))
+		return -EFAULT;
+
+	spin_lock(&vm->bans.lock);
+	list_for_each_entry(entry, &vm->bans.list, list) {
+		struct xe_pagefault *pf = entry->pf;
+
+		if (!pf && faults_only)
+			continue;
+
+		ban = &ban_list[i++];
+		ban->exec_queue_id = entry->exec_queue_id;
+		ban->faulted = !pf ? 0 : 1;
+		ban->address = pf ? pf->page_addr : 0;
+		ban->address_type = pf ? pf->address_type : 0;
+		ban->address_precision = SZ_4K;
+	}
+	spin_unlock(&vm->bans.lock);
+
+	if (copy_to_user(usr_ptr, &ban_list, size))
+		return -EFAULT;
+
+	return 0;
+}
+
+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;
+	u32 size;
+
+	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) {
+		return size;
+	} else if (args->size != size) {
+		if (args->size)
+			return -EINVAL;
+		args->size = size;
+		return 0;
+	}
+
+	switch (args->property) {
+	case DRM_XE_VM_GET_PROPERTY_FAULTS:
+		return fill_property_bans(vm, args, size, true);
+	case DRM_XE_VM_GET_PROPERTY_BANS:
+		return fill_property_bans(vm, args, size, false);
+	case DRM_XE_VM_GET_PROPERTY_NUM_RESETS:
+		args->data = atomic_read(&vm->reset_count);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 /**
  * 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 9f8457ceb905..0338f42f7a71 100644
--- a/drivers/gpu/drm/xe/xe_vm.h
+++ b/drivers/gpu/drm/xe/xe_vm.h
@@ -184,6 +184,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);