}
 
 static struct dma_fence *ops_execute(struct xe_vm *vm,
-                                    struct xe_vma_ops *vops,
-                                    bool cleanup);
+                                    struct xe_vma_ops *vops);
 static void xe_vma_ops_init(struct xe_vma_ops *vops);
 
 int xe_vm_rebind(struct xe_vm *vm, bool rebind_worker)
                        goto free_ops;
        }
 
-       fence = ops_execute(vm, &vops, false);
+       fence = ops_execute(vm, &vops);
        if (IS_ERR(fence)) {
                err = PTR_ERR(fence);
        } else {
        if (!last_op)
                return 0;
 
-       last_op->ops = ops;
        if (last) {
                last_op->flags |= XE_VMA_OP_LAST;
                last_op->num_syncs = num_syncs;
        return fence;
 }
 
-static void xe_vma_op_cleanup(struct xe_vm *vm, struct xe_vma_op *op)
-{
-       bool last = op->flags & XE_VMA_OP_LAST;
-
-       if (last) {
-               while (op->num_syncs--)
-                       xe_sync_entry_cleanup(&op->syncs[op->num_syncs]);
-               kfree(op->syncs);
-               if (op->q)
-                       xe_exec_queue_put(op->q);
-       }
-       if (!list_empty(&op->link))
-               list_del(&op->link);
-       if (op->ops)
-               drm_gpuva_ops_free(&vm->gpuvm, op->ops);
-       if (last)
-               xe_vm_put(vm);
-}
-
 static void xe_vma_op_unwind(struct xe_vm *vm, struct xe_vma_op *op,
                             bool post_commit, bool prev_post_commit,
                             bool next_post_commit)
                                         op->flags & XE_VMA_OP_PREV_COMMITTED,
                                         op->flags & XE_VMA_OP_NEXT_COMMITTED);
                }
-
-               drm_gpuva_ops_free(&vm->gpuvm, __ops);
        }
 }
 
 }
 
 static struct dma_fence *ops_execute(struct xe_vm *vm,
-                                    struct xe_vma_ops *vops,
-                                    bool cleanup)
+                                    struct xe_vma_ops *vops)
 {
        struct xe_vma_op *op, *next;
        struct dma_fence *fence = NULL;
 
        list_for_each_entry_safe(op, next, &vops->list, link) {
-               if (!IS_ERR(fence)) {
-                       dma_fence_put(fence);
-                       fence = xe_vma_op_execute(vm, op);
-               }
+               dma_fence_put(fence);
+               fence = xe_vma_op_execute(vm, op);
                if (IS_ERR(fence)) {
                        drm_warn(&vm->xe->drm, "VM op(%d) failed with %ld",
                                 op->base.op, PTR_ERR(fence));
                        fence = ERR_PTR(-ENOSPC);
+                       break;
                }
-               if (cleanup)
-                       xe_vma_op_cleanup(vm, op);
        }
 
        return fence;
                if (err)
                        goto unlock;
 
-               fence = ops_execute(vm, vops, true);
+               fence = ops_execute(vm, vops);
                if (IS_ERR(fence)) {
                        err = PTR_ERR(fence);
                        /* FIXME: Killing VM rather than proper error handling */
                goto unwind_ops;
        }
 
-       xe_vm_get(vm);
-       if (q)
-               xe_exec_queue_get(q);
-
        err = vm_bind_ioctl_ops_execute(vm, &vops);
 
-       up_write(&vm->lock);
-
-       if (q)
-               xe_exec_queue_put(q);
-       xe_vm_put(vm);
-
-       for (i = 0; bos && i < args->num_binds; ++i)
-               xe_bo_put(bos[i]);
-
-       kvfree(bos);
-       kvfree(ops);
-       if (args->num_binds > 1)
-               kvfree(bind_ops);
-
-       return err;
-
 unwind_ops:
-       vm_bind_ioctl_ops_unwind(vm, ops, args->num_binds);
+       if (err && err != -ENODATA)
+               vm_bind_ioctl_ops_unwind(vm, ops, args->num_binds);
+       for (i = args->num_binds - 1; i >= 0; --i)
+               if (ops[i])
+                       drm_gpuva_ops_free(&vm->gpuvm, ops[i]);
 free_syncs:
        if (err == -ENODATA)
                err = vm_bind_ioctl_signal_fences(vm, q, syncs, num_syncs);