@@ -165,6 +165,7 @@ panfrost_lookup_bos(struct drm_device *dev,
struct drm_panfrost_submit *args,
struct panfrost_job *job)
{
+ unsigned int i;
int ret;
job->bo_count = args->bo_handle_count;
@@ -172,6 +173,15 @@ panfrost_lookup_bos(struct drm_device *dev,
if (!job->bo_count)
return 0;
+ job->bo_flags = kvmalloc_array(job->bo_count,
+ sizeof(*job->bo_flags),
+ GFP_KERNEL | __GFP_ZERO);
+ if (!job->bo_flags)
+ return -ENOMEM;
+
+ for (i = 0; i < job->bo_count; i++)
+ job->bo_flags[i] = PANFROST_BO_REF_EXCLUSIVE;
+
ret = drm_gem_objects_lookup(file_priv,
(void __user *)(uintptr_t)args->bo_handles,
job->bo_count, &job->bos);
@@ -245,9 +245,17 @@ static int panfrost_acquire_object_fences(struct panfrost_job *job)
int i, ret;
for (i = 0; i < job->bo_count; i++) {
+ bool exclusive = job->bo_flags[i] & PANFROST_BO_REF_EXCLUSIVE;
+
+ if (!exclusive) {
+ ret = dma_resv_reserve_shared(job->bos[i]->resv, 1);
+ if (ret)
+ return ret;
+ }
+
/* panfrost always uses write mode in its current uapi */
ret = drm_sched_job_add_implicit_dependencies(&job->base, job->bos[i],
- true);
+ exclusive);
if (ret)
return ret;
}
@@ -259,8 +267,14 @@ static void panfrost_attach_object_fences(struct panfrost_job *job)
{
int i;
- for (i = 0; i < job->bo_count; i++)
- dma_resv_add_excl_fence(job->bos[i]->resv, job->render_done_fence);
+ for (i = 0; i < job->bo_count; i++) {
+ struct dma_resv *robj = job->bos[i]->resv;
+
+ if (job->bo_flags[i] & PANFROST_BO_REF_EXCLUSIVE)
+ dma_resv_add_excl_fence(robj, job->render_done_fence);
+ else
+ dma_resv_add_shared_fence(robj, job->render_done_fence);
+ }
}
int panfrost_job_push(struct panfrost_job *job)
@@ -326,6 +340,7 @@ static void panfrost_job_cleanup(struct kref *ref)
kvfree(job->bos);
}
+ kvfree(job->bo_flags);
kfree(job);
}
@@ -28,6 +28,7 @@ struct panfrost_job {
struct panfrost_gem_mapping **mappings;
struct drm_gem_object **bos;
+ u32 *bo_flags;
u32 bo_count;
/* Fence to be signaled by drm-sched once its done with the job */
@@ -226,6 +226,9 @@ struct drm_panfrost_madvise {
__u32 retained; /* out, whether backing store still exists */
};
+/* Exclusive (AKA write) access to the BO */
+#define PANFROST_BO_REF_EXCLUSIVE 0x1
+
#if defined(__cplusplus)
}
#endif