static struct sync_fence *adf_sw_complete_fence(struct adf_device *dev) { struct sync_pt *pt; struct sync_fence *complete_fence; if (!dev->timeline) { dev->timeline = sw_sync_timeline_create(dev->base.name); if (!dev->timeline) return ERR_PTR(-ENOMEM); dev->timeline_max = 1; } dev->timeline_max++; pt = sw_sync_pt_create(dev->timeline, dev->timeline_max); if (!pt) goto err_pt_create; complete_fence = sync_fence_create(dev->base.name, pt); if (!complete_fence) goto err_fence_create; return complete_fence; err_fence_create: sync_pt_free(pt); err_pt_create: dev->timeline_max--; return ERR_PTR(-ENOSYS); }
int k3fb_buf_sync_create_fence(struct k3_fb_data_type *k3fd, unsigned value) { int fd = -1; struct sync_fence *fence = NULL; struct sync_pt *pt = NULL; BUG_ON(k3fd == NULL); fd = get_unused_fd(); if (fd < 0) { K3_FB_ERR("get_unused_fd failed!\n"); return fd; } pt = sw_sync_pt_create(k3fd->buf_sync_ctrl.timeline, value); if (pt == NULL) { return -ENOMEM; } fence = sync_fence_create(BUF_SYNC_FENCE_NAME, pt); if (fence == NULL) { sync_pt_free(pt); return -ENOMEM; } sync_fence_install(fence, fd); return fd; }
int fence_create(struct sw_sync_timeline *obj, struct fence_data *data) { int fd = get_unused_fd(); int err; struct sync_pt *pt; struct sync_fence *fence; if (fd < 0) return fd; pt = sw_sync_pt_create(obj, data->value); if (pt == NULL) { err = -ENOMEM; goto err; } data->name[sizeof(data->name) - 1] = '\0'; fence = sync_fence_create(data->name, pt); if (fence == NULL) { sync_pt_free(pt); err = -ENOMEM; goto err; } data->fence = fd; sync_fence_install(fence, fd); return 0; err: put_unused_fd(fd); return err; }
int mali_stream_create_fence(mali_sync_pt *pt) { struct sync_fence *fence; struct fdtable * fdt; struct files_struct * files; int fd = -1; fence = sync_fence_create("mali_fence", pt); if (!fence) { sync_pt_free(pt); fd = -EFAULT; goto out; } /* create a fd representing the fence */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) fd = get_unused_fd_flags(O_CLOEXEC); if (fd < 0) { sync_fence_put(fence); goto out; } #else fd = get_unused_fd(); if (fd < 0) { sync_fence_put(fence); goto out; } files = current->files; spin_lock(&files->file_lock); fdt = files_fdtable(files); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) __set_close_on_exec(fd, fdt); #else FD_SET(fd, fdt->close_on_exec); #endif spin_unlock(&files->file_lock); #endif /* Linux > 3.6 */ /* bind fence to the new fd */ sync_fence_install(fence, fd); out: return fd; }
static long sw_sync_ioctl_create_fence(struct sw_sync_timeline *obj, unsigned long arg) { int fd = get_unused_fd_flags(O_CLOEXEC); int err; struct sync_pt *pt; struct sync_fence *fence; struct sw_sync_create_fence_data data; if (fd < 0) return fd; if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { err = -EFAULT; goto err; } pt = sw_sync_pt_create(obj, data.value); if (pt == NULL) { err = -ENOMEM; goto err; } data.name[sizeof(data.name) - 1] = '\0'; fence = sync_fence_create(data.name, pt); if (fence == NULL) { sync_pt_free(pt); err = -ENOMEM; goto err; } data.fence = fd; if (copy_to_user((void __user *)arg, &data, sizeof(data))) { sync_fence_put(fence); err = -EFAULT; goto err; } sync_fence_install(fence, fd); return 0; err: put_unused_fd(fd); return err; }
int i915_sync_finish_request(void *handle, struct drm_i915_gem_execbuffer2 *args, struct intel_ring_buffer *ring) { struct sync_pt *pt = (struct sync_pt *)handle; int err; int fd = -1; struct sync_fence *fence; /* Clear the active seqno. */ if (i915_write_active_seqno(ring, 0)) DRM_DEBUG_DRIVER("Failed to clear seqno for %d\n", ring->id); /* Fence was not requested, nothing more to do. */ if (!pt) return 0; fd = get_unused_fd(); if (fd < 0) { DRM_DEBUG_DRIVER("Unable to get file descriptor for fence\n"); err = fd; goto err; } fence = sync_fence_create("I915", pt); if (!fence) { DRM_DEBUG_DRIVER("Fence creation failed\n"); err = -ENOMEM; goto err_fd; } sync_fence_install(fence, fd); /* Return the fence through the rsvd2 field */ args->rsvd2 = (__u64)fd; return 0; err_fd: put_unused_fd(fd); fd = err; err: args->rsvd2 = (__u64)fd; return err; }
/** * _sde_fence_create_fd - create fence object and return an fd for it * This function is NOT thread-safe. * @timeline: Timeline to associate with fence * @name: Name for fence * @val: Timeline value at which to signal the fence * Return: File descriptor on success, or error code on error */ static int _sde_fence_create_fd(void *timeline, const char *name, uint32_t val) { struct sync_pt *sync_pt; struct sync_fence *fence; signed int fd = -EINVAL; if (!timeline) { SDE_ERROR("invalid timeline\n"); goto exit; } if (!name) name = "sde_fence"; /* create sync point */ sync_pt = sw_sync_pt_create(timeline, val); if (sync_pt == NULL) { SDE_ERROR("failed to create sync point, %s\n", name); goto exit; } /* create fence */ fence = sync_fence_create(name, sync_pt); if (fence == NULL) { sync_pt_free(sync_pt); SDE_ERROR("couldn't create fence, %s\n", name); goto exit; } /* create fd */ fd = get_unused_fd_flags(0); if (fd < 0) { SDE_ERROR("failed to get_unused_fd_flags(), %s\n", name); sync_fence_put(fence); goto exit; } sync_fence_install(fence, fd); exit: return fd; }
STATIC int balong_ade_overlay_fence_create(struct sw_sync_timeline * timeline, const char * fence_name, unsigned value) { int fd; struct sync_fence *fence; struct sync_pt *pt; if (timeline == NULL){ return -EINVAL; } fd = get_unused_fd(); if (fd < 0) { balongfb_loge("failed to get fd in create fence!\n"); return fd; } pt = sw_sync_pt_create(timeline, value); if (pt == NULL) { put_unused_fd(fd); balongfb_loge("failed to create pt in create fence!\n"); return -ENOMEM; } fence = sync_fence_create(fence_name, pt); if (fence == NULL) { sync_pt_free(pt); put_unused_fd(fd); balongfb_loge("failed to create fence in create fence!\n"); return -ENOMEM; } sync_fence_install(fence, fd); return fd; }
int kbase_stream_create_fence(int tl_fd) { struct sync_timeline *tl; struct sync_pt *pt; struct sync_fence *fence; #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0) struct files_struct *files; struct fdtable *fdt; #endif int fd; struct file *tl_file; tl_file = fget(tl_fd); if (tl_file == NULL) return -EBADF; if (tl_file->f_op != &stream_fops) { fd = -EBADF; goto out; } tl = tl_file->private_data; pt = kbase_sync_pt_alloc(tl); if (!pt) { fd = -EFAULT; goto out; } fence = sync_fence_create("mali_fence", pt); if (!fence) { sync_pt_free(pt); fd = -EFAULT; goto out; } /* from here the fence owns the sync_pt */ /* create a fd representing the fence */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0) fd = get_unused_fd_flags(O_RDWR | O_CLOEXEC); if (fd < 0) { sync_fence_put(fence); goto out; } #else fd = get_unused_fd(); if (fd < 0) { sync_fence_put(fence); goto out; } files = current->files; spin_lock(&files->file_lock); fdt = files_fdtable(files); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) __set_close_on_exec(fd, fdt); #else FD_SET(fd, fdt->close_on_exec); #endif spin_unlock(&files->file_lock); #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0) */ /* bind fence to the new fd */ sync_fence_install(fence, fd); out: fput(tl_file); return fd; }
int kgsl_add_fence_event(struct kgsl_device *device, u32 context_id, u32 timestamp, void __user *data, int len, struct kgsl_device_private *owner) { struct kgsl_fence_event_priv *event; struct kgsl_timestamp_event_fence priv; struct kgsl_context *context; struct sync_pt *pt; struct sync_fence *fence = NULL; int ret = -EINVAL; if (len != sizeof(priv)) return -EINVAL; context = kgsl_find_context(owner, context_id); if (context == NULL) return -EINVAL; event = kzalloc(sizeof(*event), GFP_KERNEL); if (event == NULL) return -ENOMEM; event->context = context; event->timestamp = timestamp; kgsl_context_get(context); pt = kgsl_sync_pt_create(context->timeline, timestamp); if (pt == NULL) { KGSL_DRV_ERR(device, "kgsl_sync_pt_create failed\n"); ret = -ENOMEM; goto fail_pt; } fence = sync_fence_create("kgsl-fence", pt); if (fence == NULL) { /* only destroy pt when not added to fence */ kgsl_sync_pt_destroy(pt); KGSL_DRV_ERR(device, "sync_fence_create failed\n"); ret = -ENOMEM; goto fail_fence; } priv.fence_fd = get_unused_fd_flags(0); if (priv.fence_fd < 0) { KGSL_DRV_ERR(device, "invalid fence fd\n"); ret = -EINVAL; goto fail_fd; } sync_fence_install(fence, priv.fence_fd); if (copy_to_user(data, &priv, sizeof(priv))) { ret = -EFAULT; goto fail_copy_fd; } ret = kgsl_add_event(device, context_id, timestamp, kgsl_fence_event_cb, event, owner); if (ret) goto fail_event; return 0; fail_event: fail_copy_fd: /* clean up sync_fence_install */ put_unused_fd(priv.fence_fd); fail_fd: /* clean up sync_fence_create */ sync_fence_put(fence); fail_fence: fail_pt: kgsl_context_put(context); kfree(event); return ret; }
int kgsl_add_fence_event(struct kgsl_device *device, u32 context_id, u32 timestamp, void __user *data, int len, struct kgsl_device_private *owner) { struct kgsl_fence_event_priv *event; struct kgsl_timestamp_event_fence priv; struct kgsl_context *context; struct sync_pt *pt; struct sync_fence *fence = NULL; int ret = -EINVAL; char fence_name[sizeof(fence->name)] = {}; priv.fence_fd = -1; if (len != sizeof(priv)) return -EINVAL; event = kzalloc(sizeof(*event), GFP_KERNEL); if (event == NULL) return -ENOMEM; kgsl_mutex_lock(&device->mutex, &device->mutex_owner); context = kgsl_context_get_owner(owner, context_id); if (context == NULL) goto unlock; event->context = context; event->timestamp = timestamp; pt = kgsl_sync_pt_create(context->timeline, timestamp); if (pt == NULL) { KGSL_DRV_ERR(device, "kgsl_sync_pt_create failed\n"); ret = -ENOMEM; goto unlock; } snprintf(fence_name, sizeof(fence_name), "%s-pid-%d-ctx-%d-ts-%d", device->name, current->group_leader->pid, context_id, timestamp); fence = sync_fence_create(fence_name, pt); if (fence == NULL) { /* only destroy pt when not added to fence */ kgsl_sync_pt_destroy(pt); KGSL_DRV_ERR(device, "sync_fence_create failed\n"); ret = -ENOMEM; goto unlock; } priv.fence_fd = get_unused_fd_flags(0); if (priv.fence_fd < 0) { KGSL_DRV_ERR(device, "Unable to get a file descriptor: %d\n", priv.fence_fd); ret = priv.fence_fd; goto unlock; } /* Unlock the mutex before copying to user */ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner); if (copy_to_user(data, &priv, sizeof(priv))) { ret = -EFAULT; goto out; } /* * Hold the context ref-count for the event - it will get released in * the callback */ ret = kgsl_add_event(device, &context->events, timestamp, kgsl_fence_event_cb, event); if (ret) goto out; sync_fence_install(fence, priv.fence_fd); return 0; unlock: kgsl_mutex_unlock(&device->mutex, &device->mutex_owner); out: if (priv.fence_fd >= 0) put_unused_fd(priv.fence_fd); if (fence) sync_fence_put(fence); kgsl_context_put(context); kfree(event); return ret; }
int sprd_fence_create(struct ion_fence_data *data, char *name) { int fd = get_unused_fd(); struct sync_pt *pt; struct sync_fence *fence; struct sync_timeline_data *parent = NULL; if (data == NULL || name == NULL) { printk(KERN_ERR "sprd_fence_create input para is NULL\n"); return -EFAULT; } if (fd < 0) { fd = get_unused_fd(); if (fd < 0) { printk(KERN_ERR "sprd_sync_pt_create failed to get fd\n"); } return -EFAULT; } if (data->device_type == SPRD_DEVICE_PRIMARY_SYNC) { parent = &sprd_timeline; } else if (data->device_type == SPRD_DEVICE_VIRTUAL_SYNC) { parent = &sprd_timeline_virtual; } if (parent == NULL) { printk(KERN_ERR "sprd_fence_create failed to get sync timeline\n"); return -EFAULT; } mutex_lock(&(parent->sync_mutex)); pt = sprd_sync_pt_create(parent->timeline, parent->timeline_value + data->life_value); if (pt == NULL) { printk(KERN_ERR "sprd_sync_pt_create failed\n"); goto err; } fence = sync_fence_create(name, pt); if (fence == NULL) { sync_pt_free(pt); printk(KERN_ERR "sprd_create_fence failed\n"); goto err; } sync_fence_install(fence, fd); mutex_unlock(&(parent->sync_mutex)); pr_debug("create a fence: %p, fd: %d, life_value: %d, name: %s\n", (void *)fence, fd, data->life_value, name); return fd; err: put_unused_fd(fd); mutex_unlock(&(parent->sync_mutex)); return -ENOMEM; }
int kgsl_add_fence_event(struct kgsl_device *device, u32 context_id, u32 timestamp, void __user *data, int len, struct kgsl_device_private *owner) { struct kgsl_timestamp_event_fence priv; struct kgsl_context *context; struct sync_pt *pt; struct sync_fence *fence = NULL; int ret = -EINVAL; char fence_name[sizeof(fence->name)] = {}; unsigned int cur; priv.fence_fd = -1; if (len != sizeof(priv)) return -EINVAL; kgsl_mutex_lock(&device->mutex, &device->mutex_owner); context = kgsl_context_get_owner(owner, context_id); if (context == NULL) goto unlock; pt = kgsl_sync_pt_create(context->timeline, context, timestamp); if (pt == NULL) { KGSL_DRV_ERR(device, "kgsl_sync_pt_create failed\n"); ret = -ENOMEM; goto unlock; } snprintf(fence_name, sizeof(fence_name), "%s-pid-%d-ctx-%d-ts-%d", device->name, current->group_leader->pid, context_id, timestamp); fence = sync_fence_create(fence_name, pt); if (fence == NULL) { /* only destroy pt when not added to fence */ kgsl_sync_pt_destroy(pt); KGSL_DRV_ERR(device, "sync_fence_create failed\n"); ret = -ENOMEM; goto unlock; } priv.fence_fd = get_unused_fd_flags(0); if (priv.fence_fd < 0) { KGSL_DRV_ERR(device, "Unable to get a file descriptor: %d\n", priv.fence_fd); ret = priv.fence_fd; goto unlock; } sync_fence_install(fence, priv.fence_fd); /* * If the timestamp hasn't expired yet create an event to trigger it. * Otherwise, just signal the fence - there is no reason to go through * the effort of creating a fence we don't need. */ cur = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED); if (timestamp_cmp(cur, timestamp) >= 0) kgsl_sync_timeline_signal(context->timeline, cur); else { ret = _add_fence_event(device, context, timestamp); if (ret) goto unlock; } kgsl_context_put(context); /* Unlock the mutex before copying to user */ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner); if (copy_to_user(data, &priv, sizeof(priv))) { ret = -EFAULT; goto out; } return 0; unlock: kgsl_mutex_unlock(&device->mutex, &device->mutex_owner); out: if (priv.fence_fd >= 0) put_unused_fd(priv.fence_fd); if (fence) sync_fence_put(fence); kgsl_context_put(context); return ret; }