// SPDX-License-Identifier: GPL-2.0-only
/*
 * GCIP-integrated IIF driver sync file.
 *
 * Copyright (C) 2023 Google LLC
 */

#include <linux/anon_inodes.h>
#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/uaccess.h>

#include <gcip/iif/iif-fence.h>
#include <gcip/iif/iif-sync-file.h>

static void iif_sync_file_fence_signaled(struct iif_fence *fence, struct iif_fence_poll_cb *poll_cb)
{
	struct iif_sync_file *sync_file = container_of(poll_cb, struct iif_sync_file, poll_cb);

	wake_up_all(&sync_file->wq);
}

static int iif_sync_file_release(struct inode *inode, struct file *file)
{
	struct iif_sync_file *sync_file = file->private_data;

	if (atomic_dec_and_test(&sync_file->fence->num_sync_file))
		iif_fence_on_sync_file_release(sync_file->fence);
	if (test_bit(IIF_SYNC_FILE_FLAGS_POLL_ENABLED, &sync_file->flags))
		iif_fence_remove_poll_callback(sync_file->fence, &sync_file->poll_cb);
	iif_fence_put(sync_file->fence);
	kfree(sync_file);

	return 0;
}

static __poll_t iif_sync_file_poll(struct file *file, poll_table *wait)
{
	struct iif_sync_file *sync_file = file->private_data;
	int ret;

	poll_wait(file, &sync_file->wq, wait);

	if (list_empty(&sync_file->poll_cb.node) &&
	    !test_and_set_bit(IIF_SYNC_FILE_FLAGS_POLL_ENABLED, &sync_file->flags)) {
		ret = iif_fence_add_poll_callback(sync_file->fence, &sync_file->poll_cb,
						  iif_sync_file_fence_signaled);
		/* If all signalers of the fence already signaled, just wake up all. */
		if (ret < 0)
			wake_up_all(&sync_file->wq);
	}

	return iif_fence_is_signaled(sync_file->fence) ? EPOLLIN : 0;
}

static int iif_sync_file_ioctl_get_information(struct iif_sync_file *sync_file,
					       struct iif_fence_get_information_ioctl __user *argp)
{
	struct iif_fence *fence = sync_file->fence;
	const struct iif_fence_get_information_ioctl ibuf = {
		.signaler_ip = fence->signaler_ip,
		.total_signalers = fence->total_signalers,
		.submitted_signalers = iif_fence_submitted_signalers(fence),
		.signaled_signalers = iif_fence_signaled_signalers(fence),
		.outstanding_waiters = iif_fence_outstanding_waiters(fence),
	};

	if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
		return -EFAULT;

	return 0;
}

static long iif_sync_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct iif_sync_file *sync_file = file->private_data;
	void __user *argp = (void __user *)arg;

	switch (cmd) {
	case IIF_FENCE_GET_INFORMATION:
		return iif_sync_file_ioctl_get_information(sync_file, argp);
	default:
		return -ENOTTY;
	}
}

static const struct file_operations iif_sync_file_fops = {
	.release = iif_sync_file_release,
	.poll = iif_sync_file_poll,
	.unlocked_ioctl = iif_sync_file_ioctl,
};

struct iif_sync_file *iif_sync_file_create(struct iif_fence *fence)
{
	struct iif_sync_file *sync_file;
	int ret;

	sync_file = kzalloc(sizeof(*sync_file), GFP_KERNEL);
	if (!sync_file)
		return ERR_PTR(-ENOMEM);

	sync_file->file = anon_inode_getfile("iif_file", &iif_sync_file_fops, sync_file, 0);
	if (IS_ERR(sync_file->file)) {
		ret = PTR_ERR(sync_file->file);
		goto err_free_sync_file;
	}

	sync_file->fence = iif_fence_get(fence);
	atomic_inc(&fence->num_sync_file);

	init_waitqueue_head(&sync_file->wq);
	INIT_LIST_HEAD(&sync_file->poll_cb.node);

	return sync_file;

err_free_sync_file:
	kfree(sync_file);
	return ERR_PTR(ret);
}

struct iif_sync_file *iif_sync_file_fdget(int fd)
{
	struct file *file = fget(fd);

	if (!file)
		return ERR_PTR(-EBADF);

	if (file->f_op != &iif_sync_file_fops) {
		fput(file);
		return ERR_PTR(-EINVAL);
	}

	return file->private_data;
}
