Skip to content

Commit db69008

Browse files
itoralpopcornmix
authored andcommitted
drm/v3d: clean caches at the end of render jobs on request from user space
Extends the user space ioctl for CL submissions so it can include a request to flush the cache once the CL execution has completed. Fixes memory write violation messages reported by the kernel in workloads involving shader memory writes (SSBOs, shader images, scratch, etc) which sometimes also lead to GPU resets during Piglit and CTS workloads. v2: if v3d_job_init() fails we need to kfree() the job instead of v3d_job_put() it (Eric Anholt). v3 (Eric Anholt): - Drop _FLAG suffix from the new flag name. - Add a new param so userspace can tell whether cache flushing is implemented in the kernel. Signed-off-by: Iago Toral Quiroga <[email protected]>
1 parent 4d486c1 commit db69008

File tree

3 files changed

+53
-10
lines changed

3 files changed

+53
-10
lines changed

drivers/gpu/drm/v3d/v3d_drv.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ static int v3d_get_param_ioctl(struct drm_device *dev, void *data,
117117
case DRM_V3D_PARAM_SUPPORTS_CSD:
118118
args->value = v3d_has_csd(v3d);
119119
return 0;
120+
case DRM_V3D_PARAM_SUPPORTS_CACHE_FLUSH:
121+
args->value = 1;
122+
return 0;
120123
default:
121124
DRM_DEBUG("Unknown parameter %d\n", args->param);
122125
return -EINVAL;

drivers/gpu/drm/v3d/v3d_gem.c

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -709,13 +709,16 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
709709
struct drm_v3d_submit_cl *args = data;
710710
struct v3d_bin_job *bin = NULL;
711711
struct v3d_render_job *render;
712+
struct v3d_job *clean_job = NULL;
713+
struct v3d_job *last_job;
712714
struct ww_acquire_ctx acquire_ctx;
713715
int ret = 0;
714716

715717
trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end);
716718

717-
if (args->pad != 0) {
718-
DRM_INFO("pad must be zero: %d\n", args->pad);
719+
if (args->flags != 0 &&
720+
args->flags != DRM_V3D_SUBMIT_CL_FLUSH_CACHE) {
721+
DRM_INFO("invalid flags: %d\n", args->flags);
719722
return -EINVAL;
720723
}
721724

@@ -755,12 +758,31 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
755758
bin->render = render;
756759
}
757760

758-
ret = v3d_lookup_bos(dev, file_priv, &render->base,
761+
if (args->flags & DRM_V3D_SUBMIT_CL_FLUSH_CACHE) {
762+
clean_job = kcalloc(1, sizeof(*clean_job), GFP_KERNEL);
763+
if (!clean_job) {
764+
ret = -ENOMEM;
765+
goto fail;
766+
}
767+
768+
ret = v3d_job_init(v3d, file_priv, clean_job, v3d_job_free, 0);
769+
if (ret) {
770+
kfree(clean_job);
771+
clean_job = NULL;
772+
goto fail;
773+
}
774+
775+
last_job = clean_job;
776+
} else {
777+
last_job = &render->base;
778+
}
779+
780+
ret = v3d_lookup_bos(dev, file_priv, last_job,
759781
args->bo_handles, args->bo_handle_count);
760782
if (ret)
761783
goto fail;
762784

763-
ret = v3d_lock_bo_reservations(&render->base, &acquire_ctx);
785+
ret = v3d_lock_bo_reservations(last_job, &acquire_ctx);
764786
if (ret)
765787
goto fail;
766788

@@ -772,33 +794,49 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
772794

773795
ret = v3d_add_dep(&render->base,
774796
dma_fence_get(bin->base.done_fence));
797+
if (ret)
798+
goto fail_unreserve;
775799
}
776800

777801
ret = v3d_push_job(v3d_priv, &render->base, V3D_RENDER);
778802
if (ret)
779803
goto fail_unreserve;
804+
805+
if (clean_job) {
806+
ret = v3d_add_dep(clean_job,
807+
dma_fence_get(render->base.done_fence));
808+
if (ret)
809+
goto fail_unreserve;
810+
ret = v3d_push_job(v3d_priv, clean_job, V3D_CACHE_CLEAN);
811+
if (ret)
812+
goto fail_unreserve;
813+
}
780814
mutex_unlock(&v3d->sched_lock);
781815

782816
v3d_attach_fences_and_unlock_reservation(file_priv,
783-
&render->base,
817+
last_job,
784818
&acquire_ctx,
785819
args->out_sync,
786-
render->base.done_fence);
820+
last_job->done_fence);
787821

788822
if (bin)
789823
v3d_job_put(&bin->base);
790824
v3d_job_put(&render->base);
825+
if (clean_job)
826+
v3d_job_put(clean_job);
791827

792828
return 0;
793829

794830
fail_unreserve:
795831
mutex_unlock(&v3d->sched_lock);
796-
v3d_unlock_bo_reservations(render->base.bo,
797-
render->base.bo_count, &acquire_ctx);
832+
v3d_unlock_bo_reservations(last_job->bo,
833+
last_job->bo_count, &acquire_ctx);
798834
fail:
799835
if (bin)
800836
v3d_job_put(&bin->base);
801837
v3d_job_put(&render->base);
838+
if (clean_job)
839+
v3d_job_put(clean_job);
802840

803841
return ret;
804842
}

include/uapi/drm/v3d_drm.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ extern "C" {
4848
#define DRM_IOCTL_V3D_SUBMIT_TFU DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_TFU, struct drm_v3d_submit_tfu)
4949
#define DRM_IOCTL_V3D_SUBMIT_CSD DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CSD, struct drm_v3d_submit_csd)
5050

51+
#define DRM_V3D_SUBMIT_CL_FLUSH_CACHE 0x01
52+
5153
/**
5254
* struct drm_v3d_submit_cl - ioctl argument for submitting commands to the 3D
5355
* engine.
@@ -106,8 +108,7 @@ struct drm_v3d_submit_cl {
106108
/* Number of BO handles passed in (size is that times 4). */
107109
__u32 bo_handle_count;
108110

109-
/* Pad, must be zero-filled. */
110-
__u32 pad;
111+
__u32 flags;
111112
};
112113

113114
/**
@@ -175,6 +176,7 @@ enum drm_v3d_param {
175176
DRM_V3D_PARAM_V3D_CORE0_IDENT2,
176177
DRM_V3D_PARAM_SUPPORTS_TFU,
177178
DRM_V3D_PARAM_SUPPORTS_CSD,
179+
DRM_V3D_PARAM_SUPPORTS_CACHE_FLUSH,
178180
};
179181

180182
struct drm_v3d_get_param {

0 commit comments

Comments
 (0)