// SPDX-License-Identifier: MIT
/*
 * Copyright © 2022 Intel Corporation
 */

#include "xe_wait_user_fence.h"

#include <drm/drm_device.h>
#include <drm/drm_file.h>
#include <drm/drm_utils.h>
#include <uapi/drm/xe_drm.h>

#include "xe_device.h"
#include "xe_gt.h"
#include "xe_macros.h"
#include "xe_exec_queue.h"

static int do_compare(u64 addr, u64 value, u64 mask, u16 op)
{
	u64 rvalue;
	int err;
	bool passed;

	err = copy_from_user(&rvalue, u64_to_user_ptr(addr), sizeof(rvalue));
	if (err)
		return -EFAULT;

	switch (op) {
	case DRM_XE_UFENCE_WAIT_OP_EQ:
		passed = (rvalue & mask) == (value & mask);
		break;
	case DRM_XE_UFENCE_WAIT_OP_NEQ:
		passed = (rvalue & mask) != (value & mask);
		break;
	case DRM_XE_UFENCE_WAIT_OP_GT:
		passed = (rvalue & mask) > (value & mask);
		break;
	case DRM_XE_UFENCE_WAIT_OP_GTE:
		passed = (rvalue & mask) >= (value & mask);
		break;
	case DRM_XE_UFENCE_WAIT_OP_LT:
		passed = (rvalue & mask) < (value & mask);
		break;
	case DRM_XE_UFENCE_WAIT_OP_LTE:
		passed = (rvalue & mask) <= (value & mask);
		break;
	default:
		XE_WARN_ON("Not possible");
		return -EINVAL;
	}

	return passed ? 0 : 1;
}

#define VALID_FLAGS	DRM_XE_UFENCE_WAIT_FLAG_ABSTIME
#define MAX_OP		DRM_XE_UFENCE_WAIT_OP_LTE

static long to_jiffies_timeout(struct xe_device *xe,
			       struct drm_xe_wait_user_fence *args)
{
	unsigned long long t;
	long timeout;

	/*
	 * For negative timeout we want to wait "forever" by setting
	 * MAX_SCHEDULE_TIMEOUT. But we have to assign this value also
	 * to args->timeout to avoid being zeroed on the signal delivery
	 * (see arithmetics after wait).
	 */
	if (args->timeout < 0) {
		args->timeout = MAX_SCHEDULE_TIMEOUT;
		return MAX_SCHEDULE_TIMEOUT;
	}

	if (args->timeout == 0)
		return 0;

	/*
	 * Save the timeout to an u64 variable because nsecs_to_jiffies
	 * might return a value that overflows s32 variable.
	 */
	if (args->flags & DRM_XE_UFENCE_WAIT_FLAG_ABSTIME)
		t = drm_timeout_abs_to_jiffies(args->timeout);
	else
		t = nsecs_to_jiffies(args->timeout);

	/*
	 * Anything greater then MAX_SCHEDULE_TIMEOUT is meaningless,
	 * also we don't want to cap it at MAX_SCHEDULE_TIMEOUT because
	 * apparently user doesn't mean to wait forever, otherwise the
	 * args->timeout should have been set to a negative value.
	 */
	if (t > MAX_SCHEDULE_TIMEOUT)
		timeout = MAX_SCHEDULE_TIMEOUT - 1;
	else
		timeout = t;

	return timeout ?: 1;
}

int xe_wait_user_fence_ioctl(struct drm_device *dev, void *data,
			     struct drm_file *file)
{
	struct xe_device *xe = to_xe_device(dev);
	struct xe_file *xef = to_xe_file(file);
	DEFINE_WAIT_FUNC(w_wait, woken_wake_function);
	struct drm_xe_wait_user_fence *args = data;
	struct xe_exec_queue *q = NULL;
	u64 addr = args->addr;
	int err = 0;
	long timeout;
	ktime_t start;

	if (XE_IOCTL_DBG(xe, args->extensions) || XE_IOCTL_DBG(xe, args->pad) ||
	    XE_IOCTL_DBG(xe, args->pad2) ||
	    XE_IOCTL_DBG(xe, args->reserved[0] || args->reserved[1]))
		return -EINVAL;

	if (XE_IOCTL_DBG(xe, args->flags & ~VALID_FLAGS))
		return -EINVAL;

	if (XE_IOCTL_DBG(xe, args->op > MAX_OP))
		return -EINVAL;

	if (XE_IOCTL_DBG(xe, addr & 0x7))
		return -EINVAL;

	if (args->exec_queue_id) {
		q = xe_exec_queue_lookup(xef, args->exec_queue_id);
		if (XE_IOCTL_DBG(xe, !q))
			return -ENOENT;
	}

	timeout = to_jiffies_timeout(xe, args);

	start = ktime_get();

	add_wait_queue(&xe->ufence_wq, &w_wait);
	for (;;) {
		err = do_compare(addr, args->value, args->mask, args->op);
		if (err <= 0)
			break;

		if (signal_pending(current)) {
			err = -ERESTARTSYS;
			break;
		}

		if (q) {
			if (q->ops->reset_status(q)) {
				drm_info(&xe->drm, "exec queue reset detected\n");
				err = -EIO;
				break;
			}
		}

		if (!timeout) {
			LNL_FLUSH_WORKQUEUE(xe->ordered_wq);
			err = do_compare(addr, args->value, args->mask,
					 args->op);
			if (err <= 0) {
				drm_dbg(&xe->drm, "LNL_FLUSH_WORKQUEUE resolved ufence timeout\n");
				break;
			}
			err = -ETIME;
			break;
		}

		timeout = wait_woken(&w_wait, TASK_INTERRUPTIBLE, timeout);
	}
	remove_wait_queue(&xe->ufence_wq, &w_wait);

	if (!(args->flags & DRM_XE_UFENCE_WAIT_FLAG_ABSTIME)) {
		args->timeout -= ktime_to_ns(ktime_sub(ktime_get(), start));
		if (args->timeout < 0)
			args->timeout = 0;
	}

	if (q)
		xe_exec_queue_put(q);

	return err;
}
