History

drm/syncobj: add timeline signal ioctl for syncobj v5

v2: individually allocate chain array, since chain node is free independently. v3: all existing points must be already signaled before cpu perform signal operation, so add check condition for that. v4: remove v3 change and add checking to prevent out-of-order v5: unify binary and timeline

Chunming Zhou committed 7 years ago

Commit 50d1ebe1 parent ea569914 files · +78 −0Browse files

Unified · Split

4 files
  1. drivers/gpu/drm/drm_internal.h +2 −0
  2. drivers/gpu/drm/drm_ioctl.c +2 −0
  3. drivers/gpu/drm/drm_syncobj.c +73 −0
  4. include/uapi/drm/drm.h +1 −0
drivers/gpu/drm/drm_internal.h+2−0
@@ -190,6 +190,8 @@ int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, · 189 unmodified lines
190190 struct drm_file *file_private);
191191 int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
192192 struct drm_file *file_private);
193+int drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data,
194+ struct drm_file *file_private);
193195 int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
194196 struct drm_file *file_private);
195197
drivers/gpu/drm/drm_ioctl.c+2−0
@@ -696,6 +696,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { · 695 unmodified lines
696696 DRM_UNLOCKED|DRM_RENDER_ALLOW),
697697 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
698698 DRM_UNLOCKED|DRM_RENDER_ALLOW),
699+ DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, drm_syncobj_timeline_signal_ioctl,
700+ DRM_UNLOCKED|DRM_RENDER_ALLOW),
699701 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
700702 DRM_UNLOCKED|DRM_RENDER_ALLOW),
701703 DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED),
drivers/gpu/drm/drm_syncobj.c+73−0
@@ -1184,6 +1184,79 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, · 1183 unmodified lines
11841184 return ret;
11851185 }
11861186
1187+int
1188+drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data,
1189+ struct drm_file *file_private)
1190+{
1191+ struct drm_syncobj_timeline_array *args = data;
1192+ struct drm_syncobj **syncobjs;
1193+ struct dma_fence_chain **chains;
1194+ uint64_t *points;
1195+ uint32_t i, j;
1196+ int ret;
1197+
1198+ if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
1199+ return -EOPNOTSUPP;
1200+
1201+ if (args->pad != 0)
1202+ return -EINVAL;
1203+
1204+ if (args->count_handles == 0)
1205+ return -EINVAL;
1206+
1207+ ret = drm_syncobj_array_find(file_private,
1208+ u64_to_user_ptr(args->handles),
1209+ args->count_handles,
1210+ &syncobjs);
1211+ if (ret < 0)
1212+ return ret;
1213+
1214+ points = kmalloc_array(args->count_handles, sizeof(*points),
1215+ GFP_KERNEL);
1216+ if (!points) {
1217+ ret = -ENOMEM;
1218+ goto out;
1219+ }
1220+ if (!u64_to_user_ptr(args->points)) {
1221+ memset(points, 0, args->count_handles * sizeof(uint64_t));
1222+ } else if (copy_from_user(points, u64_to_user_ptr(args->points),
1223+ sizeof(uint64_t) * args->count_handles)) {
1224+ ret = -EFAULT;
1225+ goto err_points;
1226+ }
1227+
1228+ chains = kmalloc_array(args->count_handles, sizeof(void *), GFP_KERNEL);
1229+ if (!chains) {
1230+ ret = -ENOMEM;
1231+ goto err_points;
1232+ }
1233+ for (i = 0; i < args->count_handles; i++) {
1234+ chains[i] = kzalloc(sizeof(struct dma_fence_chain), GFP_KERNEL);
1235+ if (!chains[i]) {
1236+ for (j = 0; j < i; j++)
1237+ kfree(chains[j]);
1238+ ret = -ENOMEM;
1239+ goto err_chains;
1240+ }
1241+ }
1242+
1243+ for (i = 0; i < args->count_handles; i++) {
1244+ struct dma_fence *fence = dma_fence_get_stub();
1245+
1246+ drm_syncobj_add_point(syncobjs[i], chains[i],
1247+ fence, points[i]);
1248+ dma_fence_put(fence);
1249+ }
1250+err_chains:
1251+ kfree(chains);
1252+err_points:
1253+ kfree(points);
1254+out:
1255+ drm_syncobj_array_free(syncobjs, args->count_handles);
1256+
1257+ return ret;
1258+}
1259+
11871260 int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
11881261 struct drm_file *file_private)
11891262 {
include/uapi/drm/drm.h+1−0
@@ -943,6 +943,7 @@ extern "C" { · 942 unmodified lines
943943 #define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait)
944944 #define DRM_IOCTL_SYNCOBJ_QUERY DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)
945945 #define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer)
946+#define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
946947
947948 /**
948949 * Device specific ioctls should only be in their respective headers