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
8383 return 0;
8484 }
8585
86−
8786 switch (args->param) {
8887 case DRM_V3D_PARAM_SUPPORTS_TFU:
8988 args->value = 1;
@@ -147,7 +146,7 @@ v3d_postclose(struct drm_device *dev, struct drm_file *file) · 57 unmodified lines
147146 DEFINE_DRM_GEM_FOPS(v3d_drm_fops);
148147
149148 /* 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 be
149+ * protection between clients. Note that render nodes would be
151150 * able to submit CLs that could access BOs from clients authenticated
152151 * with the master node. The TFU doesn't use the GMP, so it would
153152 * 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
219218 u32 mmu_debug;
220219 u32 ident1;
221220
222−
223221 v3d = devm_drm_dev_alloc(dev, &v3d_drm_driver, struct v3d_dev, drm);
224222 if (IS_ERR(v3d))
225223 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
537537 }
538538 }
539539
540+/* Whenever userspace sets ioctl extensions, v3d_get_extensions parses data
541+ * according to the extension id (name).
542+ */
543+static int
544+v3d_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+
540570 /**
541571 * v3d_submit_cl_ioctl() - Submits a job (frame) to the V3D.
542572 * @dev: DRM device
@@ -565,15 +595,24 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, · 22 unmodified lines
565595
566596 trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end);
567597
568− if (args->pad != 0)
598+ if (args->pad)
569599 return -EINVAL;
570600
571− if (args->flags != 0 &&
572− args->flags != DRM_V3D_SUBMIT_CL_FLUSH_CACHE) {
601+ if (args->flags &&
602+ args->flags & ~(DRM_V3D_SUBMIT_CL_FLUSH_CACHE |
603+ DRM_V3D_SUBMIT_EXTENSION)) {
573604 DRM_INFO("invalid flags: %d\n", args->flags);
574605 return -EINVAL;
575606 }
576607
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+
577616 ret = v3d_job_init(v3d, file_priv, (void *)&render, sizeof(*render),
578617 v3d_render_job_free, args->in_sync_rcl, V3D_RENDER);
579618 if (ret)
@@ -702,6 +741,19 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, · 122 unmodified lines
702741
703742 trace_v3d_submit_tfu_ioctl(&v3d->drm, args->iia);
704743
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+
705757 ret = v3d_job_init(v3d, file_priv, (void *)&job, sizeof(*job),
706758 v3d_job_free, args->in_sync, V3D_TFU);
707759 if (ret)
@@ -786,11 +838,27 @@ v3d_submit_csd_ioctl(struct drm_device *dev, void *data, · 78 unmodified lines
786838
787839 trace_v3d_submit_csd_ioctl(&v3d->drm, args->cfg[5], args->cfg[6]);
788840
841+ if (args->pad)
842+ return -EINVAL;
843+
789844 if (!v3d_has_csd(v3d)) {
790845 DRM_DEBUG("Attempting CSD submit on non-CSD hardware\n");
791846 return -EINVAL;
792847 }
793848
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+
794862 ret = v3d_job_init(v3d, file_priv, (void *)&job, sizeof(*job),
795863 v3d_job_free, args->in_sync, V3D_CSD);
796864 if (ret)
include/uapi/drm/v3d_drm.h+31−0
@@ -58,6 +58,20 @@ extern "C" { · 57 unmodified lines
5858 struct drm_v3d_perfmon_get_values)
5959
6060 #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+ */
69+struct drm_v3d_extension {
70+ __u64 next;
71+ __u32 id;
72+#define DRM_V3D_EXT_ID_MULTI_SYNC 0x01
73+ __u32 flags; /* mbz */
74+};
6175
6276 /**
6377 * 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
135149 /* Number of BO handles passed in (size is that times 4). */
136150 __u32 bo_handle_count;
137151
152+ /* DRM_V3D_SUBMIT_* properties */
138153 __u32 flags;
139154
140155 /* ID of the perfmon to attach to this job. 0 means no perfmon. */
141156 __u32 perfmon_id;
142157
143158 __u32 pad;
159+
160+ /* Pointer to an array of ioctl extensions*/
161+ __u64 extensions;
144162 };
145163
146164 /**
@@ -248,6 +266,12 @@ struct drm_v3d_submit_tfu { · 101 unmodified lines
248266 __u32 in_sync;
249267 /* Sync object to signal when the TFU job is done. */
250268 __u32 out_sync;
269+
270+ __u32 flags;
271+
272+ /* Pointer to an array of ioctl extensions*/
273+ __u64 extensions;
274+
251275 };
252276
253277 /* Submits a compute shader for dispatch. This job will block on any
@@ -276,6 +300,13 @@ struct drm_v3d_submit_csd { · 22 unmodified lines
276300
277301 /* ID of the perfmon to attach to this job. 0 means no perfmon. */
278302 __u32 perfmon_id;
303+
304+ /* Pointer to an array of ioctl extensions*/
305+ __u64 extensions;
306+
307+ __u32 flags;
308+
309+ __u32 pad;
279310 };
280311
281312 enum {