Loading drivers/staging/android/oneshot_sync.c +87 −39 Original line number Diff line number Diff line Loading @@ -206,14 +206,13 @@ static struct sync_timeline_ops oneshot_timeline_ops = { .pt_value_str = oneshot_pt_value_str, }; static int oneshot_open(struct inode *inode, struct file *file) struct oneshot_sync_timeline *oneshot_timeline_create(const char *name) { struct oneshot_sync_timeline *timeline = NULL; char name[32]; char task_comm[TASK_COMM_LEN]; static const char *default_name = "oneshot-timeline"; get_task_comm(task_comm, current); snprintf(name, sizeof(name), "%s-oneshot", task_comm); if (name == NULL) name = default_name; timeline = (struct oneshot_sync_timeline *) sync_timeline_create(&oneshot_timeline_ops, Loading @@ -221,11 +220,35 @@ static int oneshot_open(struct inode *inode, struct file *file) name); if (timeline == NULL) return -ENOMEM; return NULL; INIT_LIST_HEAD(&timeline->state_list); spin_lock_init(&timeline->lock); return timeline; } EXPORT_SYMBOL(oneshot_timeline_create); void oneshot_timeline_destroy(struct oneshot_sync_timeline *timeline) { if (timeline) sync_timeline_destroy(&timeline->obj); } EXPORT_SYMBOL(oneshot_timeline_destroy); static int oneshot_open(struct inode *inode, struct file *file) { struct oneshot_sync_timeline *timeline = NULL; char name[32]; char task_comm[TASK_COMM_LEN]; get_task_comm(task_comm, current); snprintf(name, sizeof(name), "%s-oneshot", task_comm); timeline = oneshot_timeline_create(name); if (timeline == NULL) return -ENOMEM; file->private_data = timeline; return 0; } Loading @@ -233,17 +256,40 @@ static int oneshot_open(struct inode *inode, struct file *file) static int oneshot_release(struct inode *inode, struct file *file) { struct oneshot_sync_timeline *timeline = file->private_data; sync_timeline_destroy(&timeline->obj); oneshot_timeline_destroy(timeline); return 0; } static long oneshot_fence_create(struct oneshot_sync_timeline *timeline, struct sync_fence *oneshot_fence_create(struct oneshot_sync_timeline *timeline, const char *name) { struct sync_fence *fence = NULL; struct oneshot_sync_pt *pt = NULL; pt = oneshot_pt_create(timeline); if (pt == NULL) return NULL; fence = sync_fence_create(name, &pt->sync_pt); if (fence == NULL) { sync_pt_free(&pt->sync_pt); return NULL; } pt->state->orig_fence = fence; return fence; } EXPORT_SYMBOL(oneshot_fence_create); static long oneshot_ioctl_fence_create(struct oneshot_sync_timeline *timeline, unsigned long arg) { struct oneshot_sync_create_fence param; int ret = -ENOMEM; struct sync_fence *fence = NULL; struct oneshot_sync_pt *pt = NULL; int fd = get_unused_fd(); if (fd < 0) Loading @@ -254,15 +300,11 @@ static long oneshot_fence_create(struct oneshot_sync_timeline *timeline, goto out; } pt = oneshot_pt_create(timeline); if (pt == NULL) goto out; fence = sync_fence_create(param.name, &pt->sync_pt); if (fence == NULL) fence = oneshot_fence_create(timeline, param.name); if (fence == NULL) { ret = -ENOMEM; goto out; pt->state->orig_fence = fence; } param.fence_fd = fd; Loading @@ -277,32 +319,20 @@ out: if (ret) { if (fence) sync_fence_put(fence); else if (pt) sync_pt_free(&pt->sync_pt); put_unused_fd(fd); } return ret; } static long oneshot_fence_signal(struct oneshot_sync_timeline *timeline, unsigned long arg) int oneshot_fence_signal(struct oneshot_sync_timeline *timeline, struct sync_fence *fence) { int ret = -EINVAL; int fd = -1; struct sync_fence *fence = NULL; struct oneshot_sync_state *state = NULL; bool signaled = false; if (get_user(fd, (unsigned int __user *)arg)) { ret = -EFAULT; goto out; } fence = sync_fence_fdget(fd); if (fence == NULL) { ret = -EBADF; goto out; } if (timeline == NULL || fence == NULL) return -EINVAL; spin_lock(&timeline->lock); list_for_each_entry(state, &timeline->state_list, node) { Loading @@ -322,13 +352,31 @@ static long oneshot_fence_signal(struct oneshot_sync_timeline *timeline, } spin_unlock(&timeline->lock); if (ret == -EINVAL) pr_debug("fence fd: %d not from this timeline\n", fd); pr_debug("fence: %p not from this timeline\n", fence); if (signaled) sync_timeline_signal(&timeline->obj); out: if (fence) return ret; } EXPORT_SYMBOL(oneshot_fence_signal); static long oneshot_ioctl_fence_signal(struct oneshot_sync_timeline *timeline, unsigned long arg) { int ret = -EINVAL; int fd = -1; struct sync_fence *fence = NULL; if (get_user(fd, (int __user *)arg)) return -EFAULT; fence = sync_fence_fdget(fd); if (fence == NULL) return -EBADF; ret = oneshot_fence_signal(timeline, fence); sync_fence_put(fence); return ret; } Loading @@ -339,10 +387,10 @@ static long oneshot_ioctl(struct file *file, unsigned int cmd, switch (cmd) { case ONESHOT_SYNC_IOC_CREATE_FENCE: return oneshot_fence_create(timeline, arg); return oneshot_ioctl_fence_create(timeline, arg); case ONESHOT_SYNC_IOC_SIGNAL_FENCE: return oneshot_fence_signal(timeline, arg); return oneshot_ioctl_fence_signal(timeline, arg); default: return -ENOTTY; Loading include/linux/oneshot_sync.h +40 −0 Original line number Diff line number Diff line Loading @@ -15,4 +15,44 @@ #include <uapi/linux/oneshot_sync.h> struct oneshot_sync_timeline; struct sync_fence; #ifdef CONFIG_ONESHOT_SYNC struct oneshot_sync_timeline *oneshot_timeline_create(const char *name); void oneshot_timeline_destroy(struct oneshot_sync_timeline *); struct sync_fence *oneshot_fence_create(struct oneshot_sync_timeline *, const char *name); int oneshot_fence_signal(struct oneshot_sync_timeline *, struct sync_fence *); #else static inline struct oneshot_sync_timeline * oneshot_timeline_create(const char *name) { return NULL; } void oneshot_timeline_destroy(struct oneshot_sync_timeline *timeline) { } struct sync_fence *oneshot_fence_create(struct oneshot_sync_timeline *timeline, const char *name) { return NULL; } int oneshot_fence_signal(struct oneshot_sync_timeline *timeline, struct sync_fence *fence) { return -EINVAL; } #endif #endif /* LINUX_ONESHOT_SYNC_H */ Loading
drivers/staging/android/oneshot_sync.c +87 −39 Original line number Diff line number Diff line Loading @@ -206,14 +206,13 @@ static struct sync_timeline_ops oneshot_timeline_ops = { .pt_value_str = oneshot_pt_value_str, }; static int oneshot_open(struct inode *inode, struct file *file) struct oneshot_sync_timeline *oneshot_timeline_create(const char *name) { struct oneshot_sync_timeline *timeline = NULL; char name[32]; char task_comm[TASK_COMM_LEN]; static const char *default_name = "oneshot-timeline"; get_task_comm(task_comm, current); snprintf(name, sizeof(name), "%s-oneshot", task_comm); if (name == NULL) name = default_name; timeline = (struct oneshot_sync_timeline *) sync_timeline_create(&oneshot_timeline_ops, Loading @@ -221,11 +220,35 @@ static int oneshot_open(struct inode *inode, struct file *file) name); if (timeline == NULL) return -ENOMEM; return NULL; INIT_LIST_HEAD(&timeline->state_list); spin_lock_init(&timeline->lock); return timeline; } EXPORT_SYMBOL(oneshot_timeline_create); void oneshot_timeline_destroy(struct oneshot_sync_timeline *timeline) { if (timeline) sync_timeline_destroy(&timeline->obj); } EXPORT_SYMBOL(oneshot_timeline_destroy); static int oneshot_open(struct inode *inode, struct file *file) { struct oneshot_sync_timeline *timeline = NULL; char name[32]; char task_comm[TASK_COMM_LEN]; get_task_comm(task_comm, current); snprintf(name, sizeof(name), "%s-oneshot", task_comm); timeline = oneshot_timeline_create(name); if (timeline == NULL) return -ENOMEM; file->private_data = timeline; return 0; } Loading @@ -233,17 +256,40 @@ static int oneshot_open(struct inode *inode, struct file *file) static int oneshot_release(struct inode *inode, struct file *file) { struct oneshot_sync_timeline *timeline = file->private_data; sync_timeline_destroy(&timeline->obj); oneshot_timeline_destroy(timeline); return 0; } static long oneshot_fence_create(struct oneshot_sync_timeline *timeline, struct sync_fence *oneshot_fence_create(struct oneshot_sync_timeline *timeline, const char *name) { struct sync_fence *fence = NULL; struct oneshot_sync_pt *pt = NULL; pt = oneshot_pt_create(timeline); if (pt == NULL) return NULL; fence = sync_fence_create(name, &pt->sync_pt); if (fence == NULL) { sync_pt_free(&pt->sync_pt); return NULL; } pt->state->orig_fence = fence; return fence; } EXPORT_SYMBOL(oneshot_fence_create); static long oneshot_ioctl_fence_create(struct oneshot_sync_timeline *timeline, unsigned long arg) { struct oneshot_sync_create_fence param; int ret = -ENOMEM; struct sync_fence *fence = NULL; struct oneshot_sync_pt *pt = NULL; int fd = get_unused_fd(); if (fd < 0) Loading @@ -254,15 +300,11 @@ static long oneshot_fence_create(struct oneshot_sync_timeline *timeline, goto out; } pt = oneshot_pt_create(timeline); if (pt == NULL) goto out; fence = sync_fence_create(param.name, &pt->sync_pt); if (fence == NULL) fence = oneshot_fence_create(timeline, param.name); if (fence == NULL) { ret = -ENOMEM; goto out; pt->state->orig_fence = fence; } param.fence_fd = fd; Loading @@ -277,32 +319,20 @@ out: if (ret) { if (fence) sync_fence_put(fence); else if (pt) sync_pt_free(&pt->sync_pt); put_unused_fd(fd); } return ret; } static long oneshot_fence_signal(struct oneshot_sync_timeline *timeline, unsigned long arg) int oneshot_fence_signal(struct oneshot_sync_timeline *timeline, struct sync_fence *fence) { int ret = -EINVAL; int fd = -1; struct sync_fence *fence = NULL; struct oneshot_sync_state *state = NULL; bool signaled = false; if (get_user(fd, (unsigned int __user *)arg)) { ret = -EFAULT; goto out; } fence = sync_fence_fdget(fd); if (fence == NULL) { ret = -EBADF; goto out; } if (timeline == NULL || fence == NULL) return -EINVAL; spin_lock(&timeline->lock); list_for_each_entry(state, &timeline->state_list, node) { Loading @@ -322,13 +352,31 @@ static long oneshot_fence_signal(struct oneshot_sync_timeline *timeline, } spin_unlock(&timeline->lock); if (ret == -EINVAL) pr_debug("fence fd: %d not from this timeline\n", fd); pr_debug("fence: %p not from this timeline\n", fence); if (signaled) sync_timeline_signal(&timeline->obj); out: if (fence) return ret; } EXPORT_SYMBOL(oneshot_fence_signal); static long oneshot_ioctl_fence_signal(struct oneshot_sync_timeline *timeline, unsigned long arg) { int ret = -EINVAL; int fd = -1; struct sync_fence *fence = NULL; if (get_user(fd, (int __user *)arg)) return -EFAULT; fence = sync_fence_fdget(fd); if (fence == NULL) return -EBADF; ret = oneshot_fence_signal(timeline, fence); sync_fence_put(fence); return ret; } Loading @@ -339,10 +387,10 @@ static long oneshot_ioctl(struct file *file, unsigned int cmd, switch (cmd) { case ONESHOT_SYNC_IOC_CREATE_FENCE: return oneshot_fence_create(timeline, arg); return oneshot_ioctl_fence_create(timeline, arg); case ONESHOT_SYNC_IOC_SIGNAL_FENCE: return oneshot_fence_signal(timeline, arg); return oneshot_ioctl_fence_signal(timeline, arg); default: return -ENOTTY; Loading
include/linux/oneshot_sync.h +40 −0 Original line number Diff line number Diff line Loading @@ -15,4 +15,44 @@ #include <uapi/linux/oneshot_sync.h> struct oneshot_sync_timeline; struct sync_fence; #ifdef CONFIG_ONESHOT_SYNC struct oneshot_sync_timeline *oneshot_timeline_create(const char *name); void oneshot_timeline_destroy(struct oneshot_sync_timeline *); struct sync_fence *oneshot_fence_create(struct oneshot_sync_timeline *, const char *name); int oneshot_fence_signal(struct oneshot_sync_timeline *, struct sync_fence *); #else static inline struct oneshot_sync_timeline * oneshot_timeline_create(const char *name) { return NULL; } void oneshot_timeline_destroy(struct oneshot_sync_timeline *timeline) { } struct sync_fence *oneshot_fence_create(struct oneshot_sync_timeline *timeline, const char *name) { return NULL; } int oneshot_fence_signal(struct oneshot_sync_timeline *timeline, struct sync_fence *fence) { return -EINVAL; } #endif #endif /* LINUX_ONESHOT_SYNC_H */