Hi Iago,

On 02/07/26 03:44, Iago Toral wrote:
I think we probably want to add a comment in v3d_submit_cl_ioctl when
we setup the bin job explaining why we postpone looking up the BO list
until the render job.

With that, this is: Reviewed-by: Iago Toral Quiroga <[email protected]>


Thanks for the review!

Also, unrelated to this patch: should we not use the same
v3d_lookup_bos helper in the TFU submit path instead of having a loop
looking up individual BOs one by one?

TFU uses a fixed BO array with the handles (__u32 bo_handles[4]) instead
of a u64 variable that points to the array. That's why the treatment is
different.

Best regards,
- Maíra


Iago

El jue, 18-06-2026 a las 12:03 -0300, Maíra Canal escribió:
A submission can expand into a chain of jobs (e.g. bin + render +
cache
clean), but v3d_lookup_bos() only looked up the user's BO list onto
the
*last* job of the submission. Every earlier job was left with
bo_count == 0 and an empty bo[] array.

As a consequence, when implicit synchronization happens in
v3d_submit_lock_reservations(), earlier jobs get no implicit
dependencies at all, as the loop is gated on job->bo_count and
earlier
jobs don't have any BO attached to them. With that, the RENDER job
could
therefore be dispatched to the hardware and read a BO while another
context
was still writing it, leading to data corruption.

Fix this by calling v3d_lookup_bos() for each job that references the
submission's BOs, so every job carries its own bo[]/bo_count and
picks
up the correct implicit dependencies during reservation locking.

Fixes: dffa9b7a78c4 ("drm/v3d: Add missing implicit
synchronization.")
Signed-off-by: Maíra Canal <[email protected]>
---
  drivers/gpu/drm/v3d/v3d_submit.c | 36 +++++++++++++++++-------------
------
  1 file changed, 17 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/v3d/v3d_submit.c
b/drivers/gpu/drm/v3d/v3d_submit.c
index ee2ac2540ed5..18467e448c91 100644
--- a/drivers/gpu/drm/v3d/v3d_submit.c
+++ b/drivers/gpu/drm/v3d/v3d_submit.c
@@ -68,7 +68,6 @@ v3d_submit_unlock_reservations(struct v3d_submit
*submit)
  /**
   * v3d_lookup_bos() - Sets up job->bo[] with the GEM objects
   * referenced by the job.
- * @dev: DRM device
   * @file_priv: DRM file for this fd
   * @job: V3D job being set up
   * @bo_handles: GEM handles
@@ -82,23 +81,19 @@ v3d_submit_unlock_reservations(struct v3d_submit
*submit)
   * failure, because that will happen at `v3d_job_free()`.
   */
  static int
-v3d_lookup_bos(struct v3d_submit *submit, u64 bo_handles, u32
bo_count)
+v3d_lookup_bos(struct drm_file *file_priv, struct v3d_job *job,
+              u64 bo_handles, u32 bo_count)
  {
-       struct v3d_job *last_job = submit->jobs[submit->job_count -
1];
-
-       last_job->bo_count = bo_count;
-
-       if (!last_job->bo_count) {
-               /* See comment on bo_index for why we have to check
-                * this.
-                */
-               drm_warn(&submit->v3d->drm, "Rendering requires
BOs\n");
+       if (!bo_count) {
+               drm_warn(&job->v3d->drm, "Rendering requires
BOs\n");
                return -EINVAL;
        }
- return drm_gem_objects_lookup(submit->file_priv,
+       job->bo_count = bo_count;
+
+       return drm_gem_objects_lookup(file_priv,
                                      (void __user
*)(uintptr_t)bo_handles,
-                                     last_job->bo_count, &last_job-
bo);
+                                     job->bo_count, &job->bo);
  }
 static void
@@ -446,7 +441,8 @@ v3d_setup_csd_jobs_and_bos(struct v3d_submit
*submit,
        if (IS_ERR(clean_job))
                return PTR_ERR(clean_job);
- return v3d_lookup_bos(submit, args->bo_handles, args-
bo_handle_count);
+       return v3d_lookup_bos(submit->file_priv, &job->base,
+                             args->bo_handles, args-
bo_handle_count);
  }
 static void
@@ -1085,6 +1081,11 @@ v3d_submit_cl_ioctl(struct drm_device *dev,
void *data,
        if (ret)
                goto fail;
+ ret = v3d_lookup_bos(submit.file_priv, &render->base,
+                            args->bo_handles, args-
bo_handle_count);
+       if (ret)
+               goto fail;
+
        if (args->flags & DRM_V3D_SUBMIT_CL_FLUSH_CACHE) {
                clean_job = v3d_submit_add_job(&submit,
V3D_CACHE_CLEAN);
                if (IS_ERR(clean_job)) {
@@ -1097,10 +1098,6 @@ v3d_submit_cl_ioctl(struct drm_device *dev,
void *data,
        if (ret)
                goto fail;
- ret = v3d_lookup_bos(&submit, args->bo_handles, args-
bo_handle_count);
-       if (ret)
-               goto fail;
-
        ret = v3d_submit_lock_reservations(&submit);
        if (ret)
                goto fail;
@@ -1359,7 +1356,8 @@ v3d_submit_cpu_ioctl(struct drm_device *dev,
void *data,
         * the CSD and clean jobs in the case of indirect CSD job.
         */
        if (args->bo_handle_count) {
-               ret = v3d_lookup_bos(&submit, args->bo_handles,
args->bo_handle_count);
+               ret = v3d_lookup_bos(submit.file_priv, &cpu_job-
base,
+                                    args->bo_handles, args-
bo_handle_count);
                if (ret)
                        goto fail;
        }



Reply via email to