Commit a783a09e authored by Eric Anholt's avatar Eric Anholt

drm/v3d: Refactor job management.

The CL submission had two jobs embedded in an exec struct.  When I
added TFU support, I had to replicate some of the exec stuff and some
of the job stuff.  As I went to add CSD, it became clear that actually
what was in exec should just be in the two CL jobs, and it would let
us share a lot more code between the 4 queues.

v2: Fix missing error path in TFU ioctl's bo[] allocation.
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20190416225856.20264-3-eric@anholt.netAcked-by: default avatarRob Clark <robdclark@gmail.com>
parent d4c3022a
...@@ -67,8 +67,8 @@ struct v3d_dev { ...@@ -67,8 +67,8 @@ struct v3d_dev {
struct work_struct overflow_mem_work; struct work_struct overflow_mem_work;
struct v3d_exec_info *bin_job; struct v3d_bin_job *bin_job;
struct v3d_exec_info *render_job; struct v3d_render_job *render_job;
struct v3d_tfu_job *tfu_job; struct v3d_tfu_job *tfu_job;
struct v3d_queue_state queue[V3D_MAX_QUEUES]; struct v3d_queue_state queue[V3D_MAX_QUEUES];
...@@ -117,7 +117,7 @@ struct v3d_bo { ...@@ -117,7 +117,7 @@ struct v3d_bo {
struct drm_mm_node node; struct drm_mm_node node;
/* List entry for the BO's position in /* List entry for the BO's position in
* v3d_exec_info->unref_list * v3d_render_job->unref_list
*/ */
struct list_head unref_head; struct list_head unref_head;
}; };
...@@ -157,7 +157,15 @@ to_v3d_fence(struct dma_fence *fence) ...@@ -157,7 +157,15 @@ to_v3d_fence(struct dma_fence *fence)
struct v3d_job { struct v3d_job {
struct drm_sched_job base; struct drm_sched_job base;
struct v3d_exec_info *exec; struct kref refcount;
struct v3d_dev *v3d;
/* This is the array of BOs that were looked up at the start
* of submission.
*/
struct drm_gem_object **bo;
u32 bo_count;
/* An optional fence userspace can pass in for the job to depend on. */ /* An optional fence userspace can pass in for the job to depend on. */
struct dma_fence *in_fence; struct dma_fence *in_fence;
...@@ -165,59 +173,53 @@ struct v3d_job { ...@@ -165,59 +173,53 @@ struct v3d_job {
/* v3d fence to be signaled by IRQ handler when the job is complete. */ /* v3d fence to be signaled by IRQ handler when the job is complete. */
struct dma_fence *irq_fence; struct dma_fence *irq_fence;
/* scheduler fence for when the job is considered complete and
* the BO reservations can be released.
*/
struct dma_fence *done_fence;
/* Callback for the freeing of the job on refcount going to 0. */
void (*free)(struct kref *ref);
};
struct v3d_bin_job {
struct v3d_job base;
/* GPU virtual addresses of the start/end of the CL job. */ /* GPU virtual addresses of the start/end of the CL job. */
u32 start, end; u32 start, end;
u32 timedout_ctca, timedout_ctra; u32 timedout_ctca, timedout_ctra;
};
struct v3d_exec_info { /* Corresponding render job, for attaching our overflow memory. */
struct v3d_dev *v3d; struct v3d_render_job *render;
/* Submitted tile memory allocation start/size, tile state. */
u32 qma, qms, qts;
};
struct v3d_job bin, render; struct v3d_render_job {
struct v3d_job base;
/* Fence for when the scheduler considers the binner to be /* Optional fence for the binner, to depend on before starting
* done, for render to depend on. * our job.
*/ */
struct dma_fence *bin_done_fence; struct dma_fence *bin_done_fence;
/* Fence for when the scheduler considers the render to be /* GPU virtual addresses of the start/end of the CL job. */
* done, for when the BOs reservations should be complete. u32 start, end;
*/
struct dma_fence *render_done_fence;
struct kref refcount;
/* This is the array of BOs that were looked up at the start of exec. */ u32 timedout_ctca, timedout_ctra;
struct drm_gem_object **bo;
u32 bo_count;
/* List of overflow BOs used in the job that need to be /* List of overflow BOs used in the job that need to be
* released once the job is complete. * released once the job is complete.
*/ */
struct list_head unref_list; struct list_head unref_list;
/* Submitted tile memory allocation start/size, tile state. */
u32 qma, qms, qts;
}; };
struct v3d_tfu_job { struct v3d_tfu_job {
struct drm_sched_job base; struct v3d_job base;
struct drm_v3d_submit_tfu args; struct drm_v3d_submit_tfu args;
/* An optional fence userspace can pass in for the job to depend on. */
struct dma_fence *in_fence;
/* v3d fence to be signaled by IRQ handler when the job is complete. */
struct dma_fence *irq_fence;
struct v3d_dev *v3d;
struct kref refcount;
/* This is the array of BOs that were looked up at the start of exec. */
struct drm_gem_object *bo[4];
}; };
/** /**
...@@ -283,8 +285,7 @@ int v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, ...@@ -283,8 +285,7 @@ int v3d_submit_tfu_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
int v3d_wait_bo_ioctl(struct drm_device *dev, void *data, int v3d_wait_bo_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
void v3d_exec_put(struct v3d_exec_info *exec); void v3d_job_put(struct v3d_job *job);
void v3d_tfu_job_put(struct v3d_tfu_job *exec);
void v3d_reset(struct v3d_dev *v3d); void v3d_reset(struct v3d_dev *v3d);
void v3d_invalidate_caches(struct v3d_dev *v3d); void v3d_invalidate_caches(struct v3d_dev *v3d);
......
This diff is collapsed.
...@@ -62,7 +62,7 @@ v3d_overflow_mem_work(struct work_struct *work) ...@@ -62,7 +62,7 @@ v3d_overflow_mem_work(struct work_struct *work)
} }
drm_gem_object_get(obj); drm_gem_object_get(obj);
list_add_tail(&bo->unref_head, &v3d->bin_job->unref_list); list_add_tail(&bo->unref_head, &v3d->bin_job->render->unref_list);
spin_unlock_irqrestore(&v3d->job_lock, irqflags); spin_unlock_irqrestore(&v3d->job_lock, irqflags);
V3D_CORE_WRITE(0, V3D_PTB_BPOA, bo->node.start << PAGE_SHIFT); V3D_CORE_WRITE(0, V3D_PTB_BPOA, bo->node.start << PAGE_SHIFT);
...@@ -96,7 +96,7 @@ v3d_irq(int irq, void *arg) ...@@ -96,7 +96,7 @@ v3d_irq(int irq, void *arg)
if (intsts & V3D_INT_FLDONE) { if (intsts & V3D_INT_FLDONE) {
struct v3d_fence *fence = struct v3d_fence *fence =
to_v3d_fence(v3d->bin_job->bin.irq_fence); to_v3d_fence(v3d->bin_job->base.irq_fence);
trace_v3d_bcl_irq(&v3d->drm, fence->seqno); trace_v3d_bcl_irq(&v3d->drm, fence->seqno);
dma_fence_signal(&fence->base); dma_fence_signal(&fence->base);
...@@ -105,7 +105,7 @@ v3d_irq(int irq, void *arg) ...@@ -105,7 +105,7 @@ v3d_irq(int irq, void *arg)
if (intsts & V3D_INT_FRDONE) { if (intsts & V3D_INT_FRDONE) {
struct v3d_fence *fence = struct v3d_fence *fence =
to_v3d_fence(v3d->render_job->render.irq_fence); to_v3d_fence(v3d->render_job->base.irq_fence);
trace_v3d_rcl_irq(&v3d->drm, fence->seqno); trace_v3d_rcl_irq(&v3d->drm, fence->seqno);
dma_fence_signal(&fence->base); dma_fence_signal(&fence->base);
...@@ -141,7 +141,7 @@ v3d_hub_irq(int irq, void *arg) ...@@ -141,7 +141,7 @@ v3d_hub_irq(int irq, void *arg)
if (intsts & V3D_HUB_INT_TFUC) { if (intsts & V3D_HUB_INT_TFUC) {
struct v3d_fence *fence = struct v3d_fence *fence =
to_v3d_fence(v3d->tfu_job->irq_fence); to_v3d_fence(v3d->tfu_job->base.irq_fence);
trace_v3d_tfu_irq(&v3d->drm, fence->seqno); trace_v3d_tfu_irq(&v3d->drm, fence->seqno);
dma_fence_signal(&fence->base); dma_fence_signal(&fence->base);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment