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

#include <linux/dma-fence.h>
#include <linux/slab.h>

#include <drm/ttm/ttm_bo_api.h>

#include "i915_deps.h"

/**
 * DOC: Set of utilities to dynamically collect dependencies into a
 * structure which is fed into the GT migration code.
 *
 * Once we can do async unbinding, this is also needed to coalesce
 * the migration fence with the unbind fences if these are coalesced
 * post-migration.
 *
 * While collecting the individual dependencies, we store the refcounted
 * struct dma_fence pointers in a realloc-managed pointer array, since
 * that can be easily fed into a dma_fence_array. Other options are
 * available, like for example an xarray for similarity with drm/sched.
 * Can be changed easily if needed.
 *
 * A struct i915_deps need to be initialized using i915_deps_init().
 * If i915_deps_add_dependency() or i915_deps_add_resv() return an
 * error code they will internally call i915_deps_fini(), which frees
 * all internal references and allocations.
 */

/* Min number of fence pointers in the array when an allocation occurs. */
#define I915_DEPS_MIN_ALLOC_CHUNK 8U

static void i915_deps_reset_fences(struct i915_deps *deps)
{
	if (deps->fences != &deps->single)
		kfree(deps->fences);
	deps->num_deps = 0;
	deps->fences_size = 1;
	deps->fences = &deps->single;
}

/**
 * i915_deps_init - Initialize an i915_deps structure
 * @deps: Pointer to the i915_deps structure to initialize.
 * @gfp: The allocation mode for subsequenst allocations.
 */
void i915_deps_init(struct i915_deps *deps, gfp_t gfp)
{
	deps->fences = NULL;
	deps->gfp = gfp;
	i915_deps_reset_fences(deps);
}

/**
 * i915_deps_fini - Finalize an i915_deps structure
 * @deps: Pointer to the i915_deps structure to finalize.
 *
 * This function drops all fence references taken, conditionally frees and
 * then resets the fences array.
 */
void i915_deps_fini(struct i915_deps *deps)
{
	unsigned int i;

	for (i = 0; i < deps->num_deps; ++i)
		dma_fence_put(deps->fences[i]);

	if (deps->fences != &deps->single)
		kfree(deps->fences);
}

static int i915_deps_grow(struct i915_deps *deps, struct dma_fence *fence,
			  const struct ttm_operation_ctx *ctx)
{
	int ret;

	if (deps->num_deps >= deps->fences_size) {
		unsigned int new_size = 2 * deps->fences_size;
		struct dma_fence **new_fences;

		new_size = max(new_size, I915_DEPS_MIN_ALLOC_CHUNK);
		new_fences = kmalloc_array(new_size, sizeof(*new_fences), deps->gfp);
		if (!new_fences)
			goto sync;

		memcpy(new_fences, deps->fences,
		       deps->fences_size * sizeof(*new_fences));
		swap(new_fences, deps->fences);
		if (new_fences != &deps->single)
			kfree(new_fences);
		deps->fences_size = new_size;
	}
	deps->fences[deps->num_deps++] = dma_fence_get(fence);
	return 0;

sync:
	if (ctx->no_wait_gpu && !dma_fence_is_signaled(fence)) {
		ret = -EBUSY;
		goto unref;
	}

	ret = dma_fence_wait(fence, ctx->interruptible);
	if (ret)
		goto unref;

	ret = fence->error;
	if (ret)
		goto unref;

	return 0;

unref:
	i915_deps_fini(deps);
	return ret;
}

/**
 * i915_deps_sync - Wait for all the fences in the dependency collection
 * @deps: Pointer to the i915_deps structure the fences of which to wait for.
 * @ctx: Pointer to a struct ttm_operation_ctx indicating how the waits
 * should be performed.
 *
 * This function waits for fences in the dependency collection. If it
 * encounters an error during the wait or a fence error, the wait for
 * further fences is aborted and the error returned.
 *
 * Return: Zero if successful, Negative error code on error.
 */
int i915_deps_sync(const struct i915_deps *deps, const struct ttm_operation_ctx *ctx)
{
	struct dma_fence **fences = deps->fences;
	unsigned int i;
	int ret = 0;

	for (i = 0; i < deps->num_deps; ++i, ++fences) {
		if (ctx->no_wait_gpu && !dma_fence_is_signaled(*fences)) {
			ret = -EBUSY;
			break;
		}

		ret = dma_fence_wait(*fences, ctx->interruptible);
		if (!ret)
			ret = (*fences)->error;
		if (ret)
			break;
	}

	return ret;
}

/**
 * i915_deps_add_dependency - Add a fence to the dependency collection
 * @deps: Pointer to the i915_deps structure a fence is to be added to.
 * @fence: The fence to add.
 * @ctx: Pointer to a struct ttm_operation_ctx indicating how waits are to
 * be performed if waiting.
 *
 * Adds a fence to the dependency collection, and takes a reference on it.
 * If the fence context is not zero and there was a later fence from the
 * same fence context already added, then the fence is not added to the
 * dependency collection. If the fence context is not zero and there was
 * an earlier fence already added, then the fence will replace the older
 * fence from the same context and the reference on the earlier fence will
 * be dropped.
 * If there is a failure to allocate memory to accommodate the new fence to
 * be added, the new fence will instead be waited for and an error may
 * be returned; depending on the value of @ctx, or if there was a fence
 * error. If an error was returned, the dependency collection will be
 * finalized and all fence reference dropped.
 *
 * Return: 0 if success. Negative error code on error.
 */
int i915_deps_add_dependency(struct i915_deps *deps,
			     struct dma_fence *fence,
			     const struct ttm_operation_ctx *ctx)
{
	unsigned int i;
	int ret;

	if (!fence)
		return 0;

	if (dma_fence_is_signaled(fence)) {
		ret = fence->error;
		if (ret)
			i915_deps_fini(deps);
		return ret;
	}

	for (i = 0; i < deps->num_deps; ++i) {
		struct dma_fence *entry = deps->fences[i];

		if (!entry->context || entry->context != fence->context)
			continue;

		if (dma_fence_is_later(fence, entry)) {
			dma_fence_put(entry);
			deps->fences[i] = dma_fence_get(fence);
		}

		return 0;
	}

	return i915_deps_grow(deps, fence, ctx);
}

/**
 * i915_deps_add_resv - Add the fences of a reservation object to a dependency
 * collection.
 * @deps: Pointer to the i915_deps structure a fence is to be added to.
 * @resv: The reservation object, then fences of which to add.
 * @ctx: Pointer to a struct ttm_operation_ctx indicating how waits are to
 * be performed if waiting.
 *
 * Calls i915_deps_add_depencency() on the indicated fences of @resv.
 *
 * Return: Zero on success. Negative error code on error.
 */
int i915_deps_add_resv(struct i915_deps *deps, struct dma_resv *resv,
		       const struct ttm_operation_ctx *ctx)
{
	struct dma_resv_iter iter;
	struct dma_fence *fence;

	dma_resv_assert_held(resv);
	dma_resv_for_each_fence(&iter, resv, dma_resv_usage_rw(true), fence) {
		int ret = i915_deps_add_dependency(deps, fence, ctx);

		if (ret)
			return ret;
	}

	return 0;
}
