1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/dma-buf/sync_file.c
5 * Copyright (C) 2012 Google, Inc.
8 #include <linux/export.h>
9 #include <linux/file.h>
11 #include <linux/kernel.h>
12 #include <linux/poll.h>
13 #include <linux/sched.h>
14 #include <linux/slab.h>
15 #include <linux/uaccess.h>
16 #include <linux/anon_inodes.h>
17 #include <linux/sync_file.h>
18 #include <uapi/linux/sync_file.h>
20 static const struct file_operations sync_file_fops
;
22 static struct sync_file
*sync_file_alloc(void)
24 struct sync_file
*sync_file
;
26 sync_file
= kzalloc(sizeof(*sync_file
), GFP_KERNEL
);
30 sync_file
->file
= anon_inode_getfile("sync_file", &sync_file_fops
,
32 if (IS_ERR(sync_file
->file
))
35 init_waitqueue_head(&sync_file
->wq
);
37 INIT_LIST_HEAD(&sync_file
->cb
.node
);
46 static void fence_check_cb_func(struct dma_fence
*f
, struct dma_fence_cb
*cb
)
48 struct sync_file
*sync_file
;
50 sync_file
= container_of(cb
, struct sync_file
, cb
);
52 wake_up_all(&sync_file
->wq
);
56 * sync_file_create() - creates a sync file
57 * @fence: fence to add to the sync_fence
59 * Creates a sync_file containg @fence. This function acquires and additional
60 * reference of @fence for the newly-created &sync_file, if it succeeds. The
61 * sync_file can be released with fput(sync_file->file). Returns the
62 * sync_file or NULL in case of error.
64 struct sync_file
*sync_file_create(struct dma_fence
*fence
)
66 struct sync_file
*sync_file
;
68 sync_file
= sync_file_alloc();
72 sync_file
->fence
= dma_fence_get(fence
);
76 EXPORT_SYMBOL(sync_file_create
);
78 static struct sync_file
*sync_file_fdget(int fd
)
80 struct file
*file
= fget(fd
);
85 if (file
->f_op
!= &sync_file_fops
)
88 return file
->private_data
;
96 * sync_file_get_fence - get the fence related to the sync_file fd
97 * @fd: sync_file fd to get the fence from
99 * Ensures @fd references a valid sync_file and returns a fence that
100 * represents all fence in the sync_file. On error NULL is returned.
102 struct dma_fence
*sync_file_get_fence(int fd
)
104 struct sync_file
*sync_file
;
105 struct dma_fence
*fence
;
107 sync_file
= sync_file_fdget(fd
);
111 fence
= dma_fence_get(sync_file
->fence
);
112 fput(sync_file
->file
);
116 EXPORT_SYMBOL(sync_file_get_fence
);
119 * sync_file_get_name - get the name of the sync_file
120 * @sync_file: sync_file to get the fence from
121 * @buf: destination buffer to copy sync_file name into
122 * @len: available size of destination buffer.
124 * Each sync_file may have a name assigned either by the user (when merging
125 * sync_files together) or created from the fence it contains. In the latter
126 * case construction of the name is deferred until use, and so requires
127 * sync_file_get_name().
129 * Returns: a string representing the name.
131 char *sync_file_get_name(struct sync_file
*sync_file
, char *buf
, int len
)
133 if (sync_file
->user_name
[0]) {
134 strlcpy(buf
, sync_file
->user_name
, len
);
136 struct dma_fence
*fence
= sync_file
->fence
;
138 snprintf(buf
, len
, "%s-%s%llu-%lld",
139 fence
->ops
->get_driver_name(fence
),
140 fence
->ops
->get_timeline_name(fence
),
148 static int sync_file_set_fence(struct sync_file
*sync_file
,
149 struct dma_fence
**fences
, int num_fences
)
151 struct dma_fence_array
*array
;
154 * The reference for the fences in the new sync_file and held
155 * in add_fence() during the merge procedure, so for num_fences == 1
156 * we already own a new reference to the fence. For num_fence > 1
157 * we own the reference of the dma_fence_array creation.
159 if (num_fences
== 1) {
160 sync_file
->fence
= fences
[0];
163 array
= dma_fence_array_create(num_fences
, fences
,
164 dma_fence_context_alloc(1),
169 sync_file
->fence
= &array
->base
;
175 static struct dma_fence
**get_fences(struct sync_file
*sync_file
,
178 if (dma_fence_is_array(sync_file
->fence
)) {
179 struct dma_fence_array
*array
= to_dma_fence_array(sync_file
->fence
);
181 *num_fences
= array
->num_fences
;
182 return array
->fences
;
186 return &sync_file
->fence
;
189 static void add_fence(struct dma_fence
**fences
,
190 int *i
, struct dma_fence
*fence
)
194 if (!dma_fence_is_signaled(fence
)) {
195 dma_fence_get(fence
);
201 * sync_file_merge() - merge two sync_files
202 * @name: name of new fence
206 * Creates a new sync_file which contains copies of all the fences in both
207 * @a and @b. @a and @b remain valid, independent sync_file. Returns the
208 * new merged sync_file or NULL in case of error.
210 static struct sync_file
*sync_file_merge(const char *name
, struct sync_file
*a
,
213 struct sync_file
*sync_file
;
214 struct dma_fence
**fences
, **nfences
, **a_fences
, **b_fences
;
215 int i
, i_a
, i_b
, num_fences
, a_num_fences
, b_num_fences
;
217 sync_file
= sync_file_alloc();
221 a_fences
= get_fences(a
, &a_num_fences
);
222 b_fences
= get_fences(b
, &b_num_fences
);
223 if (a_num_fences
> INT_MAX
- b_num_fences
)
226 num_fences
= a_num_fences
+ b_num_fences
;
228 fences
= kcalloc(num_fences
, sizeof(*fences
), GFP_KERNEL
);
233 * Assume sync_file a and b are both ordered and have no
234 * duplicates with the same context.
236 * If a sync_file can only be created with sync_file_merge
237 * and sync_file_create, this is a reasonable assumption.
239 for (i
= i_a
= i_b
= 0; i_a
< a_num_fences
&& i_b
< b_num_fences
; ) {
240 struct dma_fence
*pt_a
= a_fences
[i_a
];
241 struct dma_fence
*pt_b
= b_fences
[i_b
];
243 if (pt_a
->context
< pt_b
->context
) {
244 add_fence(fences
, &i
, pt_a
);
247 } else if (pt_a
->context
> pt_b
->context
) {
248 add_fence(fences
, &i
, pt_b
);
252 if (__dma_fence_is_later(pt_a
->seqno
, pt_b
->seqno
,
254 add_fence(fences
, &i
, pt_a
);
256 add_fence(fences
, &i
, pt_b
);
263 for (; i_a
< a_num_fences
; i_a
++)
264 add_fence(fences
, &i
, a_fences
[i_a
]);
266 for (; i_b
< b_num_fences
; i_b
++)
267 add_fence(fences
, &i
, b_fences
[i_b
]);
270 fences
[i
++] = dma_fence_get(a_fences
[0]);
272 if (num_fences
> i
) {
273 nfences
= krealloc(fences
, i
* sizeof(*fences
),
281 if (sync_file_set_fence(sync_file
, fences
, i
) < 0) {
286 strlcpy(sync_file
->user_name
, name
, sizeof(sync_file
->user_name
));
290 fput(sync_file
->file
);
295 static int sync_file_release(struct inode
*inode
, struct file
*file
)
297 struct sync_file
*sync_file
= file
->private_data
;
299 if (test_bit(POLL_ENABLED
, &sync_file
->flags
))
300 dma_fence_remove_callback(sync_file
->fence
, &sync_file
->cb
);
301 dma_fence_put(sync_file
->fence
);
307 static __poll_t
sync_file_poll(struct file
*file
, poll_table
*wait
)
309 struct sync_file
*sync_file
= file
->private_data
;
311 poll_wait(file
, &sync_file
->wq
, wait
);
313 if (list_empty(&sync_file
->cb
.node
) &&
314 !test_and_set_bit(POLL_ENABLED
, &sync_file
->flags
)) {
315 if (dma_fence_add_callback(sync_file
->fence
, &sync_file
->cb
,
316 fence_check_cb_func
) < 0)
317 wake_up_all(&sync_file
->wq
);
320 return dma_fence_is_signaled(sync_file
->fence
) ? EPOLLIN
: 0;
323 static long sync_file_ioctl_merge(struct sync_file
*sync_file
,
326 int fd
= get_unused_fd_flags(O_CLOEXEC
);
328 struct sync_file
*fence2
, *fence3
;
329 struct sync_merge_data data
;
334 if (copy_from_user(&data
, (void __user
*)arg
, sizeof(data
))) {
339 if (data
.flags
|| data
.pad
) {
344 fence2
= sync_file_fdget(data
.fd2
);
350 data
.name
[sizeof(data
.name
) - 1] = '\0';
351 fence3
= sync_file_merge(data
.name
, sync_file
, fence2
);
358 if (copy_to_user((void __user
*)arg
, &data
, sizeof(data
))) {
363 fd_install(fd
, fence3
->file
);
378 static int sync_fill_fence_info(struct dma_fence
*fence
,
379 struct sync_fence_info
*info
)
381 strlcpy(info
->obj_name
, fence
->ops
->get_timeline_name(fence
),
382 sizeof(info
->obj_name
));
383 strlcpy(info
->driver_name
, fence
->ops
->get_driver_name(fence
),
384 sizeof(info
->driver_name
));
386 info
->status
= dma_fence_get_status(fence
);
387 while (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT
, &fence
->flags
) &&
388 !test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT
, &fence
->flags
))
391 test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT
, &fence
->flags
) ?
392 ktime_to_ns(fence
->timestamp
) :
398 static long sync_file_ioctl_fence_info(struct sync_file
*sync_file
,
401 struct sync_file_info info
;
402 struct sync_fence_info
*fence_info
= NULL
;
403 struct dma_fence
**fences
;
405 int num_fences
, ret
, i
;
407 if (copy_from_user(&info
, (void __user
*)arg
, sizeof(info
)))
410 if (info
.flags
|| info
.pad
)
413 fences
= get_fences(sync_file
, &num_fences
);
416 * Passing num_fences = 0 means that userspace doesn't want to
417 * retrieve any sync_fence_info. If num_fences = 0 we skip filling
418 * sync_fence_info and return the actual number of fences on
421 if (!info
.num_fences
) {
422 info
.status
= dma_fence_get_status(sync_file
->fence
);
428 if (info
.num_fences
< num_fences
)
431 size
= num_fences
* sizeof(*fence_info
);
432 fence_info
= kzalloc(size
, GFP_KERNEL
);
436 for (i
= 0; i
< num_fences
; i
++) {
437 int status
= sync_fill_fence_info(fences
[i
], &fence_info
[i
]);
438 info
.status
= info
.status
<= 0 ? info
.status
: status
;
441 if (copy_to_user(u64_to_user_ptr(info
.sync_fence_info
), fence_info
,
448 sync_file_get_name(sync_file
, info
.name
, sizeof(info
.name
));
449 info
.num_fences
= num_fences
;
451 if (copy_to_user((void __user
*)arg
, &info
, sizeof(info
)))
462 static long sync_file_ioctl(struct file
*file
, unsigned int cmd
,
465 struct sync_file
*sync_file
= file
->private_data
;
469 return sync_file_ioctl_merge(sync_file
, arg
);
471 case SYNC_IOC_FILE_INFO
:
472 return sync_file_ioctl_fence_info(sync_file
, arg
);
479 static const struct file_operations sync_file_fops
= {
480 .release
= sync_file_release
,
481 .poll
= sync_file_poll
,
482 .unlocked_ioctl
= sync_file_ioctl
,
483 .compat_ioctl
= compat_ptr_ioctl
,