xref: /openbmc/linux/drivers/dma-buf/sync_file.c (revision 7a2f6f61)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * drivers/dma-buf/sync_file.c
4  *
5  * Copyright (C) 2012 Google, Inc.
6  */
7 
8 #include <linux/dma-fence-unwrap.h>
9 #include <linux/export.h>
10 #include <linux/file.h>
11 #include <linux/fs.h>
12 #include <linux/kernel.h>
13 #include <linux/poll.h>
14 #include <linux/sched.h>
15 #include <linux/slab.h>
16 #include <linux/uaccess.h>
17 #include <linux/anon_inodes.h>
18 #include <linux/sync_file.h>
19 #include <uapi/linux/sync_file.h>
20 
21 static const struct file_operations sync_file_fops;
22 
23 static struct sync_file *sync_file_alloc(void)
24 {
25 	struct sync_file *sync_file;
26 
27 	sync_file = kzalloc(sizeof(*sync_file), GFP_KERNEL);
28 	if (!sync_file)
29 		return NULL;
30 
31 	sync_file->file = anon_inode_getfile("sync_file", &sync_file_fops,
32 					     sync_file, 0);
33 	if (IS_ERR(sync_file->file))
34 		goto err;
35 
36 	init_waitqueue_head(&sync_file->wq);
37 
38 	INIT_LIST_HEAD(&sync_file->cb.node);
39 
40 	return sync_file;
41 
42 err:
43 	kfree(sync_file);
44 	return NULL;
45 }
46 
47 static void fence_check_cb_func(struct dma_fence *f, struct dma_fence_cb *cb)
48 {
49 	struct sync_file *sync_file;
50 
51 	sync_file = container_of(cb, struct sync_file, cb);
52 
53 	wake_up_all(&sync_file->wq);
54 }
55 
56 /**
57  * sync_file_create() - creates a sync file
58  * @fence:	fence to add to the sync_fence
59  *
60  * Creates a sync_file containg @fence. This function acquires and additional
61  * reference of @fence for the newly-created &sync_file, if it succeeds. The
62  * sync_file can be released with fput(sync_file->file). Returns the
63  * sync_file or NULL in case of error.
64  */
65 struct sync_file *sync_file_create(struct dma_fence *fence)
66 {
67 	struct sync_file *sync_file;
68 
69 	sync_file = sync_file_alloc();
70 	if (!sync_file)
71 		return NULL;
72 
73 	sync_file->fence = dma_fence_get(fence);
74 
75 	return sync_file;
76 }
77 EXPORT_SYMBOL(sync_file_create);
78 
79 static struct sync_file *sync_file_fdget(int fd)
80 {
81 	struct file *file = fget(fd);
82 
83 	if (!file)
84 		return NULL;
85 
86 	if (file->f_op != &sync_file_fops)
87 		goto err;
88 
89 	return file->private_data;
90 
91 err:
92 	fput(file);
93 	return NULL;
94 }
95 
96 /**
97  * sync_file_get_fence - get the fence related to the sync_file fd
98  * @fd:		sync_file fd to get the fence from
99  *
100  * Ensures @fd references a valid sync_file and returns a fence that
101  * represents all fence in the sync_file. On error NULL is returned.
102  */
103 struct dma_fence *sync_file_get_fence(int fd)
104 {
105 	struct sync_file *sync_file;
106 	struct dma_fence *fence;
107 
108 	sync_file = sync_file_fdget(fd);
109 	if (!sync_file)
110 		return NULL;
111 
112 	fence = dma_fence_get(sync_file->fence);
113 	fput(sync_file->file);
114 
115 	return fence;
116 }
117 EXPORT_SYMBOL(sync_file_get_fence);
118 
119 /**
120  * sync_file_get_name - get the name of the sync_file
121  * @sync_file:		sync_file to get the fence from
122  * @buf:		destination buffer to copy sync_file name into
123  * @len:		available size of destination buffer.
124  *
125  * Each sync_file may have a name assigned either by the user (when merging
126  * sync_files together) or created from the fence it contains. In the latter
127  * case construction of the name is deferred until use, and so requires
128  * sync_file_get_name().
129  *
130  * Returns: a string representing the name.
131  */
132 char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len)
133 {
134 	if (sync_file->user_name[0]) {
135 		strlcpy(buf, sync_file->user_name, len);
136 	} else {
137 		struct dma_fence *fence = sync_file->fence;
138 
139 		snprintf(buf, len, "%s-%s%llu-%lld",
140 			 fence->ops->get_driver_name(fence),
141 			 fence->ops->get_timeline_name(fence),
142 			 fence->context,
143 			 fence->seqno);
144 	}
145 
146 	return buf;
147 }
148 
149 static int sync_file_set_fence(struct sync_file *sync_file,
150 			       struct dma_fence **fences, int num_fences)
151 {
152 	struct dma_fence_array *array;
153 
154 	/*
155 	 * The reference for the fences in the new sync_file and held
156 	 * in add_fence() during the merge procedure, so for num_fences == 1
157 	 * we already own a new reference to the fence. For num_fence > 1
158 	 * we own the reference of the dma_fence_array creation.
159 	 */
160 	if (num_fences == 1) {
161 		sync_file->fence = fences[0];
162 		kfree(fences);
163 	} else {
164 		array = dma_fence_array_create(num_fences, fences,
165 					       dma_fence_context_alloc(1),
166 					       1, false);
167 		if (!array)
168 			return -ENOMEM;
169 
170 		sync_file->fence = &array->base;
171 	}
172 
173 	return 0;
174 }
175 
176 static void add_fence(struct dma_fence **fences,
177 		      int *i, struct dma_fence *fence)
178 {
179 	fences[*i] = fence;
180 
181 	if (!dma_fence_is_signaled(fence)) {
182 		dma_fence_get(fence);
183 		(*i)++;
184 	}
185 }
186 
187 /**
188  * sync_file_merge() - merge two sync_files
189  * @name:	name of new fence
190  * @a:		sync_file a
191  * @b:		sync_file b
192  *
193  * Creates a new sync_file which contains copies of all the fences in both
194  * @a and @b.  @a and @b remain valid, independent sync_file. Returns the
195  * new merged sync_file or NULL in case of error.
196  */
197 static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
198 					 struct sync_file *b)
199 {
200 	struct dma_fence *a_fence, *b_fence, **fences;
201 	struct dma_fence_unwrap a_iter, b_iter;
202 	unsigned int index, num_fences;
203 	struct sync_file *sync_file;
204 
205 	sync_file = sync_file_alloc();
206 	if (!sync_file)
207 		return NULL;
208 
209 	num_fences = 0;
210 	dma_fence_unwrap_for_each(a_fence, &a_iter, a->fence)
211 		++num_fences;
212 	dma_fence_unwrap_for_each(b_fence, &b_iter, b->fence)
213 		++num_fences;
214 
215 	if (num_fences > INT_MAX)
216 		goto err_free_sync_file;
217 
218 	fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL);
219 	if (!fences)
220 		goto err_free_sync_file;
221 
222 	/*
223 	 * We can't guarantee that fences in both a and b are ordered, but it is
224 	 * still quite likely.
225 	 *
226 	 * So attempt to order the fences as we pass over them and merge fences
227 	 * with the same context.
228 	 */
229 
230 	index = 0;
231 	for (a_fence = dma_fence_unwrap_first(a->fence, &a_iter),
232 	     b_fence = dma_fence_unwrap_first(b->fence, &b_iter);
233 	     a_fence || b_fence; ) {
234 
235 		if (!b_fence) {
236 			add_fence(fences, &index, a_fence);
237 			a_fence = dma_fence_unwrap_next(&a_iter);
238 
239 		} else if (!a_fence) {
240 			add_fence(fences, &index, b_fence);
241 			b_fence = dma_fence_unwrap_next(&b_iter);
242 
243 		} else if (a_fence->context < b_fence->context) {
244 			add_fence(fences, &index, a_fence);
245 			a_fence = dma_fence_unwrap_next(&a_iter);
246 
247 		} else if (b_fence->context < a_fence->context) {
248 			add_fence(fences, &index, b_fence);
249 			b_fence = dma_fence_unwrap_next(&b_iter);
250 
251 		} else if (__dma_fence_is_later(a_fence->seqno, b_fence->seqno,
252 						a_fence->ops)) {
253 			add_fence(fences, &index, a_fence);
254 			a_fence = dma_fence_unwrap_next(&a_iter);
255 			b_fence = dma_fence_unwrap_next(&b_iter);
256 
257 		} else {
258 			add_fence(fences, &index, b_fence);
259 			a_fence = dma_fence_unwrap_next(&a_iter);
260 			b_fence = dma_fence_unwrap_next(&b_iter);
261 		}
262 	}
263 
264 	if (index == 0)
265 		fences[index++] = dma_fence_get_stub();
266 
267 	if (num_fences > index) {
268 		struct dma_fence **tmp;
269 
270 		/* Keep going even when reducing the size failed */
271 		tmp = krealloc_array(fences, index, sizeof(*fences),
272 				     GFP_KERNEL);
273 		if (tmp)
274 			fences = tmp;
275 	}
276 
277 	if (sync_file_set_fence(sync_file, fences, index) < 0)
278 		goto err_put_fences;
279 
280 	strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name));
281 	return sync_file;
282 
283 err_put_fences:
284 	while (index)
285 		dma_fence_put(fences[--index]);
286 	kfree(fences);
287 
288 err_free_sync_file:
289 	fput(sync_file->file);
290 	return NULL;
291 }
292 
293 static int sync_file_release(struct inode *inode, struct file *file)
294 {
295 	struct sync_file *sync_file = file->private_data;
296 
297 	if (test_bit(POLL_ENABLED, &sync_file->flags))
298 		dma_fence_remove_callback(sync_file->fence, &sync_file->cb);
299 	dma_fence_put(sync_file->fence);
300 	kfree(sync_file);
301 
302 	return 0;
303 }
304 
305 static __poll_t sync_file_poll(struct file *file, poll_table *wait)
306 {
307 	struct sync_file *sync_file = file->private_data;
308 
309 	poll_wait(file, &sync_file->wq, wait);
310 
311 	if (list_empty(&sync_file->cb.node) &&
312 	    !test_and_set_bit(POLL_ENABLED, &sync_file->flags)) {
313 		if (dma_fence_add_callback(sync_file->fence, &sync_file->cb,
314 					   fence_check_cb_func) < 0)
315 			wake_up_all(&sync_file->wq);
316 	}
317 
318 	return dma_fence_is_signaled(sync_file->fence) ? EPOLLIN : 0;
319 }
320 
321 static long sync_file_ioctl_merge(struct sync_file *sync_file,
322 				  unsigned long arg)
323 {
324 	int fd = get_unused_fd_flags(O_CLOEXEC);
325 	int err;
326 	struct sync_file *fence2, *fence3;
327 	struct sync_merge_data data;
328 
329 	if (fd < 0)
330 		return fd;
331 
332 	if (copy_from_user(&data, (void __user *)arg, sizeof(data))) {
333 		err = -EFAULT;
334 		goto err_put_fd;
335 	}
336 
337 	if (data.flags || data.pad) {
338 		err = -EINVAL;
339 		goto err_put_fd;
340 	}
341 
342 	fence2 = sync_file_fdget(data.fd2);
343 	if (!fence2) {
344 		err = -ENOENT;
345 		goto err_put_fd;
346 	}
347 
348 	data.name[sizeof(data.name) - 1] = '\0';
349 	fence3 = sync_file_merge(data.name, sync_file, fence2);
350 	if (!fence3) {
351 		err = -ENOMEM;
352 		goto err_put_fence2;
353 	}
354 
355 	data.fence = fd;
356 	if (copy_to_user((void __user *)arg, &data, sizeof(data))) {
357 		err = -EFAULT;
358 		goto err_put_fence3;
359 	}
360 
361 	fd_install(fd, fence3->file);
362 	fput(fence2->file);
363 	return 0;
364 
365 err_put_fence3:
366 	fput(fence3->file);
367 
368 err_put_fence2:
369 	fput(fence2->file);
370 
371 err_put_fd:
372 	put_unused_fd(fd);
373 	return err;
374 }
375 
376 static int sync_fill_fence_info(struct dma_fence *fence,
377 				 struct sync_fence_info *info)
378 {
379 	strlcpy(info->obj_name, fence->ops->get_timeline_name(fence),
380 		sizeof(info->obj_name));
381 	strlcpy(info->driver_name, fence->ops->get_driver_name(fence),
382 		sizeof(info->driver_name));
383 
384 	info->status = dma_fence_get_status(fence);
385 	while (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags) &&
386 	       !test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags))
387 		cpu_relax();
388 	info->timestamp_ns =
389 		test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags) ?
390 		ktime_to_ns(fence->timestamp) :
391 		ktime_set(0, 0);
392 
393 	return info->status;
394 }
395 
396 static long sync_file_ioctl_fence_info(struct sync_file *sync_file,
397 				       unsigned long arg)
398 {
399 	struct sync_fence_info *fence_info = NULL;
400 	struct dma_fence_unwrap iter;
401 	struct sync_file_info info;
402 	unsigned int num_fences;
403 	struct dma_fence *fence;
404 	int ret;
405 	__u32 size;
406 
407 	if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
408 		return -EFAULT;
409 
410 	if (info.flags || info.pad)
411 		return -EINVAL;
412 
413 	num_fences = 0;
414 	dma_fence_unwrap_for_each(fence, &iter, sync_file->fence)
415 		++num_fences;
416 
417 	/*
418 	 * Passing num_fences = 0 means that userspace doesn't want to
419 	 * retrieve any sync_fence_info. If num_fences = 0 we skip filling
420 	 * sync_fence_info and return the actual number of fences on
421 	 * info->num_fences.
422 	 */
423 	if (!info.num_fences) {
424 		info.status = dma_fence_get_status(sync_file->fence);
425 		goto no_fences;
426 	} else {
427 		info.status = 1;
428 	}
429 
430 	if (info.num_fences < num_fences)
431 		return -EINVAL;
432 
433 	size = num_fences * sizeof(*fence_info);
434 	fence_info = kzalloc(size, GFP_KERNEL);
435 	if (!fence_info)
436 		return -ENOMEM;
437 
438 	num_fences = 0;
439 	dma_fence_unwrap_for_each(fence, &iter, sync_file->fence) {
440 		int status;
441 
442 		status = sync_fill_fence_info(fence, &fence_info[num_fences++]);
443 		info.status = info.status <= 0 ? info.status : status;
444 	}
445 
446 	if (copy_to_user(u64_to_user_ptr(info.sync_fence_info), fence_info,
447 			 size)) {
448 		ret = -EFAULT;
449 		goto out;
450 	}
451 
452 no_fences:
453 	sync_file_get_name(sync_file, info.name, sizeof(info.name));
454 	info.num_fences = num_fences;
455 
456 	if (copy_to_user((void __user *)arg, &info, sizeof(info)))
457 		ret = -EFAULT;
458 	else
459 		ret = 0;
460 
461 out:
462 	kfree(fence_info);
463 
464 	return ret;
465 }
466 
467 static long sync_file_ioctl(struct file *file, unsigned int cmd,
468 			    unsigned long arg)
469 {
470 	struct sync_file *sync_file = file->private_data;
471 
472 	switch (cmd) {
473 	case SYNC_IOC_MERGE:
474 		return sync_file_ioctl_merge(sync_file, arg);
475 
476 	case SYNC_IOC_FILE_INFO:
477 		return sync_file_ioctl_fence_info(sync_file, arg);
478 
479 	default:
480 		return -ENOTTY;
481 	}
482 }
483 
484 static const struct file_operations sync_file_fops = {
485 	.release = sync_file_release,
486 	.poll = sync_file_poll,
487 	.unlocked_ioctl = sync_file_ioctl,
488 	.compat_ioctl = compat_ptr_ioctl,
489 };
490