static unsigned int sync_file_poll(struct file *file, poll_table *wait) { struct sync_file *sync_file = file->private_data; poll_wait(file, &sync_file->wq, wait); if (!poll_does_not_wait(wait) && !test_and_set_bit(POLL_ENABLED, &sync_file->fence->flags)) { if (fence_add_callback(sync_file->fence, &sync_file->cb, fence_check_cb_func) < 0) wake_up_all(&sync_file->wq); } return fence_is_signaled(sync_file->fence) ? POLLIN : 0; }
static int reservation_cb_add_fence_cb(struct drm_reservation_cb *rcb, struct fence *fence) { int ret = 0; struct drm_reservation_fence_cb *fence_cb; struct drm_reservation_fence_cb **new_fence_cbs; new_fence_cbs = krealloc(rcb->fence_cbs, (rcb->num_fence_cbs + 1) * sizeof(struct drm_reservation_fence_cb *), GFP_KERNEL); if (!new_fence_cbs) return -ENOMEM; rcb->fence_cbs = new_fence_cbs; fence_cb = kzalloc(sizeof(struct drm_reservation_fence_cb), GFP_KERNEL); if (!fence_cb) return -ENOMEM; /* * do not want for fence to disappear on us while we are waiting for * callback and we need it in case we want to remove callbacks */ fence_get(fence); fence_cb->fence = fence; fence_cb->parent = rcb; rcb->fence_cbs[rcb->num_fence_cbs] = fence_cb; atomic_inc(&rcb->count); ret = fence_add_callback(fence, &fence_cb->base, reservation_cb_fence_cb); if (ret == -ENOENT) { /* already signaled */ atomic_dec(&rcb->count); fence_put(fence_cb->fence); kfree(fence_cb); ret = 0; } else if (ret < 0) { atomic_dec(&rcb->count); fence_put(fence_cb->fence); kfree(fence_cb); return ret; } else { rcb->num_fence_cbs++; } return ret; }