Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm: omapdrm: Remove legacy buffer synchronization support

The omapdrm driver uses a custom API to synchronize with the SGX GPU.
This is unusable as such in the mainline kernel as the API is only
partially implemented and requires additional out-of-tree patches.
Furthermore, as no SGX driver is available in the mainline kernel, the
API can't be considered as a stable mainline API.

Now that the driver supports synchronization through fences, remove
legacy buffer synchronization support. The two userspace ioctls are
turned into no-ops to avoid breaking userspace and will be removed in
the future.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

authored by

Laurent Pinchart and committed by
Tomi Valkeinen
d6f544f6 a9e6f9f7

+6 -270
+4 -49
drivers/gpu/drm/omapdrm/omap_drv.c
··· 365 365 &args->handle); 366 366 } 367 367 368 - static int ioctl_gem_cpu_prep(struct drm_device *dev, void *data, 369 - struct drm_file *file_priv) 370 - { 371 - struct drm_omap_gem_cpu_prep *args = data; 372 - struct drm_gem_object *obj; 373 - int ret; 374 - 375 - VERB("%p:%p: handle=%d, op=%x", dev, file_priv, args->handle, args->op); 376 - 377 - obj = drm_gem_object_lookup(file_priv, args->handle); 378 - if (!obj) 379 - return -ENOENT; 380 - 381 - ret = omap_gem_op_sync(obj, args->op); 382 - 383 - if (!ret) 384 - ret = omap_gem_op_start(obj, args->op); 385 - 386 - drm_gem_object_unreference_unlocked(obj); 387 - 388 - return ret; 389 - } 390 - 391 - static int ioctl_gem_cpu_fini(struct drm_device *dev, void *data, 392 - struct drm_file *file_priv) 393 - { 394 - struct drm_omap_gem_cpu_fini *args = data; 395 - struct drm_gem_object *obj; 396 - int ret; 397 - 398 - VERB("%p:%p: handle=%d", dev, file_priv, args->handle); 399 - 400 - obj = drm_gem_object_lookup(file_priv, args->handle); 401 - if (!obj) 402 - return -ENOENT; 403 - 404 - /* XXX flushy, flushy */ 405 - ret = 0; 406 - 407 - if (!ret) 408 - ret = omap_gem_op_finish(obj, args->op); 409 - 410 - drm_gem_object_unreference_unlocked(obj); 411 - 412 - return ret; 413 - } 414 - 415 368 static int ioctl_gem_info(struct drm_device *dev, void *data, 416 369 struct drm_file *file_priv) 417 370 { ··· 393 440 DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), 394 441 DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new, 395 442 DRM_AUTH | DRM_RENDER_ALLOW), 396 - DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, ioctl_gem_cpu_prep, 443 + /* Deprecated, to be removed. */ 444 + DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, drm_noop, 397 445 DRM_AUTH | DRM_RENDER_ALLOW), 398 - DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_FINI, ioctl_gem_cpu_fini, 446 + /* Deprecated, to be removed. */ 447 + DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_FINI, drm_noop, 399 448 DRM_AUTH | DRM_RENDER_ALLOW), 400 449 DRM_IOCTL_DEF_DRV(OMAP_GEM_INFO, ioctl_gem_info, 401 450 DRM_AUTH | DRM_RENDER_ALLOW),
-5
drivers/gpu/drm/omapdrm/omap_drv.h
··· 184 184 int omap_gem_mmap_obj(struct drm_gem_object *obj, 185 185 struct vm_area_struct *vma); 186 186 int omap_gem_fault(struct vm_fault *vmf); 187 - int omap_gem_op_start(struct drm_gem_object *obj, enum omap_gem_op op); 188 - int omap_gem_op_finish(struct drm_gem_object *obj, enum omap_gem_op op); 189 - int omap_gem_op_sync(struct drm_gem_object *obj, enum omap_gem_op op); 190 - int omap_gem_op_async(struct drm_gem_object *obj, enum omap_gem_op op, 191 - void (*fxn)(void *arg), void *arg); 192 187 int omap_gem_roll(struct drm_gem_object *obj, uint32_t roll); 193 188 void omap_gem_cpu_sync(struct drm_gem_object *obj, int pgoff); 194 189 void omap_gem_dma_sync(struct drm_gem_object *obj,
-214
drivers/gpu/drm/omapdrm/omap_gem.c
··· 101 101 * Virtual address, if mapped. 102 102 */ 103 103 void *vaddr; 104 - 105 - /** 106 - * sync-object allocated on demand (if needed) 107 - * 108 - * Per-buffer sync-object for tracking pending and completed hw/dma 109 - * read and write operations. 110 - */ 111 - struct { 112 - uint32_t write_pending; 113 - uint32_t write_complete; 114 - uint32_t read_pending; 115 - uint32_t read_complete; 116 - } *sync; 117 104 }; 118 105 119 106 #define to_omap_bo(x) container_of(x, struct omap_gem_object, base) ··· 1058 1071 #endif 1059 1072 1060 1073 /* ----------------------------------------------------------------------------- 1061 - * Buffer Synchronization 1062 - */ 1063 - 1064 - static DEFINE_SPINLOCK(sync_lock); 1065 - 1066 - struct omap_gem_sync_waiter { 1067 - struct list_head list; 1068 - struct omap_gem_object *omap_obj; 1069 - enum omap_gem_op op; 1070 - uint32_t read_target, write_target; 1071 - /* notify called w/ sync_lock held */ 1072 - void (*notify)(void *arg); 1073 - void *arg; 1074 - }; 1075 - 1076 - /* list of omap_gem_sync_waiter.. the notify fxn gets called back when 1077 - * the read and/or write target count is achieved which can call a user 1078 - * callback (ex. to kick 3d and/or 2d), wakeup blocked task (prep for 1079 - * cpu access), etc. 1080 - */ 1081 - static LIST_HEAD(waiters); 1082 - 1083 - static inline bool is_waiting(struct omap_gem_sync_waiter *waiter) 1084 - { 1085 - struct omap_gem_object *omap_obj = waiter->omap_obj; 1086 - if ((waiter->op & OMAP_GEM_READ) && 1087 - (omap_obj->sync->write_complete < waiter->write_target)) 1088 - return true; 1089 - if ((waiter->op & OMAP_GEM_WRITE) && 1090 - (omap_obj->sync->read_complete < waiter->read_target)) 1091 - return true; 1092 - return false; 1093 - } 1094 - 1095 - /* macro for sync debug.. */ 1096 - #define SYNCDBG 0 1097 - #define SYNC(fmt, ...) do { if (SYNCDBG) \ 1098 - pr_err("%s:%d: " fmt "\n", __func__, __LINE__, ##__VA_ARGS__); \ 1099 - } while (0) 1100 - 1101 - 1102 - static void sync_op_update(void) 1103 - { 1104 - struct omap_gem_sync_waiter *waiter, *n; 1105 - list_for_each_entry_safe(waiter, n, &waiters, list) { 1106 - if (!is_waiting(waiter)) { 1107 - list_del(&waiter->list); 1108 - SYNC("notify: %p", waiter); 1109 - waiter->notify(waiter->arg); 1110 - kfree(waiter); 1111 - } 1112 - } 1113 - } 1114 - 1115 - static inline int sync_op(struct drm_gem_object *obj, 1116 - enum omap_gem_op op, bool start) 1117 - { 1118 - struct omap_gem_object *omap_obj = to_omap_bo(obj); 1119 - int ret = 0; 1120 - 1121 - spin_lock(&sync_lock); 1122 - 1123 - if (!omap_obj->sync) { 1124 - omap_obj->sync = kzalloc(sizeof(*omap_obj->sync), GFP_ATOMIC); 1125 - if (!omap_obj->sync) { 1126 - ret = -ENOMEM; 1127 - goto unlock; 1128 - } 1129 - } 1130 - 1131 - if (start) { 1132 - if (op & OMAP_GEM_READ) 1133 - omap_obj->sync->read_pending++; 1134 - if (op & OMAP_GEM_WRITE) 1135 - omap_obj->sync->write_pending++; 1136 - } else { 1137 - if (op & OMAP_GEM_READ) 1138 - omap_obj->sync->read_complete++; 1139 - if (op & OMAP_GEM_WRITE) 1140 - omap_obj->sync->write_complete++; 1141 - sync_op_update(); 1142 - } 1143 - 1144 - unlock: 1145 - spin_unlock(&sync_lock); 1146 - 1147 - return ret; 1148 - } 1149 - 1150 - /* mark the start of read and/or write operation */ 1151 - int omap_gem_op_start(struct drm_gem_object *obj, enum omap_gem_op op) 1152 - { 1153 - return sync_op(obj, op, true); 1154 - } 1155 - 1156 - int omap_gem_op_finish(struct drm_gem_object *obj, enum omap_gem_op op) 1157 - { 1158 - return sync_op(obj, op, false); 1159 - } 1160 - 1161 - static DECLARE_WAIT_QUEUE_HEAD(sync_event); 1162 - 1163 - static void sync_notify(void *arg) 1164 - { 1165 - struct task_struct **waiter_task = arg; 1166 - *waiter_task = NULL; 1167 - wake_up_all(&sync_event); 1168 - } 1169 - 1170 - int omap_gem_op_sync(struct drm_gem_object *obj, enum omap_gem_op op) 1171 - { 1172 - struct omap_gem_object *omap_obj = to_omap_bo(obj); 1173 - int ret = 0; 1174 - if (omap_obj->sync) { 1175 - struct task_struct *waiter_task = current; 1176 - struct omap_gem_sync_waiter *waiter = 1177 - kzalloc(sizeof(*waiter), GFP_KERNEL); 1178 - 1179 - if (!waiter) 1180 - return -ENOMEM; 1181 - 1182 - waiter->omap_obj = omap_obj; 1183 - waiter->op = op; 1184 - waiter->read_target = omap_obj->sync->read_pending; 1185 - waiter->write_target = omap_obj->sync->write_pending; 1186 - waiter->notify = sync_notify; 1187 - waiter->arg = &waiter_task; 1188 - 1189 - spin_lock(&sync_lock); 1190 - if (is_waiting(waiter)) { 1191 - SYNC("waited: %p", waiter); 1192 - list_add_tail(&waiter->list, &waiters); 1193 - spin_unlock(&sync_lock); 1194 - ret = wait_event_interruptible(sync_event, 1195 - (waiter_task == NULL)); 1196 - spin_lock(&sync_lock); 1197 - if (waiter_task) { 1198 - SYNC("interrupted: %p", waiter); 1199 - /* we were interrupted */ 1200 - list_del(&waiter->list); 1201 - waiter_task = NULL; 1202 - } else { 1203 - /* freed in sync_op_update() */ 1204 - waiter = NULL; 1205 - } 1206 - } 1207 - spin_unlock(&sync_lock); 1208 - kfree(waiter); 1209 - } 1210 - return ret; 1211 - } 1212 - 1213 - /* call fxn(arg), either synchronously or asynchronously if the op 1214 - * is currently blocked.. fxn() can be called from any context 1215 - * 1216 - * (TODO for now fxn is called back from whichever context calls 1217 - * omap_gem_op_finish().. but this could be better defined later 1218 - * if needed) 1219 - * 1220 - * TODO more code in common w/ _sync().. 1221 - */ 1222 - int omap_gem_op_async(struct drm_gem_object *obj, enum omap_gem_op op, 1223 - void (*fxn)(void *arg), void *arg) 1224 - { 1225 - struct omap_gem_object *omap_obj = to_omap_bo(obj); 1226 - if (omap_obj->sync) { 1227 - struct omap_gem_sync_waiter *waiter = 1228 - kzalloc(sizeof(*waiter), GFP_ATOMIC); 1229 - 1230 - if (!waiter) 1231 - return -ENOMEM; 1232 - 1233 - waiter->omap_obj = omap_obj; 1234 - waiter->op = op; 1235 - waiter->read_target = omap_obj->sync->read_pending; 1236 - waiter->write_target = omap_obj->sync->write_pending; 1237 - waiter->notify = fxn; 1238 - waiter->arg = arg; 1239 - 1240 - spin_lock(&sync_lock); 1241 - if (is_waiting(waiter)) { 1242 - SYNC("waited: %p", waiter); 1243 - list_add_tail(&waiter->list, &waiters); 1244 - spin_unlock(&sync_lock); 1245 - return 0; 1246 - } 1247 - 1248 - spin_unlock(&sync_lock); 1249 - 1250 - kfree(waiter); 1251 - } 1252 - 1253 - /* no waiting.. */ 1254 - fxn(arg); 1255 - 1256 - return 0; 1257 - } 1258 - 1259 - /* ----------------------------------------------------------------------------- 1260 1074 * Constructor & Destructor 1261 1075 */ 1262 1076 ··· 1095 1307 } else if (obj->import_attach) { 1096 1308 drm_prime_gem_destroy(obj, omap_obj->sgt); 1097 1309 } 1098 - 1099 - kfree(omap_obj->sync); 1100 1310 1101 1311 drm_gem_object_release(obj); 1102 1312
+2 -2
include/uapi/drm/omap_drm.h
··· 106 106 #define DRM_OMAP_GET_PARAM 0x00 107 107 #define DRM_OMAP_SET_PARAM 0x01 108 108 #define DRM_OMAP_GEM_NEW 0x03 109 - #define DRM_OMAP_GEM_CPU_PREP 0x04 110 - #define DRM_OMAP_GEM_CPU_FINI 0x05 109 + #define DRM_OMAP_GEM_CPU_PREP 0x04 /* Deprecated, to be removed */ 110 + #define DRM_OMAP_GEM_CPU_FINI 0x05 /* Deprecated, to be removed */ 111 111 #define DRM_OMAP_GEM_INFO 0x06 112 112 #define DRM_OMAP_NUM_IOCTLS 0x07 113 113