/* SPDX-License-Identifier: MIT */

/*
 * Copyright © 2019 Intel Corporation
 */

#include <linux/delay.h>
#include <linux/dma-fence.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/sched/signal.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

#include "selftest.h"

static struct kmem_cache *slab_fences;

static struct mock_fence {
	struct dma_fence base;
	struct spinlock lock;
} *to_mock_fence(struct dma_fence *f) {
	return container_of(f, struct mock_fence, base);
}

static const char *mock_name(struct dma_fence *f)
{
	return "mock";
}

static void mock_fence_release(struct dma_fence *f)
{
	kmem_cache_free(slab_fences, to_mock_fence(f));
}

struct wait_cb {
	struct dma_fence_cb cb;
	struct task_struct *task;
};

static void mock_wakeup(struct dma_fence *f, struct dma_fence_cb *cb)
{
	wake_up_process(container_of(cb, struct wait_cb, cb)->task);
}

static long mock_wait(struct dma_fence *f, bool intr, long timeout)
{
	const int state = intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
	struct wait_cb cb = { .task = current };

	if (dma_fence_add_callback(f, &cb.cb, mock_wakeup))
		return timeout;

	while (timeout) {
		set_current_state(state);

		if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &f->flags))
			break;

		if (signal_pending_state(state, current))
			break;

		timeout = schedule_timeout(timeout);
	}
	__set_current_state(TASK_RUNNING);

	if (!dma_fence_remove_callback(f, &cb.cb))
		return timeout;

	if (signal_pending_state(state, current))
		return -ERESTARTSYS;

	return -ETIME;
}

static const struct dma_fence_ops mock_ops = {
	.get_driver_name = mock_name,
	.get_timeline_name = mock_name,
	.wait = mock_wait,
	.release = mock_fence_release,
};

static struct dma_fence *mock_fence(void)
{
	struct mock_fence *f;

	f = kmem_cache_alloc(slab_fences, GFP_KERNEL);
	if (!f)
		return NULL;

	spin_lock_init(&f->lock);
	dma_fence_init(&f->base, &mock_ops, &f->lock, 0, 0);

	return &f->base;
}

static int sanitycheck(void *arg)
{
	struct dma_fence *f;

	f = mock_fence();
	if (!f)
		return -ENOMEM;

	dma_fence_enable_sw_signaling(f);

	dma_fence_signal(f);
	dma_fence_put(f);

	return 0;
}

static int test_signaling(void *arg)
{
	struct dma_fence *f;
	int err = -EINVAL;

	f = mock_fence();
	if (!f)
		return -ENOMEM;

	dma_fence_enable_sw_signaling(f);

	if (dma_fence_is_signaled(f)) {
		pr_err("Fence unexpectedly signaled on creation\n");
		goto err_free;
	}

	if (dma_fence_signal(f)) {
		pr_err("Fence reported being already signaled\n");
		goto err_free;
	}

	if (!dma_fence_is_signaled(f)) {
		pr_err("Fence not reporting signaled\n");
		goto err_free;
	}

	if (!dma_fence_signal(f)) {
		pr_err("Fence reported not being already signaled\n");
		goto err_free;
	}

	err = 0;
err_free:
	dma_fence_put(f);
	return err;
}

struct simple_cb {
	struct dma_fence_cb cb;
	bool seen;
};

static void simple_callback(struct dma_fence *f, struct dma_fence_cb *cb)
{
	smp_store_mb(container_of(cb, struct simple_cb, cb)->seen, true);
}

static int test_add_callback(void *arg)
{
	struct simple_cb cb = {};
	struct dma_fence *f;
	int err = -EINVAL;

	f = mock_fence();
	if (!f)
		return -ENOMEM;

	if (dma_fence_add_callback(f, &cb.cb, simple_callback)) {
		pr_err("Failed to add callback, fence already signaled!\n");
		goto err_free;
	}

	dma_fence_signal(f);
	if (!cb.seen) {
		pr_err("Callback failed!\n");
		goto err_free;
	}

	err = 0;
err_free:
	dma_fence_put(f);
	return err;
}

static int test_late_add_callback(void *arg)
{
	struct simple_cb cb = {};
	struct dma_fence *f;
	int err = -EINVAL;

	f = mock_fence();
	if (!f)
		return -ENOMEM;

	dma_fence_enable_sw_signaling(f);

	dma_fence_signal(f);

	if (!dma_fence_add_callback(f, &cb.cb, simple_callback)) {
		pr_err("Added callback, but fence was already signaled!\n");
		goto err_free;
	}

	dma_fence_signal(f);
	if (cb.seen) {
		pr_err("Callback called after failed attachment !\n");
		goto err_free;
	}

	err = 0;
err_free:
	dma_fence_put(f);
	return err;
}

static int test_rm_callback(void *arg)
{
	struct simple_cb cb = {};
	struct dma_fence *f;
	int err = -EINVAL;

	f = mock_fence();
	if (!f)
		return -ENOMEM;

	if (dma_fence_add_callback(f, &cb.cb, simple_callback)) {
		pr_err("Failed to add callback, fence already signaled!\n");
		goto err_free;
	}

	if (!dma_fence_remove_callback(f, &cb.cb)) {
		pr_err("Failed to remove callback!\n");
		goto err_free;
	}

	dma_fence_signal(f);
	if (cb.seen) {
		pr_err("Callback still signaled after removal!\n");
		goto err_free;
	}

	err = 0;
err_free:
	dma_fence_put(f);
	return err;
}

static int test_late_rm_callback(void *arg)
{
	struct simple_cb cb = {};
	struct dma_fence *f;
	int err = -EINVAL;

	f = mock_fence();
	if (!f)
		return -ENOMEM;

	if (dma_fence_add_callback(f, &cb.cb, simple_callback)) {
		pr_err("Failed to add callback, fence already signaled!\n");
		goto err_free;
	}

	dma_fence_signal(f);
	if (!cb.seen) {
		pr_err("Callback failed!\n");
		goto err_free;
	}

	if (dma_fence_remove_callback(f, &cb.cb)) {
		pr_err("Callback removal succeed after being executed!\n");
		goto err_free;
	}

	err = 0;
err_free:
	dma_fence_put(f);
	return err;
}

static int test_status(void *arg)
{
	struct dma_fence *f;
	int err = -EINVAL;

	f = mock_fence();
	if (!f)
		return -ENOMEM;

	dma_fence_enable_sw_signaling(f);

	if (dma_fence_get_status(f)) {
		pr_err("Fence unexpectedly has signaled status on creation\n");
		goto err_free;
	}

	dma_fence_signal(f);
	if (!dma_fence_get_status(f)) {
		pr_err("Fence not reporting signaled status\n");
		goto err_free;
	}

	err = 0;
err_free:
	dma_fence_put(f);
	return err;
}

static int test_error(void *arg)
{
	struct dma_fence *f;
	int err = -EINVAL;

	f = mock_fence();
	if (!f)
		return -ENOMEM;

	dma_fence_enable_sw_signaling(f);

	dma_fence_set_error(f, -EIO);

	if (dma_fence_get_status(f)) {
		pr_err("Fence unexpectedly has error status before signal\n");
		goto err_free;
	}

	dma_fence_signal(f);
	if (dma_fence_get_status(f) != -EIO) {
		pr_err("Fence not reporting error status, got %d\n",
		       dma_fence_get_status(f));
		goto err_free;
	}

	err = 0;
err_free:
	dma_fence_put(f);
	return err;
}

static int test_wait(void *arg)
{
	struct dma_fence *f;
	int err = -EINVAL;

	f = mock_fence();
	if (!f)
		return -ENOMEM;

	dma_fence_enable_sw_signaling(f);

	if (dma_fence_wait_timeout(f, false, 0) != -ETIME) {
		pr_err("Wait reported complete before being signaled\n");
		goto err_free;
	}

	dma_fence_signal(f);

	if (dma_fence_wait_timeout(f, false, 0) != 0) {
		pr_err("Wait reported incomplete after being signaled\n");
		goto err_free;
	}

	err = 0;
err_free:
	dma_fence_signal(f);
	dma_fence_put(f);
	return err;
}

struct wait_timer {
	struct timer_list timer;
	struct dma_fence *f;
};

static void wait_timer(struct timer_list *timer)
{
	struct wait_timer *wt = from_timer(wt, timer, timer);

	dma_fence_signal(wt->f);
}

static int test_wait_timeout(void *arg)
{
	struct wait_timer wt;
	int err = -EINVAL;

	timer_setup_on_stack(&wt.timer, wait_timer, 0);

	wt.f = mock_fence();
	if (!wt.f)
		return -ENOMEM;

	dma_fence_enable_sw_signaling(wt.f);

	if (dma_fence_wait_timeout(wt.f, false, 1) != -ETIME) {
		pr_err("Wait reported complete before being signaled\n");
		goto err_free;
	}

	mod_timer(&wt.timer, jiffies + 1);

	if (dma_fence_wait_timeout(wt.f, false, 2) == -ETIME) {
		if (timer_pending(&wt.timer)) {
			pr_notice("Timer did not fire within the jiffy!\n");
			err = 0; /* not our fault! */
		} else {
			pr_err("Wait reported incomplete after timeout\n");
		}
		goto err_free;
	}

	err = 0;
err_free:
	del_timer_sync(&wt.timer);
	destroy_timer_on_stack(&wt.timer);
	dma_fence_signal(wt.f);
	dma_fence_put(wt.f);
	return err;
}

static int test_stub(void *arg)
{
	struct dma_fence *f[64];
	int err = -EINVAL;
	int i;

	for (i = 0; i < ARRAY_SIZE(f); i++) {
		f[i] = dma_fence_get_stub();
		if (!dma_fence_is_signaled(f[i])) {
			pr_err("Obtained unsignaled stub fence!\n");
			goto err;
		}
	}

	err = 0;
err:
	while (i--)
		dma_fence_put(f[i]);
	return err;
}

/* Now off to the races! */

struct race_thread {
	struct dma_fence __rcu **fences;
	struct task_struct *task;
	bool before;
	int id;
};

static void __wait_for_callbacks(struct dma_fence *f)
{
	spin_lock_irq(f->lock);
	spin_unlock_irq(f->lock);
}

static int thread_signal_callback(void *arg)
{
	const struct race_thread *t = arg;
	unsigned long pass = 0;
	unsigned long miss = 0;
	int err = 0;

	while (!err && !kthread_should_stop()) {
		struct dma_fence *f1, *f2;
		struct simple_cb cb;

		f1 = mock_fence();
		if (!f1) {
			err = -ENOMEM;
			break;
		}

		dma_fence_enable_sw_signaling(f1);

		rcu_assign_pointer(t->fences[t->id], f1);
		smp_wmb();

		rcu_read_lock();
		do {
			f2 = dma_fence_get_rcu_safe(&t->fences[!t->id]);
		} while (!f2 && !kthread_should_stop());
		rcu_read_unlock();

		if (t->before)
			dma_fence_signal(f1);

		smp_store_mb(cb.seen, false);
		if (!f2 ||
		    dma_fence_add_callback(f2, &cb.cb, simple_callback)) {
			miss++;
			cb.seen = true;
		}

		if (!t->before)
			dma_fence_signal(f1);

		if (!cb.seen) {
			dma_fence_wait(f2, false);
			__wait_for_callbacks(f2);
		}

		if (!READ_ONCE(cb.seen)) {
			pr_err("Callback not seen on thread %d, pass %lu (%lu misses), signaling %s add_callback; fence signaled? %s\n",
			       t->id, pass, miss,
			       t->before ? "before" : "after",
			       dma_fence_is_signaled(f2) ? "yes" : "no");
			err = -EINVAL;
		}

		dma_fence_put(f2);

		rcu_assign_pointer(t->fences[t->id], NULL);
		smp_wmb();

		dma_fence_put(f1);

		pass++;
	}

	pr_info("%s[%d] completed %lu passes, %lu misses\n",
		__func__, t->id, pass, miss);
	return err;
}

static int race_signal_callback(void *arg)
{
	struct dma_fence __rcu *f[2] = {};
	int ret = 0;
	int pass;

	for (pass = 0; !ret && pass <= 1; pass++) {
		struct race_thread t[2];
		int i;

		for (i = 0; i < ARRAY_SIZE(t); i++) {
			t[i].fences = f;
			t[i].id = i;
			t[i].before = pass;
			t[i].task = kthread_run(thread_signal_callback, &t[i],
						"dma-fence:%d", i);
			if (IS_ERR(t[i].task)) {
				ret = PTR_ERR(t[i].task);
				while (--i >= 0)
					kthread_stop_put(t[i].task);
				return ret;
			}
			get_task_struct(t[i].task);
		}

		msleep(50);

		for (i = 0; i < ARRAY_SIZE(t); i++) {
			int err;

			err = kthread_stop_put(t[i].task);
			if (err && !ret)
				ret = err;
		}
	}

	return ret;
}

int dma_fence(void)
{
	static const struct subtest tests[] = {
		SUBTEST(sanitycheck),
		SUBTEST(test_signaling),
		SUBTEST(test_add_callback),
		SUBTEST(test_late_add_callback),
		SUBTEST(test_rm_callback),
		SUBTEST(test_late_rm_callback),
		SUBTEST(test_status),
		SUBTEST(test_error),
		SUBTEST(test_wait),
		SUBTEST(test_wait_timeout),
		SUBTEST(test_stub),
		SUBTEST(race_signal_callback),
	};
	int ret;

	pr_info("sizeof(dma_fence)=%zu\n", sizeof(struct dma_fence));

	slab_fences = KMEM_CACHE(mock_fence,
				 SLAB_TYPESAFE_BY_RCU |
				 SLAB_HWCACHE_ALIGN);
	if (!slab_fences)
		return -ENOMEM;

	ret = subtests(tests, NULL);

	kmem_cache_destroy(slab_fences);

	return ret;
}
