drm/nouveau: enable dynamic job-flow control
authorDanilo Krummrich <dakr@redhat.com>
Tue, 14 Nov 2023 00:27:25 +0000 (01:27 +0100)
committerDanilo Krummrich <dakr@redhat.com>
Fri, 24 Nov 2023 20:24:51 +0000 (21:24 +0100)
Make use of the scheduler's credit limit and scheduler job's credit
count to account for the actual size of a job, such that we fill up the
ring efficiently.

Signed-off-by: Danilo Krummrich <dakr@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231114002728.3491-2-dakr@redhat.com
drivers/gpu/drm/nouveau/nouveau_abi16.c
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/nouveau/nouveau_exec.c
drivers/gpu/drm/nouveau/nouveau_sched.c
drivers/gpu/drm/nouveau/nouveau_sched.h
drivers/gpu/drm/nouveau/nouveau_uvmm.c

index 7542e17..a04156c 100644 (file)
@@ -337,7 +337,8 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
        if (ret)
                goto done;
 
-       ret = nouveau_sched_init(&chan->sched, drm, drm->sched_wq);
+       ret = nouveau_sched_init(&chan->sched, drm, drm->sched_wq,
+                                chan->chan->dma.ib_max);
        if (ret)
                goto done;
 
index 7e5f191..6f6c31a 100644 (file)
@@ -320,7 +320,7 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname,
         * locks which indirectly or directly are held for allocations
         * elsewhere.
         */
-       ret = nouveau_sched_init(&cli->sched, drm, NULL);
+       ret = nouveau_sched_init(&cli->sched, drm, NULL, 1);
        if (ret)
                goto done;
 
index a179eeb..bc5d71b 100644 (file)
@@ -231,10 +231,12 @@ nouveau_exec_job_init(struct nouveau_exec_job **pjob,
                }
        }
 
+       args.file_priv = __args->file_priv;
        job->chan = __args->chan;
 
        args.sched = __args->sched;
-       args.file_priv = __args->file_priv;
+       /* Plus one to account for the HW fence. */
+       args.credits = job->push.count + 1;
 
        args.in_sync.count = __args->in_sync.count;
        args.in_sync.s = __args->in_sync.s;
index 0f4583f..3393647 100644 (file)
@@ -12,7 +12,6 @@
 #include "nouveau_abi16.h"
 #include "nouveau_sched.h"
 
-#define NOUVEAU_SCHED_HW_SUBMISSIONS           1
 #define NOUVEAU_SCHED_JOB_TIMEOUT_MS           10000
 
 /* Starts at 0, since the DRM scheduler interprets those parameters as (initial)
@@ -85,10 +84,10 @@ nouveau_job_init(struct nouveau_job *job,
                        ret = -ENOMEM;
                        goto err_free_objs;
                }
-
        }
 
-       ret = drm_sched_job_init(&job->base, &sched->entity, 1, NULL);
+       ret = drm_sched_job_init(&job->base, &sched->entity,
+                                args->credits, NULL);
        if (ret)
                goto err_free_chains;
 
@@ -401,7 +400,7 @@ static const struct drm_sched_backend_ops nouveau_sched_ops = {
 
 int
 nouveau_sched_init(struct nouveau_sched *sched, struct nouveau_drm *drm,
-                  struct workqueue_struct *wq)
+                  struct workqueue_struct *wq, u32 credit_limit)
 {
        struct drm_gpu_scheduler *drm_sched = &sched->base;
        struct drm_sched_entity *entity = &sched->entity;
@@ -419,7 +418,7 @@ nouveau_sched_init(struct nouveau_sched *sched, struct nouveau_drm *drm,
 
        ret = drm_sched_init(drm_sched, &nouveau_sched_ops, wq,
                             NOUVEAU_SCHED_PRIORITY_COUNT,
-                            NOUVEAU_SCHED_HW_SUBMISSIONS, 0, job_hang_limit,
+                            credit_limit, 0, job_hang_limit,
                             NULL, NULL, "nouveau_sched", drm->dev->dev);
        if (ret)
                goto fail_wq;
index 23eff4b..a6528f5 100644 (file)
@@ -27,6 +27,7 @@ enum nouveau_job_state {
 struct nouveau_job_args {
        struct drm_file *file_priv;
        struct nouveau_sched *sched;
+       u32 credits;
 
        enum dma_resv_usage resv_usage;
        bool sync;
@@ -111,7 +112,7 @@ struct nouveau_sched {
 };
 
 int nouveau_sched_init(struct nouveau_sched *sched, struct nouveau_drm *drm,
-                      struct workqueue_struct *wq);
+                      struct workqueue_struct *wq, u32 credit_limit);
 void nouveau_sched_fini(struct nouveau_sched *sched);
 
 #endif
index 46493fc..4b236da 100644 (file)
@@ -1607,9 +1607,11 @@ nouveau_uvmm_bind_job_init(struct nouveau_uvmm_bind_job **pjob,
 
        init_completion(&job->complete);
 
-       args.sched = __args->sched;
        args.file_priv = __args->file_priv;
 
+       args.sched = __args->sched;
+       args.credits = 1;
+
        args.in_sync.count = __args->in_sync.count;
        args.in_sync.s = __args->in_sync.s;