* [PATCH v3 0/3] drm/msm: Fix VM_BIND job, queue and entity lifetimes
@ 2026-11-14 14:18 Jiwoo Kim
2026-11-14 14:18 ` [PATCH v3 1/3] drm/msm: Release the pins and ops of a killed VM_BIND job Jiwoo Kim
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Jiwoo Kim @ 2026-11-14 14:18 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov
Cc: Akhil P Oommen, Konrad Dybcio, Anna Maniscalco,
Julius Bairaktaris, Abhinav Kumar, Jessica Zhang, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter, linux-arm-msm,
dri-devel, freedreno, linux-kernel, stable
These fix what happens to VM_BIND jobs, queues and entities when the
file or a VM_BIND queue is closed while jobs are still pending.
Patch 1 makes a VM_BIND job that the scheduler kills before it runs
apply its queued unmaps before it drops the references that keep the
unmapped pages alive, release its BO pins, and mark the VM unusable,
as the VM no longer matches its pgtables. Patch 2 destroys the VM_BIND
entity when its queue is closed, instead of on the final put, which can
come after the VM's scheduler has been torn down. Patch 3 puts the
queue last when a job is freed, as the queue may hold the last
reference to the VM.
Changes in v3:
- Patch 1: only apply the queued ops of a job that the scheduler frees
after killing it, once its dependencies and the previous job of its
entity are done. The error path of msm_ioctl_vm_bind() frees the job
right away, so v2 could apply its unmaps too early and out of order
(Sashiko). That path is left as it is in mainline, and the title now
says which jobs the patch is about.
- Patch 3: rebased on patch 1, title adjusted.
Changes in v2:
- New patch 1, for an issue that Sashiko reported on v1 patch 1, which
that patch makes easier to hit.
- Patch 2: changelog refers to patch 1.
v2: https://lore.kernel.org/r/20261114081902.1669-1-arpe1618@gmail.com
v1: https://lore.kernel.org/r/20261114062541.2001-1-arpe1618@gmail.com
Jiwoo Kim (3):
drm/msm: Release the pins and ops of a killed VM_BIND job
drm/msm: Destroy the VM_BIND entity when its queue is closed
drm/msm: Put the VM_BIND queue last when freeing a VM_BIND job
drivers/gpu/drm/msm/msm_gem_vma.c | 99 +++++++++++++++++++++++----
drivers/gpu/drm/msm/msm_gpu.h | 6 ++
drivers/gpu/drm/msm/msm_submitqueue.c | 50 ++++++++++----
3 files changed, 128 insertions(+), 27 deletions(-)
base-commit: 1e59855738454b14021b64115f0090eafc7526ae
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v3 1/3] drm/msm: Release the pins and ops of a killed VM_BIND job
2026-11-14 14:18 [PATCH v3 0/3] drm/msm: Fix VM_BIND job, queue and entity lifetimes Jiwoo Kim
@ 2026-11-14 14:18 ` Jiwoo Kim
2026-11-14 14:18 ` [PATCH v3 2/3] drm/msm: Destroy the VM_BIND entity when its queue is closed Jiwoo Kim
2026-11-14 14:18 ` [PATCH v3 3/3] drm/msm: Put the VM_BIND queue last when freeing a VM_BIND job Jiwoo Kim
2 siblings, 0 replies; 4+ messages in thread
From: Jiwoo Kim @ 2026-11-14 14:18 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov
Cc: Akhil P Oommen, Konrad Dybcio, Anna Maniscalco,
Julius Bairaktaris, Abhinav Kumar, Jessica Zhang, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter, linux-arm-msm,
dri-devel, freedreno, linux-kernel, stable
msm_vma_job_run() applies the pgtable updates that vm_bind_job_prepare()
queued for a VM_BIND job, drops the GEM object references that
vm_op_enqueue() took for them, and unpins the BOs of the job. When the
entity of a job is killed, e.g. on SIGKILL while the process exits, the
scheduler frees the job without running it. msm_vma_job_free() then
frees the queued ops without applying them and without dropping their
references, and leaves the BOs pinned. Besides the leaks, the VM no
longer matches its pgtables: for example, the pages of a VMA that was
unmapped from the VM are still mapped.
The scheduler only frees a killed job once its dependencies have
signalled and the job queued before it on the same entity has run or
been killed, so the updates of the jobs that ran before it have all been
applied by then. In msm_vma_job_free(), apply the queued updates the way
msm_vma_job_run() does on error: skip the maps, but apply the unmaps, so
that their references can be dropped without freeing pages that are
still mapped, and mark the VM unusable. Killed jobs can be freed
concurrently, but as they only unmap, their order does not matter. Move
that part of msm_vma_job_run() into a helper for this. Also clear
bos_pinned once msm_vma_job_run() has unpinned the BOs, as msm_job_run()
does for submits, and unpin the BOs of a job that still has them pinned,
taking the object lock, as the job's fence does not keep them busy
anymore.
msm_ioctl_vm_bind() frees a job that fails right away, before its
dependencies and the previous jobs of its queue have completed, so the
queued updates of such a job must not be applied. Move the freeing
itself into vm_bind_job_free(), and call that directly from there.
The patch and its changelog were drafted with an AI coding assistant.
The issue has not been reproduced, and the change has only been
compile-tested.
Fixes: 2e6a8a1fe2b2 ("drm/msm: Add VM_BIND ioctl")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/r/sashiko-outbox-214234@kernel.org
Signed-off-by: Jiwoo Kim <arpe1618@gmail.com>
---
At commit 2e6a8a1fe2b2, msm_vma_job_run() still unpinned the BOs under
the object lock, and msm_gem_vm_unusable() did not exist yet, so older
stable trees need an adapted backport.
Julius Bairaktaris' "drm/msm: Keep objects of queued VM_BIND unmaps
busy" keeps the objects of queued unmaps busy with the job's fence:
https://lore.kernel.org/r/20261111080619.244138-1-julius@bairaktaris.de
For a killed job, the scheduler signals that fence before it calls
free_job(), so with both patches, these objects are no longer busy for
the short time until this patch applies the unmaps. Without this patch,
the unmaps of a killed job are never applied. Closing that window would
need the objects to stay pinned until their unmaps are applied. The two
patches apply in either order.
Not addressed here, as before this patch:
- The error path of msm_ioctl_vm_bind() still frees the queued ops of a
failed job without applying them or dropping their references. Their
unmaps could only be applied after the job's dependencies and the
previous jobs of its queue, i.e. by queuing the job anyway.
- The issues in the error handling of vm_bind_job_prepare() that
Sashiko listed for v2: a VMA left in the VM when vm_op_enqueue()
fails, which a later remap of a MAP_NULL area turns into a NULL
dereference, and the vm_bo reference in msm_gem_vm_sm_step_remap().
drivers/gpu/drm/msm/msm_gem_vma.c | 87 ++++++++++++++++++++++++++-----
1 file changed, 75 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c
index 8b702422030a..0b9f2e8916b7 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -700,16 +700,16 @@ static const struct drm_gpuvm_ops msm_gpuvm_ops = {
.sm_step_unmap = msm_gem_vm_sm_step_unmap,
};
-static struct dma_fence *
-msm_vma_job_run(struct drm_sched_job *_job)
+/*
+ * Apply the pgtable updates queued for a job, and drop the references that
+ * the ops hold. If ret is an error, or one occurs, the remaining maps are
+ * skipped, but the unmaps are still applied, as the pages they unmap must
+ * not be freed while they are still mapped.
+ */
+static int
+vm_bind_job_apply_ops(struct msm_vm_bind_job *job, int ret)
{
- struct msm_vm_bind_job *job = to_msm_vm_bind_job(_job);
- struct drm_device *dev = job->vm->drm;
struct msm_gem_vm *vm = to_msm_vm(job->vm);
- struct drm_gem_object *obj;
- int ret = vm->unusable ? -EINVAL : 0;
-
- vm_dbg("");
mutex_lock(&vm->mmu_lock);
vm->mmu->prealloc = &job->prealloc;
@@ -740,6 +740,22 @@ msm_vma_job_run(struct drm_sched_job *_job)
vm->mmu->prealloc = NULL;
mutex_unlock(&vm->mmu_lock);
+ return ret;
+}
+
+static struct dma_fence *
+msm_vma_job_run(struct drm_sched_job *_job)
+{
+ struct msm_vm_bind_job *job = to_msm_vm_bind_job(_job);
+ struct drm_device *dev = job->vm->drm;
+ struct msm_gem_vm *vm = to_msm_vm(job->vm);
+ struct drm_gem_object *obj;
+ int ret;
+
+ vm_dbg("");
+
+ ret = vm_bind_job_apply_ops(job, vm->unusable ? -EINVAL : 0);
+
/*
* We failed to perform at least _some_ of the pgtable updates, so
* now the VM is in an undefined state. Game over!
@@ -753,16 +769,22 @@ msm_vma_job_run(struct drm_sched_job *_job)
msm_gem_unpin_active(obj);
}
+ job->bos_pinned = false;
+
mutex_unlock(&dev->gem_lru_mutex);
/* VM_BIND ops are synchronous, so no fence to wait on: */
return NULL;
}
+/*
+ * Free a job, whether it ran or not. Ops that are still queued are freed
+ * without being applied, and without dropping their object references, as
+ * the pages of their unmaps may still be mapped.
+ */
static void
-msm_vma_job_free(struct drm_sched_job *_job)
+vm_bind_job_free(struct msm_vm_bind_job *job)
{
- struct msm_vm_bind_job *job = to_msm_vm_bind_job(_job);
struct msm_gem_vm *vm = to_msm_vm(job->vm);
struct drm_gem_object *obj;
@@ -770,7 +792,20 @@ msm_vma_job_free(struct drm_sched_job *_job)
atomic_sub(job->prealloc.count, &vm->prealloc_throttle.in_flight);
- drm_sched_job_cleanup(_job);
+ drm_sched_job_cleanup(&job->base);
+
+ /*
+ * A job that was killed before it ran still has its BOs pinned. The
+ * job's fence does not keep them busy anymore, so take the object lock
+ * to unpin them.
+ */
+ if (job->bos_pinned) {
+ job_foreach_bo(obj, job) {
+ msm_gem_lock(obj);
+ msm_gem_unpin_locked(obj);
+ msm_gem_unlock(obj);
+ }
+ }
job_foreach_bo (obj, job)
drm_gem_object_put(obj);
@@ -791,6 +826,29 @@ msm_vma_job_free(struct drm_sched_job *_job)
kfree(job);
}
+static void
+msm_vma_job_free(struct drm_sched_job *_job)
+{
+ struct msm_vm_bind_job *job = to_msm_vm_bind_job(_job);
+
+ /*
+ * A job that the scheduler frees without having run it was killed,
+ * e.g. because its entity was destroyed. Its queued updates were
+ * already applied to the VM's address space, but not to its pgtables.
+ * The scheduler has waited for the job's dependencies, and for the job
+ * before it on the entity to run or be killed, so apply its unmaps now,
+ * before the references to the unmapped objects are dropped, and give
+ * up on the VM, as its maps are skipped. Killed jobs only unmap, so
+ * the order in which they are freed does not matter.
+ */
+ if (!list_empty(&job->vm_ops)) {
+ vm_bind_job_apply_ops(job, -ECANCELED);
+ msm_gem_vm_unusable(job->vm);
+ }
+
+ vm_bind_job_free(job);
+}
+
static const struct drm_sched_backend_ops msm_vm_bind_ops = {
.run_job = msm_vma_job_run,
.free_job = msm_vma_job_free
@@ -1607,8 +1665,13 @@ msm_ioctl_vm_bind(struct drm_device *dev, void *data, struct drm_file *file)
}
if (!IS_ERR_OR_NULL(job)) {
+ /*
+ * Not msm_vma_job_free(): the job's dependencies and the
+ * previous jobs of the queue may not have completed, so its
+ * queued updates must not be applied here.
+ */
if (ret)
- msm_vma_job_free(&job->base);
+ vm_bind_job_free(job);
} else {
/*
* If the submit hasn't yet taken ownership of the queue
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v3 2/3] drm/msm: Destroy the VM_BIND entity when its queue is closed
2026-11-14 14:18 [PATCH v3 0/3] drm/msm: Fix VM_BIND job, queue and entity lifetimes Jiwoo Kim
2026-11-14 14:18 ` [PATCH v3 1/3] drm/msm: Release the pins and ops of a killed VM_BIND job Jiwoo Kim
@ 2026-11-14 14:18 ` Jiwoo Kim
2026-11-14 14:18 ` [PATCH v3 3/3] drm/msm: Put the VM_BIND queue last when freeing a VM_BIND job Jiwoo Kim
2 siblings, 0 replies; 4+ messages in thread
From: Jiwoo Kim @ 2026-11-14 14:18 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov
Cc: Akhil P Oommen, Konrad Dybcio, Anna Maniscalco,
Julius Bairaktaris, Abhinav Kumar, Jessica Zhang, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter, linux-arm-msm,
dri-devel, freedreno, linux-kernel, stable
The entity of a VM_BIND submitqueue is attached to the per-VM scheduler,
and msm_gem_vm_close() calls drm_sched_fini() on that scheduler when the
file is closed, which frees its run queues. The submitqueue itself is
only destroyed on its final put, though, and every VM_BIND job holds a
reference to it. msm_submitqueue_close() only flushes the entity, and a
queue that was closed earlier with MSM_SUBMITQUEUE_CLOSE is not flushed
at all.
The flush gives up after a timeout when the process exits, or on a
fatal signal, and it only kills the queued jobs when the process exits
because of SIGKILL. In these cases, and after MSM_SUBMITQUEUE_CLOSE,
the entity can still have a callback armed on the in-fence of a
VM_BIND job when drm_sched_fini() runs. When that fence signals,
drm_sched_entity_wakeup() dereferences entity->rq->sched, and so reads
a run queue that drm_sched_fini() has freed. If the jobs were killed,
the final put of the queue then calls drm_sched_entity_destroy(), which
reads the same freed run queue in drm_sched_entity_flush(). If they
were not, they never run, and keep the queue, its context and the VM
alive.
Destroy the VM_BIND entity when userspace closes the queue, on file
close or with MSM_SUBMITQUEUE_CLOSE, instead of on the final put, and
refuse new VM_BIND jobs on a closed queue. In the MSM_SUBMITQUEUE_CLOSE
path, do it after dropping ctxlock, as destroying the entity waits for
the jobs queued on it.
As a result, MSM_SUBMITQUEUE_CLOSE on a VM_BIND queue now waits
(killably) for the jobs already queued on it, and a fatal signal during
that wait cancels the remaining ones, where they used to still run. On
file close, the jobs still queued when the wait gives up are now always
cancelled, as they already were when the process was killed while
exiting, instead of being left on the entity. With the previous patch,
such jobs apply their unmaps and release their pins and references.
This was found with an AI coding assistant, which also drafted this
patch and its changelog. It has not been reproduced, and the change
has only been compile-tested.
Fixes: 92395af63a99 ("drm/msm: Add VM_BIND submitqueue")
Cc: stable@vger.kernel.org
Signed-off-by: Jiwoo Kim <arpe1618@gmail.com>
---
The scoped_guard() in msm_submitqueue_remove() relies on commit
ea69d489d3a6 ("drm/msm: Rework queuelock"), so trees older than v7.3
need a manual backport.
If MSM_SUBMITQUEUE_CLOSE should rather not block, the destroy of closed
VM_BIND queues could instead be deferred to file close, e.g. with a
per-context list of them. That would also keep the ioctl out of a
killable wait for the queued jobs, which the freezer cannot interrupt.
drivers/gpu/drm/msm/msm_gem_vma.c | 5 +++
drivers/gpu/drm/msm/msm_gpu.h | 6 ++++
drivers/gpu/drm/msm/msm_submitqueue.c | 50 +++++++++++++++++++--------
3 files changed, 47 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c
index 0b9f2e8916b7..ce9d97582df5 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -1557,6 +1557,11 @@ msm_ioctl_vm_bind(struct drm_device *dev, void *data, struct drm_file *file)
if (ret)
goto out_post_unlock;
+ if (queue->vm_bind_closed) {
+ ret = -ENOENT;
+ goto out_unlock;
+ }
+
if (args->flags & MSM_VM_BIND_FENCE_FD_IN) {
struct dma_fence *in_fence;
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index bc5b31eb1eca..561f2d998e99 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -596,6 +596,12 @@ struct msm_gpu_submitqueue {
struct kref ref;
struct drm_sched_entity *entity;
+ /**
+ * @vm_bind_closed: the queue was closed by userspace, and its VM_BIND
+ * entity is being or has been destroyed. Protected by @lock.
+ */
+ bool vm_bind_closed;
+
/** @_vm_bind_entity: used for @entity pointer for VM_BIND queues */
struct drm_sched_entity _vm_bind_entity[0];
};
diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c b/drivers/gpu/drm/msm/msm_submitqueue.c
index 8d550d281704..2dbe42551bd8 100644
--- a/drivers/gpu/drm/msm/msm_submitqueue.c
+++ b/drivers/gpu/drm/msm/msm_submitqueue.c
@@ -79,9 +79,6 @@ void msm_submitqueue_destroy(struct kref *kref)
idr_destroy(&queue->fence_idr);
- if (queue->entity == &queue->_vm_bind_entity[0])
- drm_sched_entity_destroy(queue->entity);
-
msm_context_put(queue->ctx);
kfree(queue);
@@ -107,6 +104,25 @@ struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_context *ctx,
return NULL;
}
+/*
+ * The VM_BIND scheduler is torn down by msm_gem_vm_close() when the file is
+ * closed, but a VM_BIND queue can outlive that, as long as a job still holds
+ * a reference to it. So destroy the VM_BIND entity here, when userspace
+ * closes the queue, rather than on the final put. Both ways a queue is taken
+ * off ctx->submitqueues come through here.
+ */
+static void msm_submitqueue_close_vm_bind(struct msm_gpu_submitqueue *queue)
+{
+ if (queue->entity != &queue->_vm_bind_entity[0])
+ return;
+
+ mutex_lock(&queue->lock);
+ queue->vm_bind_closed = true;
+ mutex_unlock(&queue->lock);
+
+ drm_sched_entity_destroy(queue->entity);
+}
+
void msm_submitqueue_close(struct msm_context *ctx)
{
struct msm_gpu_submitqueue *queue, *tmp;
@@ -119,8 +135,7 @@ void msm_submitqueue_close(struct msm_context *ctx)
* be any more user ioctls coming our way
*/
list_for_each_entry_safe(queue, tmp, &ctx->submitqueues, node) {
- if (queue->entity == &queue->_vm_bind_entity[0])
- drm_sched_entity_flush(queue->entity, MAX_WAIT_SCHED_ENTITY_Q_EMPTY);
+ msm_submitqueue_close_vm_bind(queue);
list_del(&queue->node);
msm_submitqueue_put(queue);
}
@@ -326,7 +341,7 @@ int msm_submitqueue_query(struct drm_device *drm, struct msm_context *ctx,
int msm_submitqueue_remove(struct msm_context *ctx, u32 id)
{
- struct msm_gpu_submitqueue *entry;
+ struct msm_gpu_submitqueue *entry, *queue = NULL;
if (!ctx)
return 0;
@@ -338,16 +353,23 @@ int msm_submitqueue_remove(struct msm_context *ctx, u32 id)
if (!id)
return -ENOENT;
- guard(rwsem_write)(&ctx->ctxlock);
-
- list_for_each_entry(entry, &ctx->submitqueues, node) {
- if (entry->id == id) {
- list_del(&entry->node);
- msm_submitqueue_put(entry);
- return 0;
+ scoped_guard(rwsem_write, &ctx->ctxlock) {
+ list_for_each_entry(entry, &ctx->submitqueues, node) {
+ if (entry->id == id) {
+ list_del(&entry->node);
+ queue = entry;
+ break;
+ }
}
}
- return -ENOENT;
+ if (!queue)
+ return -ENOENT;
+
+ /* Not under ctxlock: destroying the entity can wait for its jobs */
+ msm_submitqueue_close_vm_bind(queue);
+ msm_submitqueue_put(queue);
+
+ return 0;
}
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v3 3/3] drm/msm: Put the VM_BIND queue last when freeing a VM_BIND job
2026-11-14 14:18 [PATCH v3 0/3] drm/msm: Fix VM_BIND job, queue and entity lifetimes Jiwoo Kim
2026-11-14 14:18 ` [PATCH v3 1/3] drm/msm: Release the pins and ops of a killed VM_BIND job Jiwoo Kim
2026-11-14 14:18 ` [PATCH v3 2/3] drm/msm: Destroy the VM_BIND entity when its queue is closed Jiwoo Kim
@ 2026-11-14 14:18 ` Jiwoo Kim
2 siblings, 0 replies; 4+ messages in thread
From: Jiwoo Kim @ 2026-11-14 14:18 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov
Cc: Akhil P Oommen, Konrad Dybcio, Anna Maniscalco,
Julius Bairaktaris, Abhinav Kumar, Jessica Zhang, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter, linux-arm-msm,
dri-devel, freedreno, linux-kernel, stable
vm_bind_job_free() puts the job's submitqueue and then wakes up
vm->prealloc_throttle.wait. The job does not hold a reference to the
VM of its own: the VM is kept alive by the context, which the queue
holds a reference to. When the job holds the last reference to the
queue, as it can once the file has been closed, for example when a
killed job is freed, the put can drop the last reference to the VM,
and the wakeup then uses a VM that msm_gem_vm_free() has released.
Since commit 01c8d1f385f7 ("drm/msm: RCU-free the scheduler-containing
ring and VM objects"), msm_gem_vm_free() frees the VM with kfree_rcu(),
but vm_bind_job_free() is not in an RCU read-side critical section, so
a grace period can still end before the wakeup, e.g. if the task is
preempted in between. Before that commit, the VM was freed right away.
Put the queue only after the last use of the VM.
This was found with an AI coding assistant, which also drafted this
patch and its changelog. It has not been reproduced, and the change
has only been compile-tested.
Fixes: b74fae5492d1 ("drm/msm: Add VM_BIND throttling")
Cc: stable@vger.kernel.org
Signed-off-by: Jiwoo Kim <arpe1618@gmail.com>
---
drivers/gpu/drm/msm/msm_gem_vma.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c
index ce9d97582df5..07f427c4afad 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -810,7 +810,6 @@ vm_bind_job_free(struct msm_vm_bind_job *job)
job_foreach_bo (obj, job)
drm_gem_object_put(obj);
- msm_submitqueue_put(job->queue);
dma_fence_put(job->fence);
/* In error paths, we could have unexecuted ops: */
@@ -823,6 +822,12 @@ vm_bind_job_free(struct msm_vm_bind_job *job)
wake_up(&vm->prealloc_throttle.wait);
+ /*
+ * The queue may hold the last reference to the context, and so to the
+ * VM, so put it only once we are done with the VM.
+ */
+ msm_submitqueue_put(job->queue);
+
kfree(job);
}
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-14 14:19 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-14 14:18 [PATCH v3 0/3] drm/msm: Fix VM_BIND job, queue and entity lifetimes Jiwoo Kim
2026-11-14 14:18 ` [PATCH v3 1/3] drm/msm: Release the pins and ops of a killed VM_BIND job Jiwoo Kim
2026-11-14 14:18 ` [PATCH v3 2/3] drm/msm: Destroy the VM_BIND entity when its queue is closed Jiwoo Kim
2026-11-14 14:18 ` [PATCH v3 3/3] drm/msm: Put the VM_BIND queue last when freeing a VM_BIND job Jiwoo Kim
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®