// SPDX-License-Identifier: GPL-2.0

/*
 * Test module for stress and analyze performance of vmalloc allocator.
 * (C) 2018 Uladzislau Rezki (Sony) <urezki@gmail.com>
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/random.h>
#include <linux/kthread.h>
#include <linux/moduleparam.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/rcupdate.h>
#include <linux/srcu.h>
#include <linux/slab.h>

#define __param(type, name, init, msg)		\
	static type name = init;				\
	module_param(name, type, 0444);			\
	MODULE_PARM_DESC(name, msg)				\

__param(int, nr_threads, 0,
	"Number of workers to perform tests(min: 1 max: USHRT_MAX)");

__param(bool, sequential_test_order, false,
	"Use sequential stress tests order");

__param(int, test_repeat_count, 1,
	"Set test repeat counter");

__param(int, test_loop_count, 1000000,
	"Set test loop counter");

__param(int, nr_pages, 0,
	"Set number of pages for fix_size_alloc_test(default: 1)");

__param(bool, use_huge, false,
	"Use vmalloc_huge in fix_size_alloc_test");

__param(int, run_test_mask, 7,
	"Set tests specified in the mask.\n\n"
		"\t\tid: 1,    name: fix_size_alloc_test\n"
		"\t\tid: 2,    name: full_fit_alloc_test\n"
		"\t\tid: 4,    name: long_busy_list_alloc_test\n"
		"\t\tid: 8,    name: random_size_alloc_test\n"
		"\t\tid: 16,   name: fix_align_alloc_test\n"
		"\t\tid: 32,   name: random_size_align_alloc_test\n"
		"\t\tid: 64,   name: align_shift_alloc_test\n"
		"\t\tid: 128,  name: pcpu_alloc_test\n"
		"\t\tid: 256,  name: kvfree_rcu_1_arg_vmalloc_test\n"
		"\t\tid: 512,  name: kvfree_rcu_2_arg_vmalloc_test\n"
		"\t\tid: 1024, name: vm_map_ram_test\n"
		/* Add a new test case description here. */
);

/*
 * This is for synchronization of setup phase.
 */
DEFINE_STATIC_SRCU(prepare_for_test_srcu);

/*
 * Completion tracking for worker threads.
 */
static DECLARE_COMPLETION(test_all_done_comp);
static atomic_t test_n_undone = ATOMIC_INIT(0);

static inline void
test_report_one_done(void)
{
	if (atomic_dec_and_test(&test_n_undone))
		complete(&test_all_done_comp);
}

static int random_size_align_alloc_test(void)
{
	unsigned long size, align;
	unsigned int rnd;
	void *ptr;
	int i;

	for (i = 0; i < test_loop_count; i++) {
		rnd = get_random_u8();

		/*
		 * Maximum 1024 pages, if PAGE_SIZE is 4096.
		 */
		align = 1 << (rnd % 23);

		/*
		 * Maximum 10 pages.
		 */
		size = ((rnd % 10) + 1) * PAGE_SIZE;

		ptr = __vmalloc_node(size, align, GFP_KERNEL | __GFP_ZERO, 0,
				__builtin_return_address(0));
		if (!ptr)
			return -1;

		vfree(ptr);
	}

	return 0;
}

/*
 * This test case is supposed to be failed.
 */
static int align_shift_alloc_test(void)
{
	unsigned long align;
	void *ptr;
	int i;

	for (i = 0; i < BITS_PER_LONG; i++) {
		align = 1UL << i;

		ptr = __vmalloc_node(PAGE_SIZE, align, GFP_KERNEL|__GFP_ZERO, 0,
				__builtin_return_address(0));
		if (!ptr)
			return -1;

		vfree(ptr);
	}

	return 0;
}

static int fix_align_alloc_test(void)
{
	void *ptr;
	int i;

	for (i = 0; i < test_loop_count; i++) {
		ptr = __vmalloc_node(5 * PAGE_SIZE, THREAD_ALIGN << 1,
				GFP_KERNEL | __GFP_ZERO, 0,
				__builtin_return_address(0));
		if (!ptr)
			return -1;

		vfree(ptr);
	}

	return 0;
}

static int random_size_alloc_test(void)
{
	unsigned int n;
	void *p;
	int i;

	for (i = 0; i < test_loop_count; i++) {
		n = get_random_u32_inclusive(1, 100);
		p = vmalloc(n * PAGE_SIZE);

		if (!p)
			return -1;

		*((__u8 *)p) = 1;
		vfree(p);
	}

	return 0;
}

static int long_busy_list_alloc_test(void)
{
	void *ptr_1, *ptr_2;
	void **ptr;
	int rv = -1;
	int i;

	ptr = vmalloc(sizeof(void *) * 15000);
	if (!ptr)
		return rv;

	for (i = 0; i < 15000; i++)
		ptr[i] = vmalloc(1 * PAGE_SIZE);

	for (i = 0; i < test_loop_count; i++) {
		ptr_1 = vmalloc(100 * PAGE_SIZE);
		if (!ptr_1)
			goto leave;

		ptr_2 = vmalloc(1 * PAGE_SIZE);
		if (!ptr_2) {
			vfree(ptr_1);
			goto leave;
		}

		*((__u8 *)ptr_1) = 0;
		*((__u8 *)ptr_2) = 1;

		vfree(ptr_1);
		vfree(ptr_2);
	}

	/*  Success */
	rv = 0;

leave:
	for (i = 0; i < 15000; i++)
		vfree(ptr[i]);

	vfree(ptr);
	return rv;
}

static int full_fit_alloc_test(void)
{
	void **ptr, **junk_ptr, *tmp;
	int junk_length;
	int rv = -1;
	int i;

	junk_length = fls(num_online_cpus());
	junk_length *= (32 * 1024 * 1024 / PAGE_SIZE);

	ptr = vmalloc(sizeof(void *) * junk_length);
	if (!ptr)
		return rv;

	junk_ptr = vmalloc(sizeof(void *) * junk_length);
	if (!junk_ptr) {
		vfree(ptr);
		return rv;
	}

	for (i = 0; i < junk_length; i++) {
		ptr[i] = vmalloc(1 * PAGE_SIZE);
		junk_ptr[i] = vmalloc(1 * PAGE_SIZE);
	}

	for (i = 0; i < junk_length; i++)
		vfree(junk_ptr[i]);

	for (i = 0; i < test_loop_count; i++) {
		tmp = vmalloc(1 * PAGE_SIZE);

		if (!tmp)
			goto error;

		*((__u8 *)tmp) = 1;
		vfree(tmp);
	}

	/* Success */
	rv = 0;

error:
	for (i = 0; i < junk_length; i++)
		vfree(ptr[i]);

	vfree(ptr);
	vfree(junk_ptr);

	return rv;
}

static int fix_size_alloc_test(void)
{
	void *ptr;
	int i;

	for (i = 0; i < test_loop_count; i++) {
		if (use_huge)
			ptr = vmalloc_huge((nr_pages > 0 ? nr_pages:1) * PAGE_SIZE, GFP_KERNEL);
		else
			ptr = vmalloc((nr_pages > 0 ? nr_pages:1) * PAGE_SIZE);

		if (!ptr)
			return -1;

		*((__u8 *)ptr) = 0;

		vfree(ptr);
	}

	return 0;
}

static int
pcpu_alloc_test(void)
{
	int rv = 0;
#ifndef CONFIG_NEED_PER_CPU_KM
	void __percpu **pcpu;
	size_t size, align;
	int i;

	pcpu = vmalloc(sizeof(void __percpu *) * 35000);
	if (!pcpu)
		return -1;

	for (i = 0; i < 35000; i++) {
		size = get_random_u32_inclusive(1, PAGE_SIZE / 4);

		/*
		 * Maximum PAGE_SIZE
		 */
		align = 1 << get_random_u32_inclusive(1, 11);

		pcpu[i] = __alloc_percpu(size, align);
		if (!pcpu[i])
			rv = -1;
	}

	for (i = 0; i < 35000; i++)
		free_percpu(pcpu[i]);

	vfree(pcpu);
#endif
	return rv;
}

struct test_kvfree_rcu {
	struct rcu_head rcu;
	unsigned char array[20];
};

static int
kvfree_rcu_1_arg_vmalloc_test(void)
{
	struct test_kvfree_rcu *p;
	int i;

	for (i = 0; i < test_loop_count; i++) {
		p = vmalloc(1 * PAGE_SIZE);
		if (!p)
			return -1;

		p->array[0] = 'a';
		kvfree_rcu_mightsleep(p);
	}

	return 0;
}

static int
kvfree_rcu_2_arg_vmalloc_test(void)
{
	struct test_kvfree_rcu *p;
	int i;

	for (i = 0; i < test_loop_count; i++) {
		p = vmalloc(1 * PAGE_SIZE);
		if (!p)
			return -1;

		p->array[0] = 'a';
		kvfree_rcu(p, rcu);
	}

	return 0;
}

static int
vm_map_ram_test(void)
{
	unsigned long nr_allocated;
	unsigned int map_nr_pages;
	unsigned char *v_ptr;
	struct page **pages;
	int i;

	map_nr_pages = nr_pages > 0 ? nr_pages:1;
	pages = kcalloc(map_nr_pages, sizeof(struct page *), GFP_KERNEL);
	if (!pages)
		return -1;

	nr_allocated = alloc_pages_bulk(GFP_KERNEL, map_nr_pages, pages);
	if (nr_allocated != map_nr_pages)
		goto cleanup;

	/* Run the test loop. */
	for (i = 0; i < test_loop_count; i++) {
		v_ptr = vm_map_ram(pages, map_nr_pages, NUMA_NO_NODE);
		*v_ptr = 'a';
		vm_unmap_ram(v_ptr, map_nr_pages);
	}

cleanup:
	for (i = 0; i < nr_allocated; i++)
		__free_page(pages[i]);

	kfree(pages);

	/* 0 indicates success. */
	return nr_allocated != map_nr_pages;
}

struct test_case_desc {
	const char *test_name;
	int (*test_func)(void);
	bool xfail;
};

static struct test_case_desc test_case_array[] = {
	{ "fix_size_alloc_test", fix_size_alloc_test, },
	{ "full_fit_alloc_test", full_fit_alloc_test, },
	{ "long_busy_list_alloc_test", long_busy_list_alloc_test, },
	{ "random_size_alloc_test", random_size_alloc_test, },
	{ "fix_align_alloc_test", fix_align_alloc_test, },
	{ "random_size_align_alloc_test", random_size_align_alloc_test, },
	{ "align_shift_alloc_test", align_shift_alloc_test, true },
	{ "pcpu_alloc_test", pcpu_alloc_test, },
	{ "kvfree_rcu_1_arg_vmalloc_test", kvfree_rcu_1_arg_vmalloc_test, },
	{ "kvfree_rcu_2_arg_vmalloc_test", kvfree_rcu_2_arg_vmalloc_test, },
	{ "vm_map_ram_test", vm_map_ram_test, },
	/* Add a new test case here. */
};

struct test_case_data {
	int test_failed;
	int test_xfailed;
	int test_passed;
	u64 time;
};

static struct test_driver {
	struct task_struct *task;
	struct test_case_data data[ARRAY_SIZE(test_case_array)];

	unsigned long start;
	unsigned long stop;
} *tdriver;

static void shuffle_array(int *arr, int n)
{
	int i, j;

	for (i = n - 1; i > 0; i--)  {
		/* Cut the range. */
		j = get_random_u32_below(i);

		/* Swap indexes. */
		swap(arr[i], arr[j]);
	}
}

static int test_func(void *private)
{
	struct test_driver *t = private;
	int random_array[ARRAY_SIZE(test_case_array)];
	int index, i, j, ret;
	ktime_t kt;
	u64 delta;

	for (i = 0; i < ARRAY_SIZE(test_case_array); i++)
		random_array[i] = i;

	if (!sequential_test_order)
		shuffle_array(random_array, ARRAY_SIZE(test_case_array));

	/*
	 * Block until initialization is done.
	 */
	synchronize_srcu(&prepare_for_test_srcu);

	t->start = get_cycles();
	for (i = 0; i < ARRAY_SIZE(test_case_array); i++) {
		index = random_array[i];

		/*
		 * Skip tests if run_test_mask has been specified.
		 */
		if (!((run_test_mask & (1 << index)) >> index))
			continue;
		kt = ktime_get();
		for (j = 0; j < test_repeat_count; j++) {
			ret = test_case_array[index].test_func();

			if (!ret && !test_case_array[index].xfail)
				t->data[index].test_passed++;
			else if (ret && test_case_array[index].xfail)
				t->data[index].test_xfailed++;
			else
				t->data[index].test_failed++;
		}

		/*
		 * Take an average time that test took.
		 */
		delta = (u64) ktime_us_delta(ktime_get(), kt);
		do_div(delta, (u32) test_repeat_count);

		t->data[index].time = delta;
	}
	t->stop = get_cycles();
	test_report_one_done();

	/*
	 * Wait for the kthread_stop() call.
	 */
	while (!kthread_should_stop())
		msleep(10);

	return 0;
}

static int
init_test_configuration(void)
{
	/*
	 * A maximum number of workers is defined as hard-coded
	 * value and set to USHRT_MAX. We add such gap just in
	 * case and for potential heavy stressing.
	 */
	nr_threads = clamp(nr_threads, 1, (int) USHRT_MAX);

	/* Allocate the space for test instances. */
	tdriver = kvcalloc(nr_threads, sizeof(*tdriver), GFP_KERNEL);
	if (tdriver == NULL)
		return -1;

	if (test_repeat_count <= 0)
		test_repeat_count = 1;

	if (test_loop_count <= 0)
		test_loop_count = 1;

	return 0;
}

static void do_concurrent_test(void)
{
	int i, ret, idx;

	/*
	 * Set some basic configurations plus sanity check.
	 */
	ret = init_test_configuration();
	if (ret < 0)
		return;

	/*
	 * Put on hold all workers.
	 */
	idx = srcu_read_lock(&prepare_for_test_srcu);

	for (i = 0; i < nr_threads; i++) {
		struct test_driver *t = &tdriver[i];

		t->task = kthread_run(test_func, t, "vmalloc_test/%d", i);

		if (!IS_ERR(t->task))
			/* Success. */
			atomic_inc(&test_n_undone);
		else
			pr_err("Failed to start %d kthread\n", i);
	}

	/*
	 * Now let the workers do their job.
	 */
	srcu_read_unlock(&prepare_for_test_srcu, idx);

	/*
	 * Sleep quiet until all workers are done with 1 second
	 * interval. Since the test can take a lot of time we
	 * can run into a stack trace of the hung task. That is
	 * why we go with completion_timeout and HZ value.
	 */
	do {
		ret = wait_for_completion_timeout(&test_all_done_comp, HZ);
	} while (!ret);

	for (i = 0; i < nr_threads; i++) {
		struct test_driver *t = &tdriver[i];
		int j;

		if (!IS_ERR(t->task))
			kthread_stop(t->task);

		for (j = 0; j < ARRAY_SIZE(test_case_array); j++) {
			if (!((run_test_mask & (1 << j)) >> j))
				continue;

			pr_info(
				"Summary: %s passed: %d failed: %d xfailed: %d repeat: %d loops: %d avg: %llu usec\n",
				test_case_array[j].test_name,
				t->data[j].test_passed,
				t->data[j].test_failed,
				t->data[j].test_xfailed,
				test_repeat_count, test_loop_count,
				t->data[j].time);
		}

		pr_info("All test took worker%d=%lu cycles\n",
			i, t->stop - t->start);
	}

	kvfree(tdriver);
}

static int __init vmalloc_test_init(void)
{
	do_concurrent_test();
	/* Fail will directly unload the module */
	return IS_BUILTIN(CONFIG_TEST_VMALLOC) ? 0:-EAGAIN;
}

#ifdef MODULE
module_init(vmalloc_test_init)
#else
late_initcall(vmalloc_test_init);
#endif

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Uladzislau Rezki");
MODULE_DESCRIPTION("vmalloc test module");
