History

drm/v3d: add generic ioctl extension

Add support to attach generic extensions on job submission. This patch is third prep work to enable multiple syncobjs on job submission. With this work, when the job submission interface needs to be extended to accommodate a new feature, we will use a generic extension struct where an id determines the data type to be pointed. The first application is to enable multiples in/out syncobj (next patch), but the base is already done for future features. Therefore, to attach a new feature, a specific extension struct should subclass drm_v3d_extension and update the list of extensions in a job submission. v2: - remove redundant elements to subclass struct (Daniel) v3: - add comment for v3d_get_extensions

Melissa Wen committed 5 years ago

Commit bb3425e1 parent 07c2a413 files · +103 −6Browse files

Unified · Split

3 files
  1. drivers/gpu/drm/v3d/v3d_drv.c +1 −3
  2. drivers/gpu/drm/v3d/v3d_gem.c +71 −3
  3. include/uapi/drm/v3d_drm.h +31 −0
drivers/gpu/drm/v3d/v3d_drv.c+1−3
@@ -83,7 +83,6 @@ static int v3d_get_param_ioctl(struct drm_device *dev, void *data, · 82 unmodified lines
83 return 0;83 return 0;
84 }84 }
85 85
86
87 switch (args->param) {86 switch (args->param) {
88 case DRM_V3D_PARAM_SUPPORTS_TFU:87 case DRM_V3D_PARAM_SUPPORTS_TFU:
89 args->value = 1;88 args->value = 1;
@@ -147,7 +146,7 @@ v3d_postclose(struct drm_device *dev, struct drm_file *file) · 57 unmodified lines
147DEFINE_DRM_GEM_FOPS(v3d_drm_fops);146DEFINE_DRM_GEM_FOPS(v3d_drm_fops);
148 147
149/* DRM_AUTH is required on SUBMIT_CL for now, while we don't have GMP148/* DRM_AUTH is required on SUBMIT_CL for now, while we don't have GMP
150 * protection between clients. Note that render nodes would be be149 * protection between clients. Note that render nodes would be
151 * able to submit CLs that could access BOs from clients authenticated150 * able to submit CLs that could access BOs from clients authenticated
152 * with the master node. The TFU doesn't use the GMP, so it would151 * with the master node. The TFU doesn't use the GMP, so it would
153 * need to stay DRM_AUTH until we do buffer size/offset validation.152 * need to stay DRM_AUTH until we do buffer size/offset validation.
@@ -219,7 +218,6 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) · 65 unmodified lines
219 u32 mmu_debug;218 u32 mmu_debug;
220 u32 ident1;219 u32 ident1;
221 220
222
223 v3d = devm_drm_dev_alloc(dev, &v3d_drm_driver, struct v3d_dev, drm);221 v3d = devm_drm_dev_alloc(dev, &v3d_drm_driver, struct v3d_dev, drm);
224 if (IS_ERR(v3d))222 if (IS_ERR(v3d))
225 return PTR_ERR(v3d);223 return PTR_ERR(v3d);
drivers/gpu/drm/v3d/v3d_gem.c+71−3
@@ -537,6 +537,36 @@ v3d_attach_fences_and_unlock_reservation(struct drm_file *file_priv, · 536 unmodified lines
537 }537 }
538}538}
539 539
540/* Whenever userspace sets ioctl extensions, v3d_get_extensions parses data
541 * according to the extension id (name).
542 */
543static int
544v3d_get_extensions(struct drm_file *file_priv, u64 ext_handles)
545{
546 struct drm_v3d_extension __user *user_ext;
547
548 user_ext = u64_to_user_ptr(ext_handles);
549 while (user_ext) {
550 struct drm_v3d_extension ext;
551
552 if (copy_from_user(&ext, user_ext, sizeof(ext))) {
553 DRM_DEBUG("Failed to copy submit extension\n");
554 return -EFAULT;
555 }
556
557 switch (ext.id) {
558 case 0:
559 default:
560 DRM_DEBUG_DRIVER("Unknown extension id: %d\n", ext.id);
561 return -EINVAL;
562 }
563
564 user_ext = u64_to_user_ptr(ext.next);
565 }
566
567 return 0;
568}
569
540/**570/**
541 * v3d_submit_cl_ioctl() - Submits a job (frame) to the V3D.571 * v3d_submit_cl_ioctl() - Submits a job (frame) to the V3D.
542 * @dev: DRM device572 * @dev: DRM device
@@ -565,15 +595,24 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, · 22 unmodified lines
565 595
566 trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end);596 trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end);
567 597
568 if (args->pad != 0)598 if (args->pad)
569 return -EINVAL;599 return -EINVAL;
570 600
571 if (args->flags != 0 &&601 if (args->flags &&
572 args->flags != DRM_V3D_SUBMIT_CL_FLUSH_CACHE) {602 args->flags & ~(DRM_V3D_SUBMIT_CL_FLUSH_CACHE |
603 DRM_V3D_SUBMIT_EXTENSION)) {
573 DRM_INFO("invalid flags: %d\n", args->flags);604 DRM_INFO("invalid flags: %d\n", args->flags);
574 return -EINVAL;605 return -EINVAL;
575 }606 }
576 607
608 if (args->flags & DRM_V3D_SUBMIT_EXTENSION) {
609 ret = v3d_get_extensions(file_priv, args->extensions);
610 if (ret) {
611 DRM_DEBUG("Failed to get extensions.\n");
612 return ret;
613 }
614 }
615
577 ret = v3d_job_init(v3d, file_priv, (void *)&render, sizeof(*render),616 ret = v3d_job_init(v3d, file_priv, (void *)&render, sizeof(*render),
578 v3d_render_job_free, args->in_sync_rcl, V3D_RENDER);617 v3d_render_job_free, args->in_sync_rcl, V3D_RENDER);
579 if (ret)618 if (ret)
@@ -702,6 +741,19 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, · 122 unmodified lines
702 741
703 trace_v3d_submit_tfu_ioctl(&v3d->drm, args->iia);742 trace_v3d_submit_tfu_ioctl(&v3d->drm, args->iia);
704 743
744 if (args->flags && !(args->flags & DRM_V3D_SUBMIT_EXTENSION)) {
745 DRM_DEBUG("invalid flags: %d\n", args->flags);
746 return -EINVAL;
747 }
748
749 if (args->flags & DRM_V3D_SUBMIT_EXTENSION) {
750 ret = v3d_get_extensions(file_priv, args->extensions);
751 if (ret) {
752 DRM_DEBUG("Failed to get extensions.\n");
753 return ret;
754 }
755 }
756
705 ret = v3d_job_init(v3d, file_priv, (void *)&job, sizeof(*job),757 ret = v3d_job_init(v3d, file_priv, (void *)&job, sizeof(*job),
706 v3d_job_free, args->in_sync, V3D_TFU);758 v3d_job_free, args->in_sync, V3D_TFU);
707 if (ret)759 if (ret)
@@ -786,11 +838,27 @@ v3d_submit_csd_ioctl(struct drm_device *dev, void *data, · 78 unmodified lines
786 838
787 trace_v3d_submit_csd_ioctl(&v3d->drm, args->cfg[5], args->cfg[6]);839 trace_v3d_submit_csd_ioctl(&v3d->drm, args->cfg[5], args->cfg[6]);
788 840
841 if (args->pad)
842 return -EINVAL;
843
789 if (!v3d_has_csd(v3d)) {844 if (!v3d_has_csd(v3d)) {
790 DRM_DEBUG("Attempting CSD submit on non-CSD hardware\n");845 DRM_DEBUG("Attempting CSD submit on non-CSD hardware\n");
791 return -EINVAL;846 return -EINVAL;
792 }847 }
793 848
849 if (args->flags && !(args->flags & DRM_V3D_SUBMIT_EXTENSION)) {
850 DRM_INFO("invalid flags: %d\n", args->flags);
851 return -EINVAL;
852 }
853
854 if (args->flags & DRM_V3D_SUBMIT_EXTENSION) {
855 ret = v3d_get_extensions(file_priv, args->extensions);
856 if (ret) {
857 DRM_DEBUG("Failed to get extensions.\n");
858 return ret;
859 }
860 }
861
794 ret = v3d_job_init(v3d, file_priv, (void *)&job, sizeof(*job),862 ret = v3d_job_init(v3d, file_priv, (void *)&job, sizeof(*job),
795 v3d_job_free, args->in_sync, V3D_CSD);863 v3d_job_free, args->in_sync, V3D_CSD);
796 if (ret)864 if (ret)
include/uapi/drm/v3d_drm.h+31−0
@@ -58,6 +58,20 @@ extern "C" { · 57 unmodified lines
58 struct drm_v3d_perfmon_get_values)58 struct drm_v3d_perfmon_get_values)
59 59
60#define DRM_V3D_SUBMIT_CL_FLUSH_CACHE 0x0160#define DRM_V3D_SUBMIT_CL_FLUSH_CACHE 0x01
61#define DRM_V3D_SUBMIT_EXTENSION 0x02
62
63/* struct drm_v3d_extension - ioctl extensions
64 *
65 * Linked-list of generic extensions where the id identify which struct is
66 * pointed by ext_data. Therefore, DRM_V3D_EXT_ID_* is used on id to identify
67 * the extension type.
68 */
69struct drm_v3d_extension {
70 __u64 next;
71 __u32 id;
72#define DRM_V3D_EXT_ID_MULTI_SYNC 0x01
73 __u32 flags; /* mbz */
74};
61 75
62/**76/**
63 * struct drm_v3d_submit_cl - ioctl argument for submitting commands to the 3D77 * struct drm_v3d_submit_cl - ioctl argument for submitting commands to the 3D
@@ -135,12 +149,16 @@ struct drm_v3d_submit_cl { · 71 unmodified lines
135 /* Number of BO handles passed in (size is that times 4). */149 /* Number of BO handles passed in (size is that times 4). */
136 __u32 bo_handle_count;150 __u32 bo_handle_count;
137 151
152 /* DRM_V3D_SUBMIT_* properties */
138 __u32 flags;153 __u32 flags;
139 154
140 /* ID of the perfmon to attach to this job. 0 means no perfmon. */155 /* ID of the perfmon to attach to this job. 0 means no perfmon. */
141 __u32 perfmon_id;156 __u32 perfmon_id;
142 157
143 __u32 pad;158 __u32 pad;
159
160 /* Pointer to an array of ioctl extensions*/
161 __u64 extensions;
144};162};
145 163
146/**164/**
@@ -248,6 +266,12 @@ struct drm_v3d_submit_tfu { · 101 unmodified lines
248 __u32 in_sync;266 __u32 in_sync;
249 /* Sync object to signal when the TFU job is done. */267 /* Sync object to signal when the TFU job is done. */
250 __u32 out_sync;268 __u32 out_sync;
269
270 __u32 flags;
271
272 /* Pointer to an array of ioctl extensions*/
273 __u64 extensions;
274
251};275};
252 276
253/* Submits a compute shader for dispatch. This job will block on any277/* Submits a compute shader for dispatch. This job will block on any
@@ -276,6 +300,13 @@ struct drm_v3d_submit_csd { · 22 unmodified lines
276 300
277 /* ID of the perfmon to attach to this job. 0 means no perfmon. */301 /* ID of the perfmon to attach to this job. 0 means no perfmon. */
278 __u32 perfmon_id;302 __u32 perfmon_id;
303
304 /* Pointer to an array of ioctl extensions*/
305 __u64 extensions;
306
307 __u32 flags;
308
309 __u32 pad;
279};310};
280 311
281enum {312enum {