Message ID | 20220331204651.2699107-2-daniel.vetter@ffwll.ch (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/4] drm/etnaviv: Use scheduler dependency handling | expand |
Am 31.03.22 um 22:46 schrieb Daniel Vetter: > We need to pull the drm_sched_job_init much earlier, but that's very > minor surgery. > > v2: Actually fix up cleanup paths by calling drm_sched_job_init, which > I wanted to to in the previous round (and did, for all other drivers). > Spotted by Lucas. > > v3: Rebase over renamed functions to add dependencies. > > v4: Rebase over patches from Christian. > > v5: More rebasing over work from Christian. > > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> > Cc: Lucas Stach <l.stach@pengutronix.de> > Cc: Russell King <linux+etnaviv@armlinux.org.uk> > Cc: Christian Gmeiner <christian.gmeiner@gmail.com> > Cc: Sumit Semwal <sumit.semwal@linaro.org> > Cc: "Christian König" <christian.koenig@amd.com> > Cc: etnaviv@lists.freedesktop.org > Cc: linux-media@vger.kernel.org > Cc: linaro-mm-sig@lists.linaro.org Reviewed-by: Christian König <christian.koenig@amd.com> But Lucas should probably ack that we merge it through drm-misc-next. > --- > drivers/gpu/drm/etnaviv/etnaviv_gem.h | 4 +- > drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 51 +++++++++++-------- > drivers/gpu/drm/etnaviv/etnaviv_sched.c | 53 +------------------- > drivers/gpu/drm/etnaviv/etnaviv_sched.h | 3 +- > 4 files changed, 35 insertions(+), 76 deletions(-) > > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.h b/drivers/gpu/drm/etnaviv/etnaviv_gem.h > index 8983a0ef383e..63688e6e4580 100644 > --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.h > +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.h > @@ -80,8 +80,6 @@ struct etnaviv_gem_submit_bo { > u64 va; > struct etnaviv_gem_object *obj; > struct etnaviv_vram_mapping *mapping; > - unsigned int nr_fences; > - struct dma_fence **fences; > }; > > /* Created per submit-ioctl, to track bo's and cmdstream bufs, etc, > @@ -94,7 +92,7 @@ struct etnaviv_gem_submit { > struct etnaviv_file_private *ctx; > struct etnaviv_gpu *gpu; > struct etnaviv_iommu_context *mmu_context, *prev_mmu_context; > - struct dma_fence *out_fence, *in_fence; > + struct dma_fence *out_fence; > int out_fence_id; > struct list_head node; /* GPU active submit list */ > struct etnaviv_cmdbuf cmdbuf; > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c > index 592cbb38609a..5f502c49aec2 100644 > --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c > +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c > @@ -188,9 +188,9 @@ static int submit_fence_sync(struct etnaviv_gem_submit *submit) > if (submit->flags & ETNA_SUBMIT_NO_IMPLICIT) > continue; > > - ret = dma_resv_get_fences(robj, > - bo->flags & ETNA_SUBMIT_BO_WRITE, > - &bo->nr_fences, &bo->fences); > + ret = drm_sched_job_add_implicit_dependencies(&submit->sched_job, > + &bo->obj->base, > + bo->flags & ETNA_SUBMIT_BO_WRITE); > if (ret) > return ret; > } > @@ -398,8 +398,6 @@ static void submit_cleanup(struct kref *kref) > > wake_up_all(&submit->gpu->fence_event); > > - if (submit->in_fence) > - dma_fence_put(submit->in_fence); > if (submit->out_fence) { > /* first remove from IDR, so fence can not be found anymore */ > mutex_lock(&submit->gpu->fence_lock); > @@ -530,58 +528,69 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, > ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &submit->cmdbuf, > ALIGN(args->stream_size, 8) + 8); > if (ret) > - goto err_submit_objects; > + goto err_submit_put; > > submit->ctx = file->driver_priv; > submit->mmu_context = etnaviv_iommu_context_get(submit->ctx->mmu); > submit->exec_state = args->exec_state; > submit->flags = args->flags; > > + ret = drm_sched_job_init(&submit->sched_job, > + &ctx->sched_entity[args->pipe], > + submit->ctx); > + if (ret) > + goto err_submit_put; > + > ret = submit_lookup_objects(submit, file, bos, args->nr_bos); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > if ((priv->mmu_global->version != ETNAVIV_IOMMU_V2) && > !etnaviv_cmd_validate_one(gpu, stream, args->stream_size / 4, > relocs, args->nr_relocs)) { > ret = -EINVAL; > - goto err_submit_objects; > + goto err_submit_job; > } > > if (args->flags & ETNA_SUBMIT_FENCE_FD_IN) { > - submit->in_fence = sync_file_get_fence(args->fence_fd); > - if (!submit->in_fence) { > + struct dma_fence *in_fence = sync_file_get_fence(args->fence_fd); > + if (!in_fence) { > ret = -EINVAL; > - goto err_submit_objects; > + goto err_submit_job; > } > + > + ret = drm_sched_job_add_dependency(&submit->sched_job, > + in_fence); > + if (ret) > + goto err_submit_job; > } > > ret = submit_pin_objects(submit); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > ret = submit_reloc(submit, stream, args->stream_size / 4, > relocs, args->nr_relocs); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > ret = submit_perfmon_validate(submit, args->exec_state, pmrs); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > memcpy(submit->cmdbuf.vaddr, stream, args->stream_size); > > ret = submit_lock_objects(submit, &ticket); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > ret = submit_fence_sync(submit); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > - ret = etnaviv_sched_push_job(&ctx->sched_entity[args->pipe], submit); > + ret = etnaviv_sched_push_job(submit); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > submit_attach_object_fences(submit); > > @@ -595,7 +604,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, > sync_file = sync_file_create(submit->out_fence); > if (!sync_file) { > ret = -ENOMEM; > - goto err_submit_objects; > + goto err_submit_job; > } > fd_install(out_fence_fd, sync_file->file); > } > @@ -603,7 +612,9 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, > args->fence_fd = out_fence_fd; > args->fence = submit->out_fence_id; > > -err_submit_objects: > +err_submit_job: > + drm_sched_job_cleanup(&submit->sched_job); > +err_submit_put: > etnaviv_submit_put(submit); > > err_submit_ww_acquire: > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c > index a8452ce10e3a..72e2553fbc98 100644 > --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c > +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c > @@ -17,48 +17,6 @@ module_param_named(job_hang_limit, etnaviv_job_hang_limit, int , 0444); > static int etnaviv_hw_jobs_limit = 4; > module_param_named(hw_job_limit, etnaviv_hw_jobs_limit, int , 0444); > > -static struct dma_fence * > -etnaviv_sched_dependency(struct drm_sched_job *sched_job, > - struct drm_sched_entity *entity) > -{ > - struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job); > - struct dma_fence *fence; > - int i; > - > - if (unlikely(submit->in_fence)) { > - fence = submit->in_fence; > - submit->in_fence = NULL; > - > - if (!dma_fence_is_signaled(fence)) > - return fence; > - > - dma_fence_put(fence); > - } > - > - for (i = 0; i < submit->nr_bos; i++) { > - struct etnaviv_gem_submit_bo *bo = &submit->bos[i]; > - int j; > - > - for (j = 0; j < bo->nr_fences; j++) { > - if (!bo->fences[j]) > - continue; > - > - fence = bo->fences[j]; > - bo->fences[j] = NULL; > - > - if (!dma_fence_is_signaled(fence)) > - return fence; > - > - dma_fence_put(fence); > - } > - kfree(bo->fences); > - bo->nr_fences = 0; > - bo->fences = NULL; > - } > - > - return NULL; > -} > - > static struct dma_fence *etnaviv_sched_run_job(struct drm_sched_job *sched_job) > { > struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job); > @@ -132,29 +90,22 @@ static void etnaviv_sched_free_job(struct drm_sched_job *sched_job) > } > > static const struct drm_sched_backend_ops etnaviv_sched_ops = { > - .dependency = etnaviv_sched_dependency, > .run_job = etnaviv_sched_run_job, > .timedout_job = etnaviv_sched_timedout_job, > .free_job = etnaviv_sched_free_job, > }; > > -int etnaviv_sched_push_job(struct drm_sched_entity *sched_entity, > - struct etnaviv_gem_submit *submit) > +int etnaviv_sched_push_job(struct etnaviv_gem_submit *submit) > { > int ret = 0; > > /* > * Hold the fence lock across the whole operation to avoid jobs being > * pushed out of order with regard to their sched fence seqnos as > - * allocated in drm_sched_job_init. > + * allocated in drm_sched_job_arm. > */ > mutex_lock(&submit->gpu->fence_lock); > > - ret = drm_sched_job_init(&submit->sched_job, sched_entity, > - submit->ctx); > - if (ret) > - goto out_unlock; > - > drm_sched_job_arm(&submit->sched_job); > > submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished); > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.h b/drivers/gpu/drm/etnaviv/etnaviv_sched.h > index c0a6796e22c9..baebfa069afc 100644 > --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.h > +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.h > @@ -18,7 +18,6 @@ struct etnaviv_gem_submit *to_etnaviv_submit(struct drm_sched_job *sched_job) > > int etnaviv_sched_init(struct etnaviv_gpu *gpu); > void etnaviv_sched_fini(struct etnaviv_gpu *gpu); > -int etnaviv_sched_push_job(struct drm_sched_entity *sched_entity, > - struct etnaviv_gem_submit *submit); > +int etnaviv_sched_push_job(struct etnaviv_gem_submit *submit); > > #endif /* __ETNAVIV_SCHED_H__ */
Am Donnerstag, dem 31.03.2022 um 22:46 +0200 schrieb Daniel Vetter: > We need to pull the drm_sched_job_init much earlier, but that's very > minor surgery. > > v2: Actually fix up cleanup paths by calling drm_sched_job_init, which > I wanted to to in the previous round (and did, for all other drivers). > Spotted by Lucas. > > v3: Rebase over renamed functions to add dependencies. > > v4: Rebase over patches from Christian. > > v5: More rebasing over work from Christian. > > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> > Cc: Lucas Stach <l.stach@pengutronix.de> > Cc: Russell King <linux+etnaviv@armlinux.org.uk> > Cc: Christian Gmeiner <christian.gmeiner@gmail.com> > Cc: Sumit Semwal <sumit.semwal@linaro.org> > Cc: "Christian König" <christian.koenig@amd.com> > Cc: etnaviv@lists.freedesktop.org > Cc: linux-media@vger.kernel.org > Cc: linaro-mm-sig@lists.linaro.org Acked-by: Lucas Stach <l.stach@pengutronix.de> > --- > drivers/gpu/drm/etnaviv/etnaviv_gem.h | 4 +- > drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 51 +++++++++++-------- > drivers/gpu/drm/etnaviv/etnaviv_sched.c | 53 +------------------- > drivers/gpu/drm/etnaviv/etnaviv_sched.h | 3 +- > 4 files changed, 35 insertions(+), 76 deletions(-) > > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.h b/drivers/gpu/drm/etnaviv/etnaviv_gem.h > index 8983a0ef383e..63688e6e4580 100644 > --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.h > +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.h > @@ -80,8 +80,6 @@ struct etnaviv_gem_submit_bo { > u64 va; > struct etnaviv_gem_object *obj; > struct etnaviv_vram_mapping *mapping; > - unsigned int nr_fences; > - struct dma_fence **fences; > }; > > /* Created per submit-ioctl, to track bo's and cmdstream bufs, etc, > @@ -94,7 +92,7 @@ struct etnaviv_gem_submit { > struct etnaviv_file_private *ctx; > struct etnaviv_gpu *gpu; > struct etnaviv_iommu_context *mmu_context, *prev_mmu_context; > - struct dma_fence *out_fence, *in_fence; > + struct dma_fence *out_fence; > int out_fence_id; > struct list_head node; /* GPU active submit list */ > struct etnaviv_cmdbuf cmdbuf; > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c > index 592cbb38609a..5f502c49aec2 100644 > --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c > +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c > @@ -188,9 +188,9 @@ static int submit_fence_sync(struct etnaviv_gem_submit *submit) > if (submit->flags & ETNA_SUBMIT_NO_IMPLICIT) > continue; > > - ret = dma_resv_get_fences(robj, > - bo->flags & ETNA_SUBMIT_BO_WRITE, > - &bo->nr_fences, &bo->fences); > + ret = drm_sched_job_add_implicit_dependencies(&submit->sched_job, > + &bo->obj->base, > + bo->flags & ETNA_SUBMIT_BO_WRITE); > if (ret) > return ret; > } > @@ -398,8 +398,6 @@ static void submit_cleanup(struct kref *kref) > > wake_up_all(&submit->gpu->fence_event); > > - if (submit->in_fence) > - dma_fence_put(submit->in_fence); > if (submit->out_fence) { > /* first remove from IDR, so fence can not be found anymore */ > mutex_lock(&submit->gpu->fence_lock); > @@ -530,58 +528,69 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, > ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &submit->cmdbuf, > ALIGN(args->stream_size, 8) + 8); > if (ret) > - goto err_submit_objects; > + goto err_submit_put; > > submit->ctx = file->driver_priv; > submit->mmu_context = etnaviv_iommu_context_get(submit->ctx->mmu); > submit->exec_state = args->exec_state; > submit->flags = args->flags; > > + ret = drm_sched_job_init(&submit->sched_job, > + &ctx->sched_entity[args->pipe], > + submit->ctx); > + if (ret) > + goto err_submit_put; > + > ret = submit_lookup_objects(submit, file, bos, args->nr_bos); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > if ((priv->mmu_global->version != ETNAVIV_IOMMU_V2) && > !etnaviv_cmd_validate_one(gpu, stream, args->stream_size / 4, > relocs, args->nr_relocs)) { > ret = -EINVAL; > - goto err_submit_objects; > + goto err_submit_job; > } > > if (args->flags & ETNA_SUBMIT_FENCE_FD_IN) { > - submit->in_fence = sync_file_get_fence(args->fence_fd); > - if (!submit->in_fence) { > + struct dma_fence *in_fence = sync_file_get_fence(args->fence_fd); > + if (!in_fence) { > ret = -EINVAL; > - goto err_submit_objects; > + goto err_submit_job; > } > + > + ret = drm_sched_job_add_dependency(&submit->sched_job, > + in_fence); > + if (ret) > + goto err_submit_job; > } > > ret = submit_pin_objects(submit); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > ret = submit_reloc(submit, stream, args->stream_size / 4, > relocs, args->nr_relocs); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > ret = submit_perfmon_validate(submit, args->exec_state, pmrs); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > memcpy(submit->cmdbuf.vaddr, stream, args->stream_size); > > ret = submit_lock_objects(submit, &ticket); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > ret = submit_fence_sync(submit); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > - ret = etnaviv_sched_push_job(&ctx->sched_entity[args->pipe], submit); > + ret = etnaviv_sched_push_job(submit); > if (ret) > - goto err_submit_objects; > + goto err_submit_job; > > submit_attach_object_fences(submit); > > @@ -595,7 +604,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, > sync_file = sync_file_create(submit->out_fence); > if (!sync_file) { > ret = -ENOMEM; > - goto err_submit_objects; > + goto err_submit_job; > } > fd_install(out_fence_fd, sync_file->file); > } > @@ -603,7 +612,9 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, > args->fence_fd = out_fence_fd; > args->fence = submit->out_fence_id; > > -err_submit_objects: > +err_submit_job: > + drm_sched_job_cleanup(&submit->sched_job); > +err_submit_put: > etnaviv_submit_put(submit); > > err_submit_ww_acquire: > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c > index a8452ce10e3a..72e2553fbc98 100644 > --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c > +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c > @@ -17,48 +17,6 @@ module_param_named(job_hang_limit, etnaviv_job_hang_limit, int , 0444); > static int etnaviv_hw_jobs_limit = 4; > module_param_named(hw_job_limit, etnaviv_hw_jobs_limit, int , 0444); > > -static struct dma_fence * > -etnaviv_sched_dependency(struct drm_sched_job *sched_job, > - struct drm_sched_entity *entity) > -{ > - struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job); > - struct dma_fence *fence; > - int i; > - > - if (unlikely(submit->in_fence)) { > - fence = submit->in_fence; > - submit->in_fence = NULL; > - > - if (!dma_fence_is_signaled(fence)) > - return fence; > - > - dma_fence_put(fence); > - } > - > - for (i = 0; i < submit->nr_bos; i++) { > - struct etnaviv_gem_submit_bo *bo = &submit->bos[i]; > - int j; > - > - for (j = 0; j < bo->nr_fences; j++) { > - if (!bo->fences[j]) > - continue; > - > - fence = bo->fences[j]; > - bo->fences[j] = NULL; > - > - if (!dma_fence_is_signaled(fence)) > - return fence; > - > - dma_fence_put(fence); > - } > - kfree(bo->fences); > - bo->nr_fences = 0; > - bo->fences = NULL; > - } > - > - return NULL; > -} > - > static struct dma_fence *etnaviv_sched_run_job(struct drm_sched_job *sched_job) > { > struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job); > @@ -132,29 +90,22 @@ static void etnaviv_sched_free_job(struct drm_sched_job *sched_job) > } > > static const struct drm_sched_backend_ops etnaviv_sched_ops = { > - .dependency = etnaviv_sched_dependency, > .run_job = etnaviv_sched_run_job, > .timedout_job = etnaviv_sched_timedout_job, > .free_job = etnaviv_sched_free_job, > }; > > -int etnaviv_sched_push_job(struct drm_sched_entity *sched_entity, > - struct etnaviv_gem_submit *submit) > +int etnaviv_sched_push_job(struct etnaviv_gem_submit *submit) > { > int ret = 0; > > /* > * Hold the fence lock across the whole operation to avoid jobs being > * pushed out of order with regard to their sched fence seqnos as > - * allocated in drm_sched_job_init. > + * allocated in drm_sched_job_arm. > */ > mutex_lock(&submit->gpu->fence_lock); > > - ret = drm_sched_job_init(&submit->sched_job, sched_entity, > - submit->ctx); > - if (ret) > - goto out_unlock; > - > drm_sched_job_arm(&submit->sched_job); > > submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished); > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.h b/drivers/gpu/drm/etnaviv/etnaviv_sched.h > index c0a6796e22c9..baebfa069afc 100644 > --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.h > +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.h > @@ -18,7 +18,6 @@ struct etnaviv_gem_submit *to_etnaviv_submit(struct drm_sched_job *sched_job) > > int etnaviv_sched_init(struct etnaviv_gpu *gpu); > void etnaviv_sched_fini(struct etnaviv_gpu *gpu); > -int etnaviv_sched_push_job(struct drm_sched_entity *sched_entity, > - struct etnaviv_gem_submit *submit); > +int etnaviv_sched_push_job(struct etnaviv_gem_submit *submit); > > #endif /* __ETNAVIV_SCHED_H__ */
> We need to pull the drm_sched_job_init much earlier, but that's very > minor surgery. This patch breaks the GC7000 on the LS1028A: [ 35.671102] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000078 [ 35.680925] Mem abort info: [ 35.685127] ESR = 0x96000004 [ 35.689583] EC = 0x25: DABT (current EL), IL = 32 bits [ 35.696312] SET = 0, FnV = 0 [ 35.700766] EA = 0, S1PTW = 0 [ 35.705315] FSC = 0x04: level 0 translation fault [ 35.711616] Data abort info: [ 35.715916] ISV = 0, ISS = 0x00000004 [ 35.721170] CM = 0, WnR = 0 [ 35.725552] user pgtable: 4k pages, 48-bit VAs, pgdp=0000002083f59000 [ 35.733420] [0000000000000078] pgd=0000000000000000, p4d=0000000000000000 [ 35.741627] Internal error: Oops: 96000004 [#1] SMP [ 35.747902] Modules linked in: [ 35.750963] CPU: 0 PID: 44 Comm: f0c0000.gpu Not tainted 5.18.0-rc2-00894-gde6a1d7294f5 #24 [ 35.759345] Hardware name: Kontron KBox A-230-LS (DT) [ 35.764409] pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 35.771394] pc : drm_sched_entity_select_rq+0x314/0x380 [ 35.776645] lr : drm_sched_entity_pop_job+0x4c/0x480 [ 35.781625] sp : ffff80000949bdb0 [ 35.784943] x29: ffff80000949bdb0 x28: 0000000000000000 x27: 0000000000000000 [ 35.792107] x26: ffff002003f09008 x25: ffff00200231d130 x24: ffff800008c13008 [ 35.799270] x23: ffff8000086af900 x22: ffff800008c13008 x21: ffff002003fb6e00 [ 35.806432] x20: 0000000000000040 x19: ffff002003f09008 x18: ffffffffffffffff [ 35.813594] x17: 0000000000000000 x16: 0000000000000000 x15: ffff800009ee3d48 [ 35.820756] x14: 0000000000000000 x13: 0000000000000000 x12: ffffffff00000008 [ 35.827918] x11: 0000aaaadb063d30 x10: 0000000000000960 x9 : ffff8000086afedc [ 35.835080] x8 : ffff00200186a900 x7 : 0000000000000000 x6 : 0000000000000000 [ 35.842242] x5 : ffff00200231d2b0 x4 : 0000000000000000 x3 : 0000000000000000 [ 35.849403] x2 : 0000000000000000 x1 : 0000000000000078 x0 : 0000000000000078 [ 35.856565] Call trace: [ 35.859013] drm_sched_entity_select_rq+0x314/0x380 [ 35.863906] drm_sched_main+0x1b0/0x49c [ 35.867752] kthread+0xe4/0xf0 [ 35.870814] ret_from_fork+0x10/0x20 [ 35.874401] Code: 8805fc24 35ffffa5 17fffef9 f9800031 (885f7c22) [ 35.880513] ---[ end trace 0000000000000000 ]--- # glmark2-es2-drm ======================================================= glmark2 2021.02 ======================================================= OpenGL Information GL_VENDOR: etnaviv GL_RENDERER: Vivante GC7000 rev 6202 GL_VERSION: OpenGL ES 2.0 Mesa 22.1.0-devel Mesa is Lucas latest MR branch: lynxeye/etnaviv-gc7000-r6204. Reverting this patch on drm-next will make the oops go away. Any idea what's going wrong here? -michael
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.h b/drivers/gpu/drm/etnaviv/etnaviv_gem.h index 8983a0ef383e..63688e6e4580 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.h @@ -80,8 +80,6 @@ struct etnaviv_gem_submit_bo { u64 va; struct etnaviv_gem_object *obj; struct etnaviv_vram_mapping *mapping; - unsigned int nr_fences; - struct dma_fence **fences; }; /* Created per submit-ioctl, to track bo's and cmdstream bufs, etc, @@ -94,7 +92,7 @@ struct etnaviv_gem_submit { struct etnaviv_file_private *ctx; struct etnaviv_gpu *gpu; struct etnaviv_iommu_context *mmu_context, *prev_mmu_context; - struct dma_fence *out_fence, *in_fence; + struct dma_fence *out_fence; int out_fence_id; struct list_head node; /* GPU active submit list */ struct etnaviv_cmdbuf cmdbuf; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c index 592cbb38609a..5f502c49aec2 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c @@ -188,9 +188,9 @@ static int submit_fence_sync(struct etnaviv_gem_submit *submit) if (submit->flags & ETNA_SUBMIT_NO_IMPLICIT) continue; - ret = dma_resv_get_fences(robj, - bo->flags & ETNA_SUBMIT_BO_WRITE, - &bo->nr_fences, &bo->fences); + ret = drm_sched_job_add_implicit_dependencies(&submit->sched_job, + &bo->obj->base, + bo->flags & ETNA_SUBMIT_BO_WRITE); if (ret) return ret; } @@ -398,8 +398,6 @@ static void submit_cleanup(struct kref *kref) wake_up_all(&submit->gpu->fence_event); - if (submit->in_fence) - dma_fence_put(submit->in_fence); if (submit->out_fence) { /* first remove from IDR, so fence can not be found anymore */ mutex_lock(&submit->gpu->fence_lock); @@ -530,58 +528,69 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &submit->cmdbuf, ALIGN(args->stream_size, 8) + 8); if (ret) - goto err_submit_objects; + goto err_submit_put; submit->ctx = file->driver_priv; submit->mmu_context = etnaviv_iommu_context_get(submit->ctx->mmu); submit->exec_state = args->exec_state; submit->flags = args->flags; + ret = drm_sched_job_init(&submit->sched_job, + &ctx->sched_entity[args->pipe], + submit->ctx); + if (ret) + goto err_submit_put; + ret = submit_lookup_objects(submit, file, bos, args->nr_bos); if (ret) - goto err_submit_objects; + goto err_submit_job; if ((priv->mmu_global->version != ETNAVIV_IOMMU_V2) && !etnaviv_cmd_validate_one(gpu, stream, args->stream_size / 4, relocs, args->nr_relocs)) { ret = -EINVAL; - goto err_submit_objects; + goto err_submit_job; } if (args->flags & ETNA_SUBMIT_FENCE_FD_IN) { - submit->in_fence = sync_file_get_fence(args->fence_fd); - if (!submit->in_fence) { + struct dma_fence *in_fence = sync_file_get_fence(args->fence_fd); + if (!in_fence) { ret = -EINVAL; - goto err_submit_objects; + goto err_submit_job; } + + ret = drm_sched_job_add_dependency(&submit->sched_job, + in_fence); + if (ret) + goto err_submit_job; } ret = submit_pin_objects(submit); if (ret) - goto err_submit_objects; + goto err_submit_job; ret = submit_reloc(submit, stream, args->stream_size / 4, relocs, args->nr_relocs); if (ret) - goto err_submit_objects; + goto err_submit_job; ret = submit_perfmon_validate(submit, args->exec_state, pmrs); if (ret) - goto err_submit_objects; + goto err_submit_job; memcpy(submit->cmdbuf.vaddr, stream, args->stream_size); ret = submit_lock_objects(submit, &ticket); if (ret) - goto err_submit_objects; + goto err_submit_job; ret = submit_fence_sync(submit); if (ret) - goto err_submit_objects; + goto err_submit_job; - ret = etnaviv_sched_push_job(&ctx->sched_entity[args->pipe], submit); + ret = etnaviv_sched_push_job(submit); if (ret) - goto err_submit_objects; + goto err_submit_job; submit_attach_object_fences(submit); @@ -595,7 +604,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, sync_file = sync_file_create(submit->out_fence); if (!sync_file) { ret = -ENOMEM; - goto err_submit_objects; + goto err_submit_job; } fd_install(out_fence_fd, sync_file->file); } @@ -603,7 +612,9 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, args->fence_fd = out_fence_fd; args->fence = submit->out_fence_id; -err_submit_objects: +err_submit_job: + drm_sched_job_cleanup(&submit->sched_job); +err_submit_put: etnaviv_submit_put(submit); err_submit_ww_acquire: diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c index a8452ce10e3a..72e2553fbc98 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c @@ -17,48 +17,6 @@ module_param_named(job_hang_limit, etnaviv_job_hang_limit, int , 0444); static int etnaviv_hw_jobs_limit = 4; module_param_named(hw_job_limit, etnaviv_hw_jobs_limit, int , 0444); -static struct dma_fence * -etnaviv_sched_dependency(struct drm_sched_job *sched_job, - struct drm_sched_entity *entity) -{ - struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job); - struct dma_fence *fence; - int i; - - if (unlikely(submit->in_fence)) { - fence = submit->in_fence; - submit->in_fence = NULL; - - if (!dma_fence_is_signaled(fence)) - return fence; - - dma_fence_put(fence); - } - - for (i = 0; i < submit->nr_bos; i++) { - struct etnaviv_gem_submit_bo *bo = &submit->bos[i]; - int j; - - for (j = 0; j < bo->nr_fences; j++) { - if (!bo->fences[j]) - continue; - - fence = bo->fences[j]; - bo->fences[j] = NULL; - - if (!dma_fence_is_signaled(fence)) - return fence; - - dma_fence_put(fence); - } - kfree(bo->fences); - bo->nr_fences = 0; - bo->fences = NULL; - } - - return NULL; -} - static struct dma_fence *etnaviv_sched_run_job(struct drm_sched_job *sched_job) { struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job); @@ -132,29 +90,22 @@ static void etnaviv_sched_free_job(struct drm_sched_job *sched_job) } static const struct drm_sched_backend_ops etnaviv_sched_ops = { - .dependency = etnaviv_sched_dependency, .run_job = etnaviv_sched_run_job, .timedout_job = etnaviv_sched_timedout_job, .free_job = etnaviv_sched_free_job, }; -int etnaviv_sched_push_job(struct drm_sched_entity *sched_entity, - struct etnaviv_gem_submit *submit) +int etnaviv_sched_push_job(struct etnaviv_gem_submit *submit) { int ret = 0; /* * Hold the fence lock across the whole operation to avoid jobs being * pushed out of order with regard to their sched fence seqnos as - * allocated in drm_sched_job_init. + * allocated in drm_sched_job_arm. */ mutex_lock(&submit->gpu->fence_lock); - ret = drm_sched_job_init(&submit->sched_job, sched_entity, - submit->ctx); - if (ret) - goto out_unlock; - drm_sched_job_arm(&submit->sched_job); submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.h b/drivers/gpu/drm/etnaviv/etnaviv_sched.h index c0a6796e22c9..baebfa069afc 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.h @@ -18,7 +18,6 @@ struct etnaviv_gem_submit *to_etnaviv_submit(struct drm_sched_job *sched_job) int etnaviv_sched_init(struct etnaviv_gpu *gpu); void etnaviv_sched_fini(struct etnaviv_gpu *gpu); -int etnaviv_sched_push_job(struct drm_sched_entity *sched_entity, - struct etnaviv_gem_submit *submit); +int etnaviv_sched_push_job(struct etnaviv_gem_submit *submit); #endif /* __ETNAVIV_SCHED_H__ */
We need to pull the drm_sched_job_init much earlier, but that's very minor surgery. v2: Actually fix up cleanup paths by calling drm_sched_job_init, which I wanted to to in the previous round (and did, for all other drivers). Spotted by Lucas. v3: Rebase over renamed functions to add dependencies. v4: Rebase over patches from Christian. v5: More rebasing over work from Christian. Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Cc: Lucas Stach <l.stach@pengutronix.de> Cc: Russell King <linux+etnaviv@armlinux.org.uk> Cc: Christian Gmeiner <christian.gmeiner@gmail.com> Cc: Sumit Semwal <sumit.semwal@linaro.org> Cc: "Christian König" <christian.koenig@amd.com> Cc: etnaviv@lists.freedesktop.org Cc: linux-media@vger.kernel.org Cc: linaro-mm-sig@lists.linaro.org --- drivers/gpu/drm/etnaviv/etnaviv_gem.h | 4 +- drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 51 +++++++++++-------- drivers/gpu/drm/etnaviv/etnaviv_sched.c | 53 +------------------- drivers/gpu/drm/etnaviv/etnaviv_sched.h | 3 +- 4 files changed, 35 insertions(+), 76 deletions(-)