]> www.infradead.org Git - users/hch/configfs.git/commitdiff
drm/xe: Return -ENOBUFS if a kmalloc fails which is tied to an array of binds
authorMatthew Brost <matthew.brost@intel.com>
Tue, 23 Jul 2024 01:17:02 +0000 (18:17 -0700)
committerMatthew Brost <matthew.brost@intel.com>
Tue, 23 Jul 2024 15:03:57 +0000 (08:03 -0700)
The size of an array of binds is directly tied to several kmalloc in the
KMD, thus making these kmalloc more likely to fail. Return -ENOBUFS in
the case of these failures.

The expected UMD behavior upon returning -ENOBUFS is to split an array
of binds into a series of single binds.

v2:
 - Resend for CI
v3:
 - Resend for CI

Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240723011702.1684013-1-matthew.brost@intel.com
drivers/gpu/drm/xe/xe_vm.c

index d8e099347df09b3c1caee3eca9b197c119c06d07..f225107bdd65dcafef5ad6651a527776388e554a 100644 (file)
@@ -718,7 +718,7 @@ int xe_vm_userptr_check_repin(struct xe_vm *vm)
                list_empty_careful(&vm->userptr.invalidated)) ? 0 : -EAGAIN;
 }
 
-static int xe_vma_ops_alloc(struct xe_vma_ops *vops)
+static int xe_vma_ops_alloc(struct xe_vma_ops *vops, bool array_of_binds)
 {
        int i;
 
@@ -731,7 +731,7 @@ static int xe_vma_ops_alloc(struct xe_vma_ops *vops)
                                      sizeof(*vops->pt_update_ops[i].ops),
                                      GFP_KERNEL);
                if (!vops->pt_update_ops[i].ops)
-                       return -ENOMEM;
+                       return array_of_binds ? -ENOBUFS : -ENOMEM;
        }
 
        return 0;
@@ -824,7 +824,7 @@ int xe_vm_rebind(struct xe_vm *vm, bool rebind_worker)
                        goto free_ops;
        }
 
-       err = xe_vma_ops_alloc(&vops);
+       err = xe_vma_ops_alloc(&vops, false);
        if (err)
                goto free_ops;
 
@@ -871,7 +871,7 @@ struct dma_fence *xe_vma_rebind(struct xe_vm *vm, struct xe_vma *vma, u8 tile_ma
        if (err)
                return ERR_PTR(err);
 
-       err = xe_vma_ops_alloc(&vops);
+       err = xe_vma_ops_alloc(&vops, false);
        if (err) {
                fence = ERR_PTR(err);
                goto free_ops;
@@ -2761,7 +2761,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe,
                                           sizeof(struct drm_xe_vm_bind_op),
                                           GFP_KERNEL | __GFP_ACCOUNT);
                if (!*bind_ops)
-                       return -ENOMEM;
+                       return args->num_binds > 1 ? -ENOBUFS : -ENOMEM;
 
                err = __copy_from_user(*bind_ops, bind_user,
                                       sizeof(struct drm_xe_vm_bind_op) *
@@ -3100,7 +3100,7 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
                goto unwind_ops;
        }
 
-       err = xe_vma_ops_alloc(&vops);
+       err = xe_vma_ops_alloc(&vops, args->num_binds > 1);
        if (err)
                goto unwind_ops;