drm/xe/vm: Fix ASID XA usage
authorThomas Hellström <thomas.hellstrom@linux.intel.com>
Fri, 24 Nov 2023 15:33:45 +0000 (16:33 +0100)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Thu, 21 Dec 2023 16:44:57 +0000 (11:44 -0500)
xa_alloc_cyclic() returns 1 on successful allocation, if wrapping occurs,
but the code incorrectly treats that as an error. Fix that.
Also, xa_alloc_cyclic() requires xa_init_flags(..., XA_FLAGS_ALLOC), so
fix that, and assuming we don't want a zero ASID, instead of using
XA_FLAGS_ALLOC1, adjust the xa limits at alloc_cyclic time.

v2:
- On CONFIG_DRM_XE_DEBUG, Initialize the cyclic ASID allocation in such a
  way that the next allocated ASID will be the maximum one, and the one
  following will cause an ASID wrap, (all to have CI test high ASIDs
  and ASID wraps).
v3:
- Stricter return value checking from xa_alloc_cyclic() (Matthew Auld)

Suggested-by: Ohad Sharabi <osharabi@habana.ai>
Link: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/946
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: Ohad Sharabi <osharabi@habana.ai> #v1
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231124153345.97385-5-thomas.hellstrom@linux.intel.com
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/xe_device.c
drivers/gpu/drm/xe/xe_vm.c

index 8be765a..d60379d 100644 (file)
@@ -230,7 +230,20 @@ struct xe_device *xe_device_create(struct pci_dev *pdev,
        init_waitqueue_head(&xe->ufence_wq);
 
        drmm_mutex_init(&xe->drm, &xe->usm.lock);
-       xa_init_flags(&xe->usm.asid_to_vm, XA_FLAGS_ALLOC1);
+       xa_init_flags(&xe->usm.asid_to_vm, XA_FLAGS_ALLOC);
+
+       if (IS_ENABLED(CONFIG_DRM_XE_DEBUG)) {
+               /* Trigger a large asid and an early asid wrap. */
+               u32 asid;
+
+               BUILD_BUG_ON(XE_MAX_ASID < 2);
+               err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, NULL,
+                                     XA_LIMIT(XE_MAX_ASID - 2, XE_MAX_ASID - 1),
+                                     &xe->usm.next_asid, GFP_KERNEL);
+               drm_WARN_ON(&xe->drm, err);
+               if (err >= 0)
+                       xa_erase(&xe->usm.asid_to_vm, asid);
+       }
 
        drmm_mutex_init(&xe->drm, &xe->persistent_engines.lock);
        INIT_LIST_HEAD(&xe->persistent_engines.list);
index 1b4d340..7c0ae43 100644 (file)
@@ -1996,13 +1996,14 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data,
        if (xe->info.has_asid) {
                mutex_lock(&xe->usm.lock);
                err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm,
-                                     XA_LIMIT(0, XE_MAX_ASID - 1),
+                                     XA_LIMIT(1, XE_MAX_ASID - 1),
                                      &xe->usm.next_asid, GFP_KERNEL);
                mutex_unlock(&xe->usm.lock);
-               if (err) {
+               if (err < 0) {
                        xe_vm_close_and_put(vm);
                        return err;
                }
+               err = 0;
                vm->usm.asid = asid;
        }