Line data Source code
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 0 : static struct sync_file *sync_file_alloc(void)
24 : {
25 : struct sync_file *sync_file;
26 :
27 0 : sync_file = kzalloc(sizeof(*sync_file), GFP_KERNEL);
28 0 : if (!sync_file)
29 : return NULL;
30 :
31 0 : sync_file->file = anon_inode_getfile("sync_file", &sync_file_fops,
32 : sync_file, 0);
33 0 : if (IS_ERR(sync_file->file))
34 : goto err;
35 :
36 0 : init_waitqueue_head(&sync_file->wq);
37 :
38 0 : INIT_LIST_HEAD(&sync_file->cb.node);
39 :
40 0 : return sync_file;
41 :
42 : err:
43 0 : kfree(sync_file);
44 0 : return NULL;
45 : }
46 :
47 0 : static void fence_check_cb_func(struct dma_fence *f, struct dma_fence_cb *cb)
48 : {
49 : struct sync_file *sync_file;
50 :
51 0 : sync_file = container_of(cb, struct sync_file, cb);
52 :
53 0 : wake_up_all(&sync_file->wq);
54 0 : }
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 0 : struct sync_file *sync_file_create(struct dma_fence *fence)
66 : {
67 : struct sync_file *sync_file;
68 :
69 0 : sync_file = sync_file_alloc();
70 0 : if (!sync_file)
71 : return NULL;
72 :
73 0 : sync_file->fence = dma_fence_get(fence);
74 :
75 0 : return sync_file;
76 : }
77 : EXPORT_SYMBOL(sync_file_create);
78 :
79 0 : static struct sync_file *sync_file_fdget(int fd)
80 : {
81 0 : struct file *file = fget(fd);
82 :
83 0 : if (!file)
84 : return NULL;
85 :
86 0 : if (file->f_op != &sync_file_fops)
87 : goto err;
88 :
89 0 : return file->private_data;
90 :
91 : err:
92 0 : fput(file);
93 0 : 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 0 : struct dma_fence *sync_file_get_fence(int fd)
104 : {
105 : struct sync_file *sync_file;
106 : struct dma_fence *fence;
107 :
108 0 : sync_file = sync_file_fdget(fd);
109 0 : if (!sync_file)
110 : return NULL;
111 :
112 0 : fence = dma_fence_get(sync_file->fence);
113 0 : fput(sync_file->file);
114 :
115 0 : 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 0 : char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len)
133 : {
134 0 : if (sync_file->user_name[0]) {
135 0 : strlcpy(buf, sync_file->user_name, len);
136 : } else {
137 0 : struct dma_fence *fence = sync_file->fence;
138 :
139 0 : snprintf(buf, len, "%s-%s%llu-%lld",
140 0 : fence->ops->get_driver_name(fence),
141 0 : fence->ops->get_timeline_name(fence),
142 : fence->context,
143 : fence->seqno);
144 : }
145 :
146 0 : return buf;
147 : }
148 :
149 0 : 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 :
161 0 : if (num_fences == 0) {
162 0 : sync_file->fence = dma_fence_get_stub();
163 0 : kfree(fences);
164 :
165 0 : } else if (num_fences == 1) {
166 0 : sync_file->fence = fences[0];
167 0 : kfree(fences);
168 :
169 : } else {
170 0 : array = dma_fence_array_create(num_fences, fences,
171 : dma_fence_context_alloc(1),
172 : 1, false);
173 0 : if (!array)
174 : return -ENOMEM;
175 :
176 0 : sync_file->fence = &array->base;
177 : }
178 :
179 : return 0;
180 : }
181 :
182 0 : static void add_fence(struct dma_fence **fences,
183 : int *i, struct dma_fence *fence)
184 : {
185 0 : fences[*i] = fence;
186 :
187 0 : if (!dma_fence_is_signaled(fence)) {
188 0 : dma_fence_get(fence);
189 0 : (*i)++;
190 : }
191 0 : }
192 :
193 : /**
194 : * sync_file_merge() - merge two sync_files
195 : * @name: name of new fence
196 : * @a: sync_file a
197 : * @b: sync_file b
198 : *
199 : * Creates a new sync_file which contains copies of all the fences in both
200 : * @a and @b. @a and @b remain valid, independent sync_file. Returns the
201 : * new merged sync_file or NULL in case of error.
202 : */
203 0 : static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
204 : struct sync_file *b)
205 : {
206 : struct dma_fence *a_fence, *b_fence, **fences;
207 : struct dma_fence_unwrap a_iter, b_iter;
208 : unsigned int index, num_fences;
209 : struct sync_file *sync_file;
210 :
211 0 : sync_file = sync_file_alloc();
212 0 : if (!sync_file)
213 : return NULL;
214 :
215 0 : num_fences = 0;
216 0 : dma_fence_unwrap_for_each(a_fence, &a_iter, a->fence)
217 0 : ++num_fences;
218 0 : dma_fence_unwrap_for_each(b_fence, &b_iter, b->fence)
219 0 : ++num_fences;
220 :
221 0 : if (num_fences > INT_MAX)
222 : goto err_free_sync_file;
223 :
224 0 : fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL);
225 0 : if (!fences)
226 : goto err_free_sync_file;
227 :
228 : /*
229 : * We can't guarantee that fences in both a and b are ordered, but it is
230 : * still quite likely.
231 : *
232 : * So attempt to order the fences as we pass over them and merge fences
233 : * with the same context.
234 : */
235 :
236 0 : index = 0;
237 0 : for (a_fence = dma_fence_unwrap_first(a->fence, &a_iter),
238 0 : b_fence = dma_fence_unwrap_first(b->fence, &b_iter);
239 0 : a_fence || b_fence; ) {
240 :
241 0 : if (!b_fence) {
242 0 : add_fence(fences, &index, a_fence);
243 0 : a_fence = dma_fence_unwrap_next(&a_iter);
244 :
245 0 : } else if (!a_fence) {
246 0 : add_fence(fences, &index, b_fence);
247 0 : b_fence = dma_fence_unwrap_next(&b_iter);
248 :
249 0 : } else if (a_fence->context < b_fence->context) {
250 0 : add_fence(fences, &index, a_fence);
251 0 : a_fence = dma_fence_unwrap_next(&a_iter);
252 :
253 0 : } else if (b_fence->context < a_fence->context) {
254 0 : add_fence(fences, &index, b_fence);
255 0 : b_fence = dma_fence_unwrap_next(&b_iter);
256 :
257 0 : } else if (__dma_fence_is_later(a_fence->seqno, b_fence->seqno,
258 : a_fence->ops)) {
259 0 : add_fence(fences, &index, a_fence);
260 0 : a_fence = dma_fence_unwrap_next(&a_iter);
261 0 : b_fence = dma_fence_unwrap_next(&b_iter);
262 :
263 : } else {
264 0 : add_fence(fences, &index, b_fence);
265 0 : a_fence = dma_fence_unwrap_next(&a_iter);
266 0 : b_fence = dma_fence_unwrap_next(&b_iter);
267 : }
268 : }
269 :
270 0 : if (sync_file_set_fence(sync_file, fences, index) < 0)
271 : goto err_put_fences;
272 :
273 0 : strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name));
274 : return sync_file;
275 :
276 : err_put_fences:
277 0 : while (index)
278 0 : dma_fence_put(fences[--index]);
279 0 : kfree(fences);
280 :
281 : err_free_sync_file:
282 0 : fput(sync_file->file);
283 : return NULL;
284 : }
285 :
286 0 : static int sync_file_release(struct inode *inode, struct file *file)
287 : {
288 0 : struct sync_file *sync_file = file->private_data;
289 :
290 0 : if (test_bit(POLL_ENABLED, &sync_file->flags))
291 0 : dma_fence_remove_callback(sync_file->fence, &sync_file->cb);
292 0 : dma_fence_put(sync_file->fence);
293 0 : kfree(sync_file);
294 :
295 0 : return 0;
296 : }
297 :
298 0 : static __poll_t sync_file_poll(struct file *file, poll_table *wait)
299 : {
300 0 : struct sync_file *sync_file = file->private_data;
301 :
302 0 : poll_wait(file, &sync_file->wq, wait);
303 :
304 0 : if (list_empty(&sync_file->cb.node) &&
305 0 : !test_and_set_bit(POLL_ENABLED, &sync_file->flags)) {
306 0 : if (dma_fence_add_callback(sync_file->fence, &sync_file->cb,
307 : fence_check_cb_func) < 0)
308 0 : wake_up_all(&sync_file->wq);
309 : }
310 :
311 0 : return dma_fence_is_signaled(sync_file->fence) ? EPOLLIN : 0;
312 : }
313 :
314 0 : static long sync_file_ioctl_merge(struct sync_file *sync_file,
315 : unsigned long arg)
316 : {
317 0 : int fd = get_unused_fd_flags(O_CLOEXEC);
318 : int err;
319 : struct sync_file *fence2, *fence3;
320 : struct sync_merge_data data;
321 :
322 0 : if (fd < 0)
323 0 : return fd;
324 :
325 0 : if (copy_from_user(&data, (void __user *)arg, sizeof(data))) {
326 : err = -EFAULT;
327 : goto err_put_fd;
328 : }
329 :
330 0 : if (data.flags || data.pad) {
331 : err = -EINVAL;
332 : goto err_put_fd;
333 : }
334 :
335 0 : fence2 = sync_file_fdget(data.fd2);
336 0 : if (!fence2) {
337 : err = -ENOENT;
338 : goto err_put_fd;
339 : }
340 :
341 0 : data.name[sizeof(data.name) - 1] = '\0';
342 0 : fence3 = sync_file_merge(data.name, sync_file, fence2);
343 0 : if (!fence3) {
344 : err = -ENOMEM;
345 : goto err_put_fence2;
346 : }
347 :
348 0 : data.fence = fd;
349 0 : if (copy_to_user((void __user *)arg, &data, sizeof(data))) {
350 0 : err = -EFAULT;
351 : goto err_put_fence3;
352 : }
353 :
354 0 : fd_install(fd, fence3->file);
355 0 : fput(fence2->file);
356 0 : return 0;
357 :
358 : err_put_fence3:
359 0 : fput(fence3->file);
360 :
361 : err_put_fence2:
362 0 : fput(fence2->file);
363 :
364 : err_put_fd:
365 0 : put_unused_fd(fd);
366 0 : return err;
367 : }
368 :
369 0 : static int sync_fill_fence_info(struct dma_fence *fence,
370 : struct sync_fence_info *info)
371 : {
372 0 : strlcpy(info->obj_name, fence->ops->get_timeline_name(fence),
373 : sizeof(info->obj_name));
374 0 : strlcpy(info->driver_name, fence->ops->get_driver_name(fence),
375 : sizeof(info->driver_name));
376 :
377 0 : info->status = dma_fence_get_status(fence);
378 0 : while (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags) &&
379 0 : !test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags))
380 : cpu_relax();
381 0 : info->timestamp_ns =
382 0 : test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags) ?
383 0 : ktime_to_ns(fence->timestamp) :
384 : ktime_set(0, 0);
385 :
386 0 : return info->status;
387 : }
388 :
389 0 : static long sync_file_ioctl_fence_info(struct sync_file *sync_file,
390 : unsigned long arg)
391 : {
392 0 : struct sync_fence_info *fence_info = NULL;
393 : struct dma_fence_unwrap iter;
394 : struct sync_file_info info;
395 : unsigned int num_fences;
396 : struct dma_fence *fence;
397 : int ret;
398 : __u32 size;
399 :
400 0 : if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
401 : return -EFAULT;
402 :
403 0 : if (info.flags || info.pad)
404 : return -EINVAL;
405 :
406 0 : num_fences = 0;
407 0 : dma_fence_unwrap_for_each(fence, &iter, sync_file->fence)
408 0 : ++num_fences;
409 :
410 : /*
411 : * Passing num_fences = 0 means that userspace doesn't want to
412 : * retrieve any sync_fence_info. If num_fences = 0 we skip filling
413 : * sync_fence_info and return the actual number of fences on
414 : * info->num_fences.
415 : */
416 0 : if (!info.num_fences) {
417 0 : info.status = dma_fence_get_status(sync_file->fence);
418 0 : goto no_fences;
419 : } else {
420 0 : info.status = 1;
421 : }
422 :
423 0 : if (info.num_fences < num_fences)
424 : return -EINVAL;
425 :
426 0 : size = num_fences * sizeof(*fence_info);
427 0 : fence_info = kzalloc(size, GFP_KERNEL);
428 0 : if (!fence_info)
429 : return -ENOMEM;
430 :
431 0 : num_fences = 0;
432 0 : dma_fence_unwrap_for_each(fence, &iter, sync_file->fence) {
433 : int status;
434 :
435 0 : status = sync_fill_fence_info(fence, &fence_info[num_fences++]);
436 0 : info.status = info.status <= 0 ? info.status : status;
437 : }
438 :
439 0 : if (copy_to_user(u64_to_user_ptr(info.sync_fence_info), fence_info,
440 : size)) {
441 : ret = -EFAULT;
442 : goto out;
443 : }
444 :
445 : no_fences:
446 0 : sync_file_get_name(sync_file, info.name, sizeof(info.name));
447 0 : info.num_fences = num_fences;
448 :
449 0 : if (copy_to_user((void __user *)arg, &info, sizeof(info)))
450 : ret = -EFAULT;
451 : else
452 0 : ret = 0;
453 :
454 : out:
455 0 : kfree(fence_info);
456 :
457 0 : return ret;
458 : }
459 :
460 0 : static long sync_file_ioctl(struct file *file, unsigned int cmd,
461 : unsigned long arg)
462 : {
463 0 : struct sync_file *sync_file = file->private_data;
464 :
465 0 : switch (cmd) {
466 : case SYNC_IOC_MERGE:
467 0 : return sync_file_ioctl_merge(sync_file, arg);
468 :
469 : case SYNC_IOC_FILE_INFO:
470 0 : return sync_file_ioctl_fence_info(sync_file, arg);
471 :
472 : default:
473 : return -ENOTTY;
474 : }
475 : }
476 :
477 : static const struct file_operations sync_file_fops = {
478 : .release = sync_file_release,
479 : .poll = sync_file_poll,
480 : .unlocked_ioctl = sync_file_ioctl,
481 : .compat_ioctl = compat_ptr_ioctl,
482 : };
|