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