/*
 * Copyright © 2017 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 */

#include <linux/completion.h>
#include <linux/delay.h>

#include "../i915_selftest.h"

static int __i915_sw_fence_call
fence_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
{
	switch (state) {
	case FENCE_COMPLETE:
		break;

	case FENCE_FREE:
		/* Leave the fence for the caller to free it after testing */
		break;
	}

	return NOTIFY_DONE;
}

static struct i915_sw_fence *alloc_fence(void)
{
	struct i915_sw_fence *fence;

	fence = kmalloc(sizeof(*fence), GFP_KERNEL);
	if (!fence)
		return NULL;

	i915_sw_fence_init(fence, fence_notify);
	return fence;
}

static void free_fence(struct i915_sw_fence *fence)
{
	i915_sw_fence_fini(fence);
	kfree(fence);
}

static int __test_self(struct i915_sw_fence *fence)
{
	if (i915_sw_fence_done(fence))
		return -EINVAL;

	i915_sw_fence_commit(fence);
	if (!i915_sw_fence_done(fence))
		return -EINVAL;

	i915_sw_fence_wait(fence);
	if (!i915_sw_fence_done(fence))
		return -EINVAL;

	return 0;
}

static int test_self(void *arg)
{
	struct i915_sw_fence *fence;
	int ret;

	/* Test i915_sw_fence signaling and completion testing */
	fence = alloc_fence();
	if (!fence)
		return -ENOMEM;

	ret = __test_self(fence);

	free_fence(fence);
	return ret;
}

static int test_dag(void *arg)
{
	struct i915_sw_fence *A, *B, *C;
	int ret = -EINVAL;

	/* Test detection of cycles within the i915_sw_fence graphs */
	if (!IS_ENABLED(CONFIG_DRM_I915_SW_FENCE_CHECK_DAG))
		return 0;

	A = alloc_fence();
	if (!A)
		return -ENOMEM;

	if (i915_sw_fence_await_sw_fence_gfp(A, A, GFP_KERNEL) != -EINVAL) {
		pr_err("recursive cycle not detected (AA)\n");
		goto err_A;
	}

	B = alloc_fence();
	if (!B) {
		ret = -ENOMEM;
		goto err_A;
	}

	i915_sw_fence_await_sw_fence_gfp(A, B, GFP_KERNEL);
	if (i915_sw_fence_await_sw_fence_gfp(B, A, GFP_KERNEL) != -EINVAL) {
		pr_err("single depth cycle not detected (BAB)\n");
		goto err_B;
	}

	C = alloc_fence();
	if (!C) {
		ret = -ENOMEM;
		goto err_B;
	}

	if (i915_sw_fence_await_sw_fence_gfp(B, C, GFP_KERNEL) == -EINVAL) {
		pr_err("invalid cycle detected\n");
		goto err_C;
	}
	if (i915_sw_fence_await_sw_fence_gfp(C, B, GFP_KERNEL) != -EINVAL) {
		pr_err("single depth cycle not detected (CBC)\n");
		goto err_C;
	}
	if (i915_sw_fence_await_sw_fence_gfp(C, A, GFP_KERNEL) != -EINVAL) {
		pr_err("cycle not detected (BA, CB, AC)\n");
		goto err_C;
	}
	if (i915_sw_fence_await_sw_fence_gfp(A, C, GFP_KERNEL) == -EINVAL) {
		pr_err("invalid cycle detected\n");
		goto err_C;
	}

	i915_sw_fence_commit(A);
	i915_sw_fence_commit(B);
	i915_sw_fence_commit(C);

	ret = 0;
	if (!i915_sw_fence_done(C)) {
		pr_err("fence C not done\n");
		ret = -EINVAL;
	}
	if (!i915_sw_fence_done(B)) {
		pr_err("fence B not done\n");
		ret = -EINVAL;
	}
	if (!i915_sw_fence_done(A)) {
		pr_err("fence A not done\n");
		ret = -EINVAL;
	}
err_C:
	free_fence(C);
err_B:
	free_fence(B);
err_A:
	free_fence(A);
	return ret;
}

static int test_AB(void *arg)
{
	struct i915_sw_fence *A, *B;
	int ret;

	/* Test i915_sw_fence (A) waiting on an event source (B) */
	A = alloc_fence();
	if (!A)
		return -ENOMEM;
	B = alloc_fence();
	if (!B) {
		ret = -ENOMEM;
		goto err_A;
	}

	ret = i915_sw_fence_await_sw_fence_gfp(A, B, GFP_KERNEL);
	if (ret < 0)
		goto err_B;
	if (ret == 0) {
		pr_err("Incorrectly reported fence A was complete before await\n");
		ret = -EINVAL;
		goto err_B;
	}

	ret = -EINVAL;
	i915_sw_fence_commit(A);
	if (i915_sw_fence_done(A))
		goto err_B;

	i915_sw_fence_commit(B);
	if (!i915_sw_fence_done(B)) {
		pr_err("Fence B is not done\n");
		goto err_B;
	}

	if (!i915_sw_fence_done(A)) {
		pr_err("Fence A is not done\n");
		goto err_B;
	}

	ret = 0;
err_B:
	free_fence(B);
err_A:
	free_fence(A);
	return ret;
}

static int test_ABC(void *arg)
{
	struct i915_sw_fence *A, *B, *C;
	int ret;

	/* Test a chain of fences, A waits on B who waits on C */
	A = alloc_fence();
	if (!A)
		return -ENOMEM;

	B = alloc_fence();
	if (!B) {
		ret = -ENOMEM;
		goto err_A;
	}

	C = alloc_fence();
	if (!C) {
		ret = -ENOMEM;
		goto err_B;
	}

	ret = i915_sw_fence_await_sw_fence_gfp(A, B, GFP_KERNEL);
	if (ret < 0)
		goto err_C;
	if (ret == 0) {
		pr_err("Incorrectly reported fence B was complete before await\n");
		goto err_C;
	}

	ret = i915_sw_fence_await_sw_fence_gfp(B, C, GFP_KERNEL);
	if (ret < 0)
		goto err_C;
	if (ret == 0) {
		pr_err("Incorrectly reported fence C was complete before await\n");
		goto err_C;
	}

	ret = -EINVAL;
	i915_sw_fence_commit(A);
	if (i915_sw_fence_done(A)) {
		pr_err("Fence A completed early\n");
		goto err_C;
	}

	i915_sw_fence_commit(B);
	if (i915_sw_fence_done(B)) {
		pr_err("Fence B completed early\n");
		goto err_C;
	}

	if (i915_sw_fence_done(A)) {
		pr_err("Fence A completed early (after signaling B)\n");
		goto err_C;
	}

	i915_sw_fence_commit(C);

	ret = 0;
	if (!i915_sw_fence_done(C)) {
		pr_err("Fence C not done\n");
		ret = -EINVAL;
	}
	if (!i915_sw_fence_done(B)) {
		pr_err("Fence B not done\n");
		ret = -EINVAL;
	}
	if (!i915_sw_fence_done(A)) {
		pr_err("Fence A not done\n");
		ret = -EINVAL;
	}
err_C:
	free_fence(C);
err_B:
	free_fence(B);
err_A:
	free_fence(A);
	return ret;
}

static int test_AB_C(void *arg)
{
	struct i915_sw_fence *A, *B, *C;
	int ret = -EINVAL;

	/* Test multiple fences (AB) waiting on a single event (C) */
	A = alloc_fence();
	if (!A)
		return -ENOMEM;

	B = alloc_fence();
	if (!B) {
		ret = -ENOMEM;
		goto err_A;
	}

	C = alloc_fence();
	if (!C) {
		ret = -ENOMEM;
		goto err_B;
	}

	ret = i915_sw_fence_await_sw_fence_gfp(A, C, GFP_KERNEL);
	if (ret < 0)
		goto err_C;
	if (ret == 0) {
		ret = -EINVAL;
		goto err_C;
	}

	ret = i915_sw_fence_await_sw_fence_gfp(B, C, GFP_KERNEL);
	if (ret < 0)
		goto err_C;
	if (ret == 0) {
		ret = -EINVAL;
		goto err_C;
	}

	i915_sw_fence_commit(A);
	i915_sw_fence_commit(B);

	ret = 0;
	if (i915_sw_fence_done(A)) {
		pr_err("Fence A completed early\n");
		ret = -EINVAL;
	}

	if (i915_sw_fence_done(B)) {
		pr_err("Fence B completed early\n");
		ret = -EINVAL;
	}

	i915_sw_fence_commit(C);
	if (!i915_sw_fence_done(C)) {
		pr_err("Fence C not done\n");
		ret = -EINVAL;
	}

	if (!i915_sw_fence_done(B)) {
		pr_err("Fence B not done\n");
		ret = -EINVAL;
	}

	if (!i915_sw_fence_done(A)) {
		pr_err("Fence A not done\n");
		ret = -EINVAL;
	}

err_C:
	free_fence(C);
err_B:
	free_fence(B);
err_A:
	free_fence(A);
	return ret;
}

static int test_C_AB(void *arg)
{
	struct i915_sw_fence *A, *B, *C;
	int ret;

	/* Test multiple event sources (A,B) for a single fence (C) */
	A = alloc_fence();
	if (!A)
		return -ENOMEM;

	B = alloc_fence();
	if (!B) {
		ret = -ENOMEM;
		goto err_A;
	}

	C = alloc_fence();
	if (!C) {
		ret = -ENOMEM;
		goto err_B;
	}

	ret = i915_sw_fence_await_sw_fence_gfp(C, A, GFP_KERNEL);
	if (ret < 0)
		goto err_C;
	if (ret == 0) {
		ret = -EINVAL;
		goto err_C;
	}

	ret = i915_sw_fence_await_sw_fence_gfp(C, B, GFP_KERNEL);
	if (ret < 0)
		goto err_C;
	if (ret == 0) {
		ret = -EINVAL;
		goto err_C;
	}

	ret = 0;
	i915_sw_fence_commit(C);
	if (i915_sw_fence_done(C))
		ret = -EINVAL;

	i915_sw_fence_commit(A);
	i915_sw_fence_commit(B);

	if (!i915_sw_fence_done(A)) {
		pr_err("Fence A not done\n");
		ret = -EINVAL;
	}

	if (!i915_sw_fence_done(B)) {
		pr_err("Fence B not done\n");
		ret = -EINVAL;
	}

	if (!i915_sw_fence_done(C)) {
		pr_err("Fence C not done\n");
		ret = -EINVAL;
	}

err_C:
	free_fence(C);
err_B:
	free_fence(B);
err_A:
	free_fence(A);
	return ret;
}

static int test_chain(void *arg)
{
	int nfences = 4096;
	struct i915_sw_fence **fences;
	int ret, i;

	/* Test a long chain of fences */
	fences = kmalloc_array(nfences, sizeof(*fences), GFP_KERNEL);
	if (!fences)
		return -ENOMEM;

	for (i = 0; i < nfences; i++) {
		fences[i] = alloc_fence();
		if (!fences[i]) {
			nfences = i;
			ret = -ENOMEM;
			goto err;
		}

		if (i > 0) {
			ret = i915_sw_fence_await_sw_fence_gfp(fences[i],
							       fences[i - 1],
							       GFP_KERNEL);
			if (ret < 0) {
				nfences = i + 1;
				goto err;
			}

			i915_sw_fence_commit(fences[i]);
		}
	}

	ret = 0;
	for (i = nfences; --i; ) {
		if (i915_sw_fence_done(fences[i])) {
			if (ret == 0)
				pr_err("Fence[%d] completed early\n", i);
			ret = -EINVAL;
		}
	}
	i915_sw_fence_commit(fences[0]);
	for (i = 0; ret == 0 && i < nfences; i++) {
		if (!i915_sw_fence_done(fences[i])) {
			pr_err("Fence[%d] is not done\n", i);
			ret = -EINVAL;
		}
	}

err:
	for (i = 0; i < nfences; i++)
		free_fence(fences[i]);
	kfree(fences);
	return ret;
}

struct task_ipc {
	struct work_struct work;
	struct completion started;
	struct i915_sw_fence *in, *out;
	int value;
};

static void task_ipc(struct work_struct *work)
{
	struct task_ipc *ipc = container_of(work, typeof(*ipc), work);

	complete(&ipc->started);

	i915_sw_fence_wait(ipc->in);
	smp_store_mb(ipc->value, 1);
	i915_sw_fence_commit(ipc->out);
}

static int test_ipc(void *arg)
{
	struct task_ipc ipc;
	int ret = 0;

	/* Test use of i915_sw_fence as an interprocess signaling mechanism */
	ipc.in = alloc_fence();
	if (!ipc.in)
		return -ENOMEM;
	ipc.out = alloc_fence();
	if (!ipc.out) {
		ret = -ENOMEM;
		goto err_in;
	}

	/* use a completion to avoid chicken-and-egg testing */
	init_completion(&ipc.started);

	ipc.value = 0;
	INIT_WORK_ONSTACK(&ipc.work, task_ipc);
	schedule_work(&ipc.work);

	wait_for_completion(&ipc.started);

	usleep_range(1000, 2000);
	if (READ_ONCE(ipc.value)) {
		pr_err("worker updated value before i915_sw_fence was signaled\n");
		ret = -EINVAL;
	}

	i915_sw_fence_commit(ipc.in);
	i915_sw_fence_wait(ipc.out);

	if (!READ_ONCE(ipc.value)) {
		pr_err("worker signaled i915_sw_fence before value was posted\n");
		ret = -EINVAL;
	}

	flush_work(&ipc.work);
	destroy_work_on_stack(&ipc.work);
	free_fence(ipc.out);
err_in:
	free_fence(ipc.in);
	return ret;
}

int i915_sw_fence_mock_selftests(void)
{
	static const struct i915_subtest tests[] = {
		SUBTEST(test_self),
		SUBTEST(test_dag),
		SUBTEST(test_AB),
		SUBTEST(test_ABC),
		SUBTEST(test_AB_C),
		SUBTEST(test_C_AB),
		SUBTEST(test_chain),
		SUBTEST(test_ipc),
	};

	return i915_subtests(tests, NULL);
}
