/* SPDX-License-Identifier: GPL-2.0 */
/*
 * KUnit resource API for test managed resources (allocations, etc.).
 *
 * Copyright (C) 2022, Google LLC.
 * Author: Daniel Latypov <dlatypov@google.com>
 */

#ifndef _KUNIT_RESOURCE_H
#define _KUNIT_RESOURCE_H

#include <kunit/test.h>

#include <linux/kref.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

struct kunit_resource;

typedef int (*kunit_resource_init_t)(struct kunit_resource *, void *);
typedef void (*kunit_resource_free_t)(struct kunit_resource *);

/**
 * struct kunit_resource - represents a *test managed resource*
 * @data: for the user to store arbitrary data.
 * @name: optional name
 * @free: a user supplied function to free the resource.
 *
 * Represents a *test managed resource*, a resource which will automatically be
 * cleaned up at the end of a test case. This cleanup is performed by the 'free'
 * function. The struct kunit_resource itself is freed automatically with
 * kfree() if it was allocated by KUnit (e.g., by kunit_alloc_resource()), but
 * must be freed by the user otherwise.
 *
 * Resources are reference counted so if a resource is retrieved via
 * kunit_alloc_and_get_resource() or kunit_find_resource(), we need
 * to call kunit_put_resource() to reduce the resource reference count
 * when finished with it.  Note that kunit_alloc_resource() does not require a
 * kunit_resource_put() because it does not retrieve the resource itself.
 *
 * Example:
 *
 * .. code-block:: c
 *
 *	struct kunit_kmalloc_params {
 *		size_t size;
 *		gfp_t gfp;
 *	};
 *
 *	static int kunit_kmalloc_init(struct kunit_resource *res, void *context)
 *	{
 *		struct kunit_kmalloc_params *params = context;
 *		res->data = kmalloc(params->size, params->gfp);
 *
 *		if (!res->data)
 *			return -ENOMEM;
 *
 *		return 0;
 *	}
 *
 *	static void kunit_kmalloc_free(struct kunit_resource *res)
 *	{
 *		kfree(res->data);
 *	}
 *
 *	void *kunit_kmalloc(struct kunit *test, size_t size, gfp_t gfp)
 *	{
 *		struct kunit_kmalloc_params params;
 *
 *		params.size = size;
 *		params.gfp = gfp;
 *
 *		return kunit_alloc_resource(test, kunit_kmalloc_init,
 *			kunit_kmalloc_free, gfp, &params);
 *	}
 *
 * Resources can also be named, with lookup/removal done on a name
 * basis also.  kunit_add_named_resource(), kunit_find_named_resource()
 * and kunit_destroy_named_resource().  Resource names must be
 * unique within the test instance.
 */
struct kunit_resource {
	void *data;
	const char *name;
	kunit_resource_free_t free;

	/* private: internal use only. */
	struct kref refcount;
	struct list_head node;
	bool should_kfree;
};

/**
 * kunit_get_resource() - Hold resource for use.  Should not need to be used
 *			  by most users as we automatically get resources
 *			  retrieved by kunit_find_resource*().
 * @res: resource
 */
static inline void kunit_get_resource(struct kunit_resource *res)
{
	kref_get(&res->refcount);
}

/*
 * Called when refcount reaches zero via kunit_put_resource();
 * should not be called directly.
 */
static inline void kunit_release_resource(struct kref *kref)
{
	struct kunit_resource *res = container_of(kref, struct kunit_resource,
						  refcount);

	if (res->free)
		res->free(res);

	/* 'res' is valid here, as if should_kfree is set, res->free may not free
	 * 'res' itself, just res->data
	 */
	if (res->should_kfree)
		kfree(res);
}

/**
 * kunit_put_resource() - When caller is done with retrieved resource,
 *			  kunit_put_resource() should be called to drop
 *			  reference count.  The resource list maintains
 *			  a reference count on resources, so if no users
 *			  are utilizing a resource and it is removed from
 *			  the resource list, it will be freed via the
 *			  associated free function (if any).  Only
 *			  needs to be used if we alloc_and_get() or
 *			  find() resource.
 * @res: resource
 */
static inline void kunit_put_resource(struct kunit_resource *res)
{
	kref_put(&res->refcount, kunit_release_resource);
}

/**
 * __kunit_add_resource() - Internal helper to add a resource.
 *
 * res->should_kfree is not initialised.
 * @test: The test context object.
 * @init: a user-supplied function to initialize the result (if needed).  If
 *        none is supplied, the resource data value is simply set to @data.
 *	  If an init function is supplied, @data is passed to it instead.
 * @free: a user-supplied function to free the resource (if needed).
 * @res: The resource.
 * @data: value to pass to init function or set in resource data field.
 */
int __kunit_add_resource(struct kunit *test,
			 kunit_resource_init_t init,
			 kunit_resource_free_t free,
			 struct kunit_resource *res,
			 void *data);

/**
 * kunit_add_resource() - Add a *test managed resource*.
 * @test: The test context object.
 * @init: a user-supplied function to initialize the result (if needed).  If
 *        none is supplied, the resource data value is simply set to @data.
 *	  If an init function is supplied, @data is passed to it instead.
 * @free: a user-supplied function to free the resource (if needed).
 * @res: The resource.
 * @data: value to pass to init function or set in resource data field.
 */
static inline int kunit_add_resource(struct kunit *test,
				     kunit_resource_init_t init,
				     kunit_resource_free_t free,
				     struct kunit_resource *res,
				     void *data)
{
	res->should_kfree = false;
	return __kunit_add_resource(test, init, free, res, data);
}

static inline struct kunit_resource *
kunit_find_named_resource(struct kunit *test, const char *name);

/**
 * kunit_add_named_resource() - Add a named *test managed resource*.
 * @test: The test context object.
 * @init: a user-supplied function to initialize the resource data, if needed.
 * @free: a user-supplied function to free the resource data, if needed.
 * @res: The resource.
 * @name: name to be set for resource.
 * @data: value to pass to init function or set in resource data field.
 */
static inline int kunit_add_named_resource(struct kunit *test,
					   kunit_resource_init_t init,
					   kunit_resource_free_t free,
					   struct kunit_resource *res,
					   const char *name,
					   void *data)
{
	struct kunit_resource *existing;

	if (!name)
		return -EINVAL;

	existing = kunit_find_named_resource(test, name);
	if (existing) {
		kunit_put_resource(existing);
		return -EEXIST;
	}

	res->name = name;
	res->should_kfree = false;

	return __kunit_add_resource(test, init, free, res, data);
}

/**
 * kunit_alloc_and_get_resource() - Allocates and returns a *test managed resource*.
 * @test: The test context object.
 * @init: a user supplied function to initialize the resource.
 * @free: a user supplied function to free the resource (if needed).
 * @internal_gfp: gfp to use for internal allocations, if unsure, use GFP_KERNEL
 * @context: for the user to pass in arbitrary data to the init function.
 *
 * Allocates a *test managed resource*, a resource which will automatically be
 * cleaned up at the end of a test case. See &struct kunit_resource for an
 * example.
 *
 * This is effectively identical to kunit_alloc_resource, but returns the
 * struct kunit_resource pointer, not just the 'data' pointer. It therefore
 * also increments the resource's refcount, so kunit_put_resource() should be
 * called when you've finished with it.
 *
 * Note: KUnit needs to allocate memory for a kunit_resource object. You must
 * specify an @internal_gfp that is compatible with the use context of your
 * resource.
 */
static inline struct kunit_resource *
kunit_alloc_and_get_resource(struct kunit *test,
			     kunit_resource_init_t init,
			     kunit_resource_free_t free,
			     gfp_t internal_gfp,
			     void *context)
{
	struct kunit_resource *res;
	int ret;

	res = kzalloc(sizeof(*res), internal_gfp);
	if (!res)
		return NULL;

	res->should_kfree = true;

	ret = __kunit_add_resource(test, init, free, res, context);
	if (!ret) {
		/*
		 * bump refcount for get; kunit_resource_put() should be called
		 * when done.
		 */
		kunit_get_resource(res);
		return res;
	}
	return NULL;
}

/**
 * kunit_alloc_resource() - Allocates a *test managed resource*.
 * @test: The test context object.
 * @init: a user supplied function to initialize the resource.
 * @free: a user supplied function to free the resource (if needed).
 * @internal_gfp: gfp to use for internal allocations, if unsure, use GFP_KERNEL
 * @context: for the user to pass in arbitrary data to the init function.
 *
 * Allocates a *test managed resource*, a resource which will automatically be
 * cleaned up at the end of a test case. See &struct kunit_resource for an
 * example.
 *
 * Note: KUnit needs to allocate memory for a kunit_resource object. You must
 * specify an @internal_gfp that is compatible with the use context of your
 * resource.
 */
static inline void *kunit_alloc_resource(struct kunit *test,
					 kunit_resource_init_t init,
					 kunit_resource_free_t free,
					 gfp_t internal_gfp,
					 void *context)
{
	struct kunit_resource *res;

	res = kzalloc(sizeof(*res), internal_gfp);
	if (!res)
		return NULL;

	res->should_kfree = true;
	if (!__kunit_add_resource(test, init, free, res, context))
		return res->data;

	return NULL;
}

typedef bool (*kunit_resource_match_t)(struct kunit *test,
				       struct kunit_resource *res,
				       void *match_data);

/**
 * kunit_resource_name_match() - Match a resource with the same name.
 * @test: Test case to which the resource belongs.
 * @res: The resource.
 * @match_name: The name to match against.
 */
static inline bool kunit_resource_name_match(struct kunit *test,
					     struct kunit_resource *res,
					     void *match_name)
{
	return res->name && strcmp(res->name, match_name) == 0;
}

/**
 * kunit_find_resource() - Find a resource using match function/data.
 * @test: Test case to which the resource belongs.
 * @match: match function to be applied to resources/match data.
 * @match_data: data to be used in matching.
 */
static inline struct kunit_resource *
kunit_find_resource(struct kunit *test,
		    kunit_resource_match_t match,
		    void *match_data)
{
	struct kunit_resource *res, *found = NULL;
	unsigned long flags;

	spin_lock_irqsave(&test->lock, flags);

	list_for_each_entry_reverse(res, &test->resources, node) {
		if (match(test, res, (void *)match_data)) {
			found = res;
			kunit_get_resource(found);
			break;
		}
	}

	spin_unlock_irqrestore(&test->lock, flags);

	return found;
}

/**
 * kunit_find_named_resource() - Find a resource using match name.
 * @test: Test case to which the resource belongs.
 * @name: match name.
 */
static inline struct kunit_resource *
kunit_find_named_resource(struct kunit *test,
			  const char *name)
{
	return kunit_find_resource(test, kunit_resource_name_match,
				   (void *)name);
}

/**
 * kunit_destroy_resource() - Find a kunit_resource and destroy it.
 * @test: Test case to which the resource belongs.
 * @match: Match function. Returns whether a given resource matches @match_data.
 * @match_data: Data passed into @match.
 *
 * RETURNS:
 * 0 if kunit_resource is found and freed, -ENOENT if not found.
 */
int kunit_destroy_resource(struct kunit *test,
			   kunit_resource_match_t match,
			   void *match_data);

static inline int kunit_destroy_named_resource(struct kunit *test,
					       const char *name)
{
	return kunit_destroy_resource(test, kunit_resource_name_match,
				      (void *)name);
}

/**
 * kunit_remove_resource() - remove resource from resource list associated with
 *			     test.
 * @test: The test context object.
 * @res: The resource to be removed.
 *
 * Note that the resource will not be immediately freed since it is likely
 * the caller has a reference to it via alloc_and_get() or find();
 * in this case a final call to kunit_put_resource() is required.
 */
void kunit_remove_resource(struct kunit *test, struct kunit_resource *res);

/* A 'deferred action' function to be used with kunit_add_action. */
typedef void (kunit_action_t)(void *);

/**
 * kunit_add_action() - Call a function when the test ends.
 * @test: Test case to associate the action with.
 * @action: The function to run on test exit
 * @ctx: Data passed into @func
 *
 * Defer the execution of a function until the test exits, either normally or
 * due to a failure.  @ctx is passed as additional context. All functions
 * registered with kunit_add_action() will execute in the opposite order to that
 * they were registered in.
 *
 * This is useful for cleaning up allocated memory and resources, as these
 * functions are called even if the test aborts early due to, e.g., a failed
 * assertion.
 *
 * See also: devm_add_action() for the devres equivalent.
 *
 * Returns:
 *   0 on success, an error if the action could not be deferred.
 */
int kunit_add_action(struct kunit *test, kunit_action_t *action, void *ctx);

/**
 * kunit_add_action_or_reset() - Call a function when the test ends.
 * @test: Test case to associate the action with.
 * @action: The function to run on test exit
 * @ctx: Data passed into @func
 *
 * Defer the execution of a function until the test exits, either normally or
 * due to a failure.  @ctx is passed as additional context. All functions
 * registered with kunit_add_action() will execute in the opposite order to that
 * they were registered in.
 *
 * This is useful for cleaning up allocated memory and resources, as these
 * functions are called even if the test aborts early due to, e.g., a failed
 * assertion.
 *
 * If the action cannot be created (e.g., due to the system being out of memory),
 * then action(ctx) will be called immediately, and an error will be returned.
 *
 * See also: devm_add_action_or_reset() for the devres equivalent.
 *
 * Returns:
 *   0 on success, an error if the action could not be deferred.
 */
int kunit_add_action_or_reset(struct kunit *test, kunit_action_t *action,
			      void *ctx);

/**
 * kunit_remove_action() - Cancel a matching deferred action.
 * @test: Test case the action is associated with.
 * @action: The deferred function to cancel.
 * @ctx: The context passed to the deferred function to trigger.
 *
 * Prevent an action deferred via kunit_add_action() from executing when the
 * test terminates.
 *
 * If the function/context pair was deferred multiple times, only the most
 * recent one will be cancelled.
 *
 * See also: devm_remove_action() for the devres equivalent.
 */
void kunit_remove_action(struct kunit *test,
			 kunit_action_t *action,
			 void *ctx);

/**
 * kunit_release_action() - Run a matching action call immediately.
 * @test: Test case the action is associated with.
 * @action: The deferred function to trigger.
 * @ctx: The context passed to the deferred function to trigger.
 *
 * Execute a function deferred via kunit_add_action()) immediately, rather than
 * when the test ends.
 *
 * If the function/context pair was deferred multiple times, it will only be
 * executed once here. The most recent deferral will no longer execute when
 * the test ends.
 *
 * kunit_release_action(test, func, ctx);
 * is equivalent to
 * func(ctx);
 * kunit_remove_action(test, func, ctx);
 *
 * See also: devm_release_action() for the devres equivalent.
 */
void kunit_release_action(struct kunit *test,
			  kunit_action_t *action,
			  void *ctx);
#endif /* _KUNIT_RESOURCE_H */
