mali_error kbase_prepare_soft_job(kbase_jd_atom *katom ) { switch(katom->core_req) { case BASE_JD_REQ_SOFT_DUMP_CPU_GPU_TIME: /* Nothing to do */ break; #ifdef CONFIG_SYNC case BASE_JD_REQ_SOFT_FENCE_TRIGGER: { base_fence fence; int fd; if (MALI_ERROR_NONE != ukk_copy_from_user(sizeof(fence), &fence, (__user void*)(uintptr_t)katom->jc)) { return MALI_ERROR_FUNCTION_FAILED; } fd = kbase_stream_create_fence(fence.basep.stream_fd); if (fd < 0) { return MALI_ERROR_FUNCTION_FAILED; } katom->fence = sync_fence_fdget(fd); if (katom->fence == NULL) { /* The only way the fence can be NULL is if userspace closed it for us. * So we don't need to clear it up */ return MALI_ERROR_FUNCTION_FAILED; } fence.basep.fd = fd; if (MALI_ERROR_NONE != ukk_copy_to_user(sizeof(fence), (__user void*)(uintptr_t)katom->jc, &fence)) { katom->fence = NULL; sys_close(fd); return MALI_ERROR_FUNCTION_FAILED; } } break; case BASE_JD_REQ_SOFT_FENCE_WAIT: { base_fence fence; if (MALI_ERROR_NONE != ukk_copy_from_user(sizeof(fence), &fence, (__user void*)(uintptr_t)katom->jc)) { return MALI_ERROR_FUNCTION_FAILED; } /* Get a reference to the fence object */ katom->fence = sync_fence_fdget(fence.basep.fd); if (katom->fence == NULL) { return MALI_ERROR_FUNCTION_FAILED; } } break; #endif /* CONFIG_SYNC */ default: /* Unsupported soft-job */ return MALI_ERROR_FUNCTION_FAILED; } return MALI_ERROR_NONE; }
int sprd_fence_destroy(struct ion_fence_data *data) { if (data == NULL) { printk(KERN_ERR "sprd_fence_destroy parameters NULL\n"); return -EFAULT; } if (data->release_fence_fd >= 0) { struct sync_fence *fence = sync_fence_fdget(data->release_fence_fd); if (fence == NULL) { printk(KERN_ERR "sprd_fence_destroy failed fence == NULL\n"); return -EFAULT; } } else if (data->retired_fence_fd >= 0) { struct sync_fence *fence = sync_fence_fdget(data->retired_fence_fd); if (fence == NULL) { printk(KERN_ERR "sprd_fence_destroy failed fence == NULL\n"); } return -EFAULT; } return 0; }
int sprd_fence_wait(int fence_fd) { int ret = 0; struct sync_fence *fence = NULL; if (fence_fd < 0) { printk(KERN_ERR "sprd_wait_fence input parameters is NULL\n"); return -EFAULT; } fence = sync_fence_fdget(fence_fd); if (fence == NULL) { printk(KERN_ERR "sprd_fence_wait failed fence == NULL\n"); return -EFAULT; } ret = sync_fence_wait(fence, WAIT_FENCE_TIMEOUT); sync_fence_put(fence); if (ret < 0) { printk(KERN_ERR "sync_fence_wait failed, ret = %x\n", ret); } pr_debug("sprd_wait_fence wait fence: %p done\n", (void *)fence); return ret; }
GED_ERROR ged_monitor_3D_fence_add(int fence_fd) { int err; GED_MONITOR_3D_FENCE* psMonitor; psMonitor = (GED_MONITOR_3D_FENCE*)ged_alloc(sizeof(GED_MONITOR_3D_FENCE)); if (!psMonitor) { return GED_ERROR_OOM; } sync_fence_waiter_init(&psMonitor->sSyncWaiter, ged_sync_cb); INIT_WORK(&psMonitor->sWork, ged_monitor_3D_fence_work_cb); psMonitor->psSyncFence = sync_fence_fdget(fence_fd); if (NULL == psMonitor->psSyncFence) { ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE)); return GED_ERROR_INVALID_PARAMS; } err = sync_fence_wait_async(psMonitor->psSyncFence, &psMonitor->sSyncWaiter); if ((1 == err) || (0 > err)) { sync_fence_put(psMonitor->psSyncFence); ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE)); } else if (0 == err) { int iCount = atomic_add_return(1, &g_i32Count); if (iCount > 1) { if (0 == ged_monitor_3D_fence_disable) { //unsigned int uiFreqLevelID; //if (mtk_get_bottom_gpu_freq(&uiFreqLevelID)) { //if (uiFreqLevelID != 4) { #ifdef CONFIG_GPU_TRACEPOINTS if (ged_monitor_3D_fence_systrace) { unsigned long long t = cpu_clock(smp_processor_id()); trace_gpu_sched_switch("Smart Boost", t, 1, 0, 1); } #endif mtk_set_bottom_gpu_freq(4); } } } } } if (ged_monitor_3D_fence_debug > 0) { GED_LOGI("[+]3D fences count = %d\n", atomic_read(&g_i32Count)); } return GED_OK; }
int fence_merge(char *const name, int fd1, int fd2) { int fd = get_unused_fd(); int err; struct sync_fence *fence1, *fence2, *fence3; if (fd < 0) return fd; fence1 = sync_fence_fdget(fd1); if (NULL == fence1) { err = -ENOENT; goto err_put_fd; } fence2 = sync_fence_fdget(fd2); if (NULL == fence2) { err = -ENOENT; goto err_put_fence1; } name[sizeof(name) - 1] = '\0'; fence3 = sync_fence_merge(name, fence1, fence2); if (fence3 == NULL) { err = -ENOMEM; goto err_put_fence2; } sync_fence_install(fence3, fd); sync_fence_put(fence2); sync_fence_put(fence1); return fd; err_put_fence2: sync_fence_put(fence2); err_put_fence1: sync_fence_put(fence1); err_put_fd: put_unused_fd(fd); return err; }
int kbase_fence_validate(int fd) { struct sync_fence *fence; fence = sync_fence_fdget(fd); if (!fence) return -EINVAL; sync_fence_put(fence); return 0; }
GED_ERROR ged_monitor_3D_fence_add(int fence_fd) { int err; GED_MONITOR_3D_FENCE* psMonitor = (GED_MONITOR_3D_FENCE*)ged_alloc(sizeof(GED_MONITOR_3D_FENCE)); #ifdef GED_DEBUG_MONITOR_3D_FENCE ged_log_buf_print(ghLogBuf_GED, "[+]ged_monitor_3D_fence_add"); #endif if (!psMonitor) { return GED_ERROR_OOM; } sync_fence_waiter_init(&psMonitor->sSyncWaiter, ged_sync_cb); INIT_WORK(&psMonitor->sWork, ged_monitor_3D_fence_work_cb); psMonitor->psSyncFence = sync_fence_fdget(fence_fd); if (NULL == psMonitor->psSyncFence) { ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE)); return GED_ERROR_INVALID_PARAMS; } #ifdef GED_DEBUG_MONITOR_3D_FENCE ged_log_buf_print(ghLogBuf_GED, "[+]sync_fence_wait_async"); #endif err = sync_fence_wait_async(psMonitor->psSyncFence, &psMonitor->sSyncWaiter); #ifdef GED_DEBUG_MONITOR_3D_FENCE ged_log_buf_print(ghLogBuf_GED, "[-]sync_fence_wait_async, err = %d", err); #endif if ((1 == err) || (0 > err)) { sync_fence_put(psMonitor->psSyncFence); ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE)); } else if (0 == err) { int iCount = atomic_add_return (1, &g_i32Count); if (iCount > 1) { //mtk_set_bottom_gpu_freq(iCount + 1); mtk_set_bottom_gpu_freq(4); } } #ifdef GED_DEBUG_MONITOR_3D_FENCE ged_log_buf_print(ghLogBuf_GED, "[-]ged_monitor_3D_fence_add, count = %d", atomic_read(&g_i32Count)); #endif return GED_OK; }
mali_error kbase_fence_validate(int fd) { struct sync_fence *fence; fence = sync_fence_fdget(fd); if (NULL != fence) { sync_fence_put(fence); return MALI_ERROR_NONE; } else { return MALI_ERROR_FUNCTION_FAILED; } }
_mali_osk_errcode_t mali_fence_validate(int fd) { struct sync_fence * fence; fence = sync_fence_fdget(fd); if (NULL != fence) { sync_fence_put(fence); return _MALI_OSK_ERR_OK; } else { return _MALI_OSK_ERR_FAULT; } }
struct kgsl_sync_fence_waiter *kgsl_sync_fence_async_wait(int fd, void (*func)(void *priv), void *priv) { struct kgsl_sync_fence_waiter *kwaiter; struct sync_fence *fence; int status; fence = sync_fence_fdget(fd); if (fence == NULL) return ERR_PTR(-EINVAL); /* create the waiter */ kwaiter = kzalloc(sizeof(*kwaiter), GFP_ATOMIC); if (kwaiter == NULL) { sync_fence_put(fence); return ERR_PTR(-ENOMEM); } kwaiter->fence = fence; kwaiter->priv = priv; kwaiter->func = func; strlcpy(kwaiter->name, fence->name, sizeof(kwaiter->name)); sync_fence_waiter_init((struct sync_fence_waiter *) kwaiter, kgsl_sync_callback); /* if status then error or signaled */ status = sync_fence_wait_async(fence, (struct sync_fence_waiter *) kwaiter); if (status) { kfree(kwaiter); sync_fence_put(fence); if (status < 0) kwaiter = ERR_PTR(status); else kwaiter = NULL; } return kwaiter; }
int k3fb_buf_sync_wait(int fence_fd) { int ret = 0; struct sync_fence *fence = NULL; fence = sync_fence_fdget(fence_fd); if (fence == NULL){ K3_FB_ERR("sync_fence_fdget failed!\n"); return -EINVAL; } ret = sync_fence_wait(fence, BUF_SYNC_TIMEOUT_MSEC); if (ret == -ETIME) ret = sync_fence_wait(fence, BUF_SYNC_TIMEOUT_MSEC); if (ret < 0) K3_FB_WARNING("error waiting on fence: 0x%x\n", ret); sync_fence_put(fence); return ret; }
s32 mali_timeline_sync_fence_create(struct mali_timeline_system *system, struct mali_timeline_fence *fence) { u32 i; struct sync_fence *sync_fence_acc = NULL; MALI_DEBUG_ASSERT_POINTER(system); MALI_DEBUG_ASSERT_POINTER(fence); for (i = 0; i < MALI_TIMELINE_MAX; ++i) { struct mali_timeline *timeline; struct sync_fence *sync_fence; if (MALI_TIMELINE_NO_POINT == fence->points[i]) continue; timeline = system->timelines[i]; MALI_DEBUG_ASSERT_POINTER(timeline); sync_fence = mali_timeline_sync_fence_create_and_add_tracker(timeline, fence->points[i]); if (NULL == sync_fence) goto error; if (NULL != sync_fence_acc) { /* Merge sync fences. */ sync_fence_acc = mali_sync_fence_merge(sync_fence_acc, sync_fence); if (NULL == sync_fence_acc) goto error; } else { /* This was the first sync fence created. */ sync_fence_acc = sync_fence; } } if (-1 != fence->sync_fd) { struct sync_fence *sync_fence; sync_fence = sync_fence_fdget(fence->sync_fd); if (NULL == sync_fence) goto error; if (NULL != sync_fence_acc) { sync_fence_acc = mali_sync_fence_merge(sync_fence_acc, sync_fence); if (NULL == sync_fence_acc) goto error; } else { sync_fence_acc = sync_fence; } } if (NULL == sync_fence_acc) { MALI_DEBUG_ASSERT_POINTER(system->signaled_sync_tl); /* There was nothing to wait on, so return an already signaled fence. */ sync_fence_acc = mali_sync_timeline_create_signaled_fence(system->signaled_sync_tl); if (NULL == sync_fence_acc) goto error; } /* Return file descriptor for the accumulated sync fence. */ return mali_sync_fence_fd_alloc(sync_fence_acc); error: if (NULL != sync_fence_acc) { sync_fence_put(sync_fence_acc); } return -1; }
void *sde_sync_get(uint64_t fd) { /* force signed compare, fdget accepts an int argument */ return (signed int)fd >= 0 ? sync_fence_fdget(fd) : NULL; }
/** * Check if fence has been signaled. * * @param system Timeline system. * @param fence Timeline fence. * @return MALI_TRUE if fence is signaled, MALI_FALSE if not. */ static mali_bool mali_timeline_fence_wait_check_status(struct mali_timeline_system *system, struct mali_timeline_fence *fence) { int i; u32 tid = _mali_osk_get_tid(); mali_bool ret = MALI_TRUE; #if defined(CONFIG_SYNC) struct sync_fence *sync_fence = NULL; #endif MALI_DEBUG_ASSERT_POINTER(system); MALI_DEBUG_ASSERT_POINTER(fence); mali_spinlock_reentrant_wait(system->spinlock, tid); for (i = 0; i < MALI_TIMELINE_MAX; ++i) { struct mali_timeline *timeline; mali_timeline_point point; point = fence->points[i]; if (likely(MALI_TIMELINE_NO_POINT == point)) { /* Fence contains no point on this timeline. */ continue; } timeline = system->timelines[i]; MALI_DEBUG_ASSERT_POINTER(timeline); if (unlikely(!mali_timeline_is_point_valid(timeline, point))) { MALI_PRINT_ERROR(("Mali Timeline: point %d is not valid (oldest=%d, next=%d)\n", point, timeline->point_oldest, timeline->point_next)); } if (!mali_timeline_is_point_released(timeline, point)) { ret = MALI_FALSE; goto exit; } } #if defined(CONFIG_SYNC) if (-1 != fence->sync_fd) { sync_fence = sync_fence_fdget(fence->sync_fd); if (likely(NULL != sync_fence)) { #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) if (0 == sync_fence->status) { #else if (0 == atomic_read(&sync_fence->status)) { #endif ret = MALI_FALSE; } } else { MALI_PRINT_ERROR(("Mali Timeline: failed to get sync fence from fd %d\n", fence->sync_fd)); } } #endif /* defined(CONFIG_SYNC) */ exit: mali_spinlock_reentrant_signal(system->spinlock, tid); #if defined(CONFIG_SYNC) if (NULL != sync_fence) { sync_fence_put(sync_fence); } #endif /* defined(CONFIG_SYNC) */ return ret; } mali_bool mali_timeline_fence_wait(struct mali_timeline_system *system, struct mali_timeline_fence *fence, u32 timeout) { struct mali_timeline_fence_wait_tracker *wait; mali_timeline_point point; mali_bool ret; MALI_DEBUG_ASSERT_POINTER(system); MALI_DEBUG_ASSERT_POINTER(fence); MALI_DEBUG_PRINT(4, ("Mali Timeline: wait on fence\n")); if (MALI_TIMELINE_FENCE_WAIT_TIMEOUT_IMMEDIATELY == timeout) { return mali_timeline_fence_wait_check_status(system, fence); } wait = mali_timeline_fence_wait_tracker_alloc(); if (unlikely(NULL == wait)) { MALI_PRINT_ERROR(("Mali Timeline: failed to allocate data for fence wait\n")); return MALI_FALSE; } wait->activated = MALI_FALSE; wait->system = system; /* Initialize refcount to two references. The reference first will be released by this * function after the wait is over. The second reference will be released when the tracker * is activated. */ _mali_osk_atomic_init(&wait->refcount, 2); /* Add tracker to timeline system, but not to a timeline. */ mali_timeline_tracker_init(&wait->tracker, MALI_TIMELINE_TRACKER_WAIT, fence, wait); point = mali_timeline_system_add_tracker(system, &wait->tracker, MALI_TIMELINE_NONE); MALI_DEBUG_ASSERT(MALI_TIMELINE_NO_POINT == point); MALI_IGNORE(point); /* Wait for the tracker to be activated or time out. */ if (MALI_TIMELINE_FENCE_WAIT_TIMEOUT_NEVER == timeout) { _mali_osk_wait_queue_wait_event(system->wait_queue, mali_timeline_fence_wait_tracker_is_activated, (void *) wait); } else { _mali_osk_wait_queue_wait_event_timeout(system->wait_queue, mali_timeline_fence_wait_tracker_is_activated, (void *) wait, timeout); } ret = wait->activated; if (0 == _mali_osk_atomic_dec_return(&wait->refcount)) { mali_timeline_fence_wait_tracker_free(wait); } return ret; } void mali_timeline_fence_wait_activate(struct mali_timeline_fence_wait_tracker *wait) { mali_scheduler_mask schedule_mask = MALI_SCHEDULER_MASK_EMPTY; MALI_DEBUG_ASSERT_POINTER(wait); MALI_DEBUG_ASSERT_POINTER(wait->system); MALI_DEBUG_PRINT(4, ("Mali Timeline: activation for fence wait tracker\n")); MALI_DEBUG_ASSERT(MALI_FALSE == wait->activated); wait->activated = MALI_TRUE; _mali_osk_wait_queue_wake_up(wait->system->wait_queue); /* Nothing can wait on this tracker, so nothing to schedule after release. */ schedule_mask = mali_timeline_tracker_release(&wait->tracker); MALI_DEBUG_ASSERT(MALI_SCHEDULER_MASK_EMPTY == schedule_mask); MALI_IGNORE(schedule_mask); if (0 == _mali_osk_atomic_dec_return(&wait->refcount)) { mali_timeline_fence_wait_tracker_free(wait); } }