Commit c8a31ff6 authored by Matthew Brost's avatar Matthew Brost

drm/xe: Return -ENOBUFS if a kmalloc fails which is tied to an array of binds

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: default avatarMatthew Brost <matthew.brost@intel.com>
Reviewed-by: default avatarHimal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Reviewed-by: default avatarJonathan Cavitt <jonathan.cavitt@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240723011702.1684013-1-matthew.brost@intel.com
parent 649b93db
...@@ -718,7 +718,7 @@ int xe_vm_userptr_check_repin(struct xe_vm *vm) ...@@ -718,7 +718,7 @@ int xe_vm_userptr_check_repin(struct xe_vm *vm)
list_empty_careful(&vm->userptr.invalidated)) ? 0 : -EAGAIN; 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; int i;
...@@ -731,7 +731,7 @@ static int xe_vma_ops_alloc(struct xe_vma_ops *vops) ...@@ -731,7 +731,7 @@ static int xe_vma_ops_alloc(struct xe_vma_ops *vops)
sizeof(*vops->pt_update_ops[i].ops), sizeof(*vops->pt_update_ops[i].ops),
GFP_KERNEL); GFP_KERNEL);
if (!vops->pt_update_ops[i].ops) if (!vops->pt_update_ops[i].ops)
return -ENOMEM; return array_of_binds ? -ENOBUFS : -ENOMEM;
} }
return 0; return 0;
...@@ -824,7 +824,7 @@ int xe_vm_rebind(struct xe_vm *vm, bool rebind_worker) ...@@ -824,7 +824,7 @@ int xe_vm_rebind(struct xe_vm *vm, bool rebind_worker)
goto free_ops; goto free_ops;
} }
err = xe_vma_ops_alloc(&vops); err = xe_vma_ops_alloc(&vops, false);
if (err) if (err)
goto free_ops; goto free_ops;
...@@ -871,7 +871,7 @@ struct dma_fence *xe_vma_rebind(struct xe_vm *vm, struct xe_vma *vma, u8 tile_ma ...@@ -871,7 +871,7 @@ struct dma_fence *xe_vma_rebind(struct xe_vm *vm, struct xe_vma *vma, u8 tile_ma
if (err) if (err)
return ERR_PTR(err); return ERR_PTR(err);
err = xe_vma_ops_alloc(&vops); err = xe_vma_ops_alloc(&vops, false);
if (err) { if (err) {
fence = ERR_PTR(err); fence = ERR_PTR(err);
goto free_ops; goto free_ops;
...@@ -2761,7 +2761,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, ...@@ -2761,7 +2761,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe,
sizeof(struct drm_xe_vm_bind_op), sizeof(struct drm_xe_vm_bind_op),
GFP_KERNEL | __GFP_ACCOUNT); GFP_KERNEL | __GFP_ACCOUNT);
if (!*bind_ops) if (!*bind_ops)
return -ENOMEM; return args->num_binds > 1 ? -ENOBUFS : -ENOMEM;
err = __copy_from_user(*bind_ops, bind_user, err = __copy_from_user(*bind_ops, bind_user,
sizeof(struct drm_xe_vm_bind_op) * 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) ...@@ -3100,7 +3100,7 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
goto unwind_ops; goto unwind_ops;
} }
err = xe_vma_ops_alloc(&vops); err = xe_vma_ops_alloc(&vops, args->num_binds > 1);
if (err) if (err)
goto unwind_ops; goto unwind_ops;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment