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

#include <linux/kref.h>

#include "gem/i915_gem_pm.h"
#include "gt/intel_gt.h"

#include "i915_selftest.h"

#include "igt_flush_test.h"
#include "lib_sw_fence.h"

struct live_active {
	struct i915_active base;
	struct kref ref;
	bool retired;
};

static void __live_get(struct live_active *active)
{
	kref_get(&active->ref);
}

static void __live_free(struct live_active *active)
{
	i915_active_fini(&active->base);
	kfree(active);
}

static void __live_release(struct kref *ref)
{
	struct live_active *active = container_of(ref, typeof(*active), ref);

	__live_free(active);
}

static void __live_put(struct live_active *active)
{
	kref_put(&active->ref, __live_release);
}

static int __live_active(struct i915_active *base)
{
	struct live_active *active = container_of(base, typeof(*active), base);

	__live_get(active);
	return 0;
}

static void __live_retire(struct i915_active *base)
{
	struct live_active *active = container_of(base, typeof(*active), base);

	active->retired = true;
	__live_put(active);
}

static struct live_active *__live_alloc(struct drm_i915_private *i915)
{
	struct live_active *active;

	active = kzalloc(sizeof(*active), GFP_KERNEL);
	if (!active)
		return NULL;

	kref_init(&active->ref);
	i915_active_init(&active->base, __live_active, __live_retire, 0);

	return active;
}

static struct live_active *
__live_active_setup(struct drm_i915_private *i915)
{
	struct intel_engine_cs *engine;
	struct i915_sw_fence *submit;
	struct live_active *active;
	unsigned int count = 0;
	int err = 0;

	active = __live_alloc(i915);
	if (!active)
		return ERR_PTR(-ENOMEM);

	submit = heap_fence_create(GFP_KERNEL);
	if (!submit) {
		kfree(active);
		return ERR_PTR(-ENOMEM);
	}

	err = i915_active_acquire(&active->base);
	if (err)
		goto out;

	for_each_uabi_engine(engine, i915) {
		struct i915_request *rq;

		rq = intel_engine_create_kernel_request(engine);
		if (IS_ERR(rq)) {
			err = PTR_ERR(rq);
			break;
		}

		err = i915_sw_fence_await_sw_fence_gfp(&rq->submit,
						       submit,
						       GFP_KERNEL);
		if (err >= 0)
			err = i915_active_add_request(&active->base, rq);
		i915_request_add(rq);
		if (err) {
			pr_err("Failed to track active ref!\n");
			break;
		}

		count++;
	}

	i915_active_release(&active->base);
	if (READ_ONCE(active->retired) && count) {
		pr_err("i915_active retired before submission!\n");
		err = -EINVAL;
	}
	if (atomic_read(&active->base.count) != count) {
		pr_err("i915_active not tracking all requests, found %d, expected %d\n",
		       atomic_read(&active->base.count), count);
		err = -EINVAL;
	}

out:
	i915_sw_fence_commit(submit);
	heap_fence_put(submit);
	if (err) {
		__live_put(active);
		active = ERR_PTR(err);
	}

	return active;
}

static int live_active_wait(void *arg)
{
	struct drm_i915_private *i915 = arg;
	struct live_active *active;
	int err = 0;

	/* Check that we get a callback when requests retire upon waiting */

	active = __live_active_setup(i915);
	if (IS_ERR(active))
		return PTR_ERR(active);

	__i915_active_wait(&active->base, TASK_UNINTERRUPTIBLE);
	if (!READ_ONCE(active->retired)) {
		struct drm_printer p = drm_err_printer(__func__);

		pr_err("i915_active not retired after waiting!\n");
		i915_active_print(&active->base, &p);

		err = -EINVAL;
	}

	__live_put(active);

	if (igt_flush_test(i915))
		err = -EIO;

	return err;
}

static int live_active_retire(void *arg)
{
	struct drm_i915_private *i915 = arg;
	struct live_active *active;
	int err = 0;

	/* Check that we get a callback when requests are indirectly retired */

	active = __live_active_setup(i915);
	if (IS_ERR(active))
		return PTR_ERR(active);

	/* waits for & retires all requests */
	if (igt_flush_test(i915))
		err = -EIO;

	if (!READ_ONCE(active->retired)) {
		struct drm_printer p = drm_err_printer(__func__);

		pr_err("i915_active not retired after flushing!\n");
		i915_active_print(&active->base, &p);

		err = -EINVAL;
	}

	__live_put(active);

	return err;
}

static int live_active_barrier(void *arg)
{
	struct drm_i915_private *i915 = arg;
	struct intel_engine_cs *engine;
	struct live_active *active;
	int err = 0;

	/* Check that we get a callback when requests retire upon waiting */

	active = __live_alloc(i915);
	if (!active)
		return -ENOMEM;

	err = i915_active_acquire(&active->base);
	if (err)
		goto out;

	for_each_uabi_engine(engine, i915) {
		err = i915_active_acquire_preallocate_barrier(&active->base,
							      engine);
		if (err)
			break;

		i915_active_acquire_barrier(&active->base);
	}

	i915_active_release(&active->base);
	if (err)
		goto out;

	__i915_active_wait(&active->base, TASK_UNINTERRUPTIBLE);
	if (!READ_ONCE(active->retired)) {
		pr_err("i915_active not retired after flushing barriers!\n");
		err = -EINVAL;
	}

out:
	__live_put(active);

	if (igt_flush_test(i915))
		err = -EIO;

	return err;
}

int i915_active_live_selftests(struct drm_i915_private *i915)
{
	static const struct i915_subtest tests[] = {
		SUBTEST(live_active_wait),
		SUBTEST(live_active_retire),
		SUBTEST(live_active_barrier),
	};

	if (intel_gt_is_wedged(&i915->gt))
		return 0;

	return i915_subtests(tests, i915);
}

static struct intel_engine_cs *node_to_barrier(struct active_node *it)
{
	struct intel_engine_cs *engine;

	if (!is_barrier(&it->base))
		return NULL;

	engine = __barrier_to_engine(it);
	smp_rmb(); /* serialise with add_active_barriers */
	if (!is_barrier(&it->base))
		return NULL;

	return engine;
}

void i915_active_print(struct i915_active *ref, struct drm_printer *m)
{
	drm_printf(m, "active %ps:%ps\n", ref->active, ref->retire);
	drm_printf(m, "\tcount: %d\n", atomic_read(&ref->count));
	drm_printf(m, "\tpreallocated barriers? %s\n",
		   yesno(!llist_empty(&ref->preallocated_barriers)));

	if (i915_active_acquire_if_busy(ref)) {
		struct active_node *it, *n;

		rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
			struct intel_engine_cs *engine;

			engine = node_to_barrier(it);
			if (engine) {
				drm_printf(m, "\tbarrier: %s\n", engine->name);
				continue;
			}

			if (i915_active_fence_isset(&it->base)) {
				drm_printf(m,
					   "\ttimeline: %llx\n", it->timeline);
				continue;
			}
		}

		i915_active_release(ref);
	}
}

static void spin_unlock_wait(spinlock_t *lock)
{
	spin_lock_irq(lock);
	spin_unlock_irq(lock);
}

static void active_flush(struct i915_active *ref,
			 struct i915_active_fence *active)
{
	struct dma_fence *fence;

	fence = xchg(__active_fence_slot(active), NULL);
	if (!fence)
		return;

	spin_lock_irq(fence->lock);
	__list_del_entry(&active->cb.node);
	spin_unlock_irq(fence->lock); /* serialise with fence->cb_list */
	atomic_dec(&ref->count);

	GEM_BUG_ON(!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags));
}

void i915_active_unlock_wait(struct i915_active *ref)
{
	if (i915_active_acquire_if_busy(ref)) {
		struct active_node *it, *n;

		/* Wait for all active callbacks */
		rcu_read_lock();
		active_flush(ref, &ref->excl);
		rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node)
			active_flush(ref, &it->base);
		rcu_read_unlock();

		i915_active_release(ref);
	}

	/* And wait for the retire callback */
	spin_unlock_wait(&ref->tree_lock);

	/* ... which may have been on a thread instead */
	flush_work(&ref->work);
}
