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
190 struct drm_file *file_private);190 struct drm_file *file_private);
191int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,191int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
192 struct drm_file *file_private);192 struct drm_file *file_private);
193int drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data,
194 struct drm_file *file_private);
193int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,195int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
194 struct drm_file *file_private);196 struct drm_file *file_private);
195 197
drivers/gpu/drm/drm_ioctl.c+2−0
@@ -696,6 +696,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { · 695 unmodified lines
696 DRM_UNLOCKED|DRM_RENDER_ALLOW),696 DRM_UNLOCKED|DRM_RENDER_ALLOW),
697 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,697 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
698 DRM_UNLOCKED|DRM_RENDER_ALLOW),698 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),
699 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,701 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
700 DRM_UNLOCKED|DRM_RENDER_ALLOW),702 DRM_UNLOCKED|DRM_RENDER_ALLOW),
701 DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED),703 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
1184 return ret;1184 return ret;
1185}1185}
1186 1186
1187int
1188drm_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 }
1250err_chains:
1251 kfree(chains);
1252err_points:
1253 kfree(points);
1254out:
1255 drm_syncobj_array_free(syncobjs, args->count_handles);
1256
1257 return ret;
1258}
1259
1187int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,1260int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
1188 struct drm_file *file_private)1261 struct drm_file *file_private)
1189{1262{
include/uapi/drm/drm.h+1−0
@@ -943,6 +943,7 @@ extern "C" { · 942 unmodified lines
943#define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait)943#define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait)
944#define DRM_IOCTL_SYNCOBJ_QUERY DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)944#define DRM_IOCTL_SYNCOBJ_QUERY DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)
945#define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer)945#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)
946 947
947/**948/**
948 * Device specific ioctls should only be in their respective headers949 * Device specific ioctls should only be in their respective headers