162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * lib/test_parman.c - Test module for parman
362306a36Sopenharmony_ci * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
462306a36Sopenharmony_ci * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com>
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without
762306a36Sopenharmony_ci * modification, are permitted provided that the following conditions are met:
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright
1062306a36Sopenharmony_ci *    notice, this list of conditions and the following disclaimer.
1162306a36Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright
1262306a36Sopenharmony_ci *    notice, this list of conditions and the following disclaimer in the
1362306a36Sopenharmony_ci *    documentation and/or other materials provided with the distribution.
1462306a36Sopenharmony_ci * 3. Neither the names of the copyright holders nor the names of its
1562306a36Sopenharmony_ci *    contributors may be used to endorse or promote products derived from
1662306a36Sopenharmony_ci *    this software without specific prior written permission.
1762306a36Sopenharmony_ci *
1862306a36Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the
1962306a36Sopenharmony_ci * GNU General Public License ("GPL") version 2 as published by the Free
2062306a36Sopenharmony_ci * Software Foundation.
2162306a36Sopenharmony_ci *
2262306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2362306a36Sopenharmony_ci * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2462306a36Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2562306a36Sopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2662306a36Sopenharmony_ci * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2762306a36Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2862306a36Sopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2962306a36Sopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3062306a36Sopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3162306a36Sopenharmony_ci * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3262306a36Sopenharmony_ci * POSSIBILITY OF SUCH DAMAGE.
3362306a36Sopenharmony_ci */
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#include <linux/kernel.h>
3862306a36Sopenharmony_ci#include <linux/module.h>
3962306a36Sopenharmony_ci#include <linux/slab.h>
4062306a36Sopenharmony_ci#include <linux/bitops.h>
4162306a36Sopenharmony_ci#include <linux/err.h>
4262306a36Sopenharmony_ci#include <linux/random.h>
4362306a36Sopenharmony_ci#include <linux/parman.h>
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#define TEST_PARMAN_PRIO_SHIFT 7 /* defines number of prios for testing */
4662306a36Sopenharmony_ci#define TEST_PARMAN_PRIO_COUNT BIT(TEST_PARMAN_PRIO_SHIFT)
4762306a36Sopenharmony_ci#define TEST_PARMAN_PRIO_MASK (TEST_PARMAN_PRIO_COUNT - 1)
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci#define TEST_PARMAN_ITEM_SHIFT 13 /* defines a total number
5062306a36Sopenharmony_ci				   * of items for testing
5162306a36Sopenharmony_ci				   */
5262306a36Sopenharmony_ci#define TEST_PARMAN_ITEM_COUNT BIT(TEST_PARMAN_ITEM_SHIFT)
5362306a36Sopenharmony_ci#define TEST_PARMAN_ITEM_MASK (TEST_PARMAN_ITEM_COUNT - 1)
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci#define TEST_PARMAN_BASE_SHIFT 8
5662306a36Sopenharmony_ci#define TEST_PARMAN_BASE_COUNT BIT(TEST_PARMAN_BASE_SHIFT)
5762306a36Sopenharmony_ci#define TEST_PARMAN_RESIZE_STEP_SHIFT 7
5862306a36Sopenharmony_ci#define TEST_PARMAN_RESIZE_STEP_COUNT BIT(TEST_PARMAN_RESIZE_STEP_SHIFT)
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci#define TEST_PARMAN_BULK_MAX_SHIFT (2 + TEST_PARMAN_RESIZE_STEP_SHIFT)
6162306a36Sopenharmony_ci#define TEST_PARMAN_BULK_MAX_COUNT BIT(TEST_PARMAN_BULK_MAX_SHIFT)
6262306a36Sopenharmony_ci#define TEST_PARMAN_BULK_MAX_MASK (TEST_PARMAN_BULK_MAX_COUNT - 1)
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci#define TEST_PARMAN_RUN_BUDGET (TEST_PARMAN_ITEM_COUNT * 256)
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistruct test_parman_prio {
6762306a36Sopenharmony_ci	struct parman_prio parman_prio;
6862306a36Sopenharmony_ci	unsigned long priority;
6962306a36Sopenharmony_ci};
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistruct test_parman_item {
7262306a36Sopenharmony_ci	struct parman_item parman_item;
7362306a36Sopenharmony_ci	struct test_parman_prio *prio;
7462306a36Sopenharmony_ci	bool used;
7562306a36Sopenharmony_ci};
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_cistruct test_parman {
7862306a36Sopenharmony_ci	struct parman *parman;
7962306a36Sopenharmony_ci	struct test_parman_item **prio_array;
8062306a36Sopenharmony_ci	unsigned long prio_array_limit;
8162306a36Sopenharmony_ci	struct test_parman_prio prios[TEST_PARMAN_PRIO_COUNT];
8262306a36Sopenharmony_ci	struct test_parman_item items[TEST_PARMAN_ITEM_COUNT];
8362306a36Sopenharmony_ci	struct rnd_state rnd;
8462306a36Sopenharmony_ci	unsigned long run_budget;
8562306a36Sopenharmony_ci	unsigned long bulk_budget;
8662306a36Sopenharmony_ci	bool bulk_noop;
8762306a36Sopenharmony_ci	unsigned int used_items;
8862306a36Sopenharmony_ci};
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci#define ITEM_PTRS_SIZE(count) (sizeof(struct test_parman_item *) * (count))
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cistatic int test_parman_resize(void *priv, unsigned long new_count)
9362306a36Sopenharmony_ci{
9462306a36Sopenharmony_ci	struct test_parman *test_parman = priv;
9562306a36Sopenharmony_ci	struct test_parman_item **prio_array;
9662306a36Sopenharmony_ci	unsigned long old_count;
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	prio_array = krealloc(test_parman->prio_array,
9962306a36Sopenharmony_ci			      ITEM_PTRS_SIZE(new_count), GFP_KERNEL);
10062306a36Sopenharmony_ci	if (new_count == 0)
10162306a36Sopenharmony_ci		return 0;
10262306a36Sopenharmony_ci	if (!prio_array)
10362306a36Sopenharmony_ci		return -ENOMEM;
10462306a36Sopenharmony_ci	old_count = test_parman->prio_array_limit;
10562306a36Sopenharmony_ci	if (new_count > old_count)
10662306a36Sopenharmony_ci		memset(&prio_array[old_count], 0,
10762306a36Sopenharmony_ci		       ITEM_PTRS_SIZE(new_count - old_count));
10862306a36Sopenharmony_ci	test_parman->prio_array = prio_array;
10962306a36Sopenharmony_ci	test_parman->prio_array_limit = new_count;
11062306a36Sopenharmony_ci	return 0;
11162306a36Sopenharmony_ci}
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_cistatic void test_parman_move(void *priv, unsigned long from_index,
11462306a36Sopenharmony_ci			     unsigned long to_index, unsigned long count)
11562306a36Sopenharmony_ci{
11662306a36Sopenharmony_ci	struct test_parman *test_parman = priv;
11762306a36Sopenharmony_ci	struct test_parman_item **prio_array = test_parman->prio_array;
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci	memmove(&prio_array[to_index], &prio_array[from_index],
12062306a36Sopenharmony_ci		ITEM_PTRS_SIZE(count));
12162306a36Sopenharmony_ci	memset(&prio_array[from_index], 0, ITEM_PTRS_SIZE(count));
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_cistatic const struct parman_ops test_parman_lsort_ops = {
12562306a36Sopenharmony_ci	.base_count	= TEST_PARMAN_BASE_COUNT,
12662306a36Sopenharmony_ci	.resize_step	= TEST_PARMAN_RESIZE_STEP_COUNT,
12762306a36Sopenharmony_ci	.resize		= test_parman_resize,
12862306a36Sopenharmony_ci	.move		= test_parman_move,
12962306a36Sopenharmony_ci	.algo		= PARMAN_ALGO_TYPE_LSORT,
13062306a36Sopenharmony_ci};
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_cistatic void test_parman_rnd_init(struct test_parman *test_parman)
13362306a36Sopenharmony_ci{
13462306a36Sopenharmony_ci	prandom_seed_state(&test_parman->rnd, 3141592653589793238ULL);
13562306a36Sopenharmony_ci}
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_cistatic u32 test_parman_rnd_get(struct test_parman *test_parman)
13862306a36Sopenharmony_ci{
13962306a36Sopenharmony_ci	return prandom_u32_state(&test_parman->rnd);
14062306a36Sopenharmony_ci}
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistatic unsigned long test_parman_priority_gen(struct test_parman *test_parman)
14362306a36Sopenharmony_ci{
14462306a36Sopenharmony_ci	unsigned long priority;
14562306a36Sopenharmony_ci	int i;
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ciagain:
14862306a36Sopenharmony_ci	priority = test_parman_rnd_get(test_parman);
14962306a36Sopenharmony_ci	if (priority == 0)
15062306a36Sopenharmony_ci		goto again;
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	for (i = 0; i < TEST_PARMAN_PRIO_COUNT; i++) {
15362306a36Sopenharmony_ci		struct test_parman_prio *prio = &test_parman->prios[i];
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci		if (prio->priority == 0)
15662306a36Sopenharmony_ci			break;
15762306a36Sopenharmony_ci		if (prio->priority == priority)
15862306a36Sopenharmony_ci			goto again;
15962306a36Sopenharmony_ci	}
16062306a36Sopenharmony_ci	return priority;
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistatic void test_parman_prios_init(struct test_parman *test_parman)
16462306a36Sopenharmony_ci{
16562306a36Sopenharmony_ci	int i;
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci	for (i = 0; i < TEST_PARMAN_PRIO_COUNT; i++) {
16862306a36Sopenharmony_ci		struct test_parman_prio *prio = &test_parman->prios[i];
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci		/* Assign random uniqueue priority to each prio structure */
17162306a36Sopenharmony_ci		prio->priority = test_parman_priority_gen(test_parman);
17262306a36Sopenharmony_ci		parman_prio_init(test_parman->parman, &prio->parman_prio,
17362306a36Sopenharmony_ci				 prio->priority);
17462306a36Sopenharmony_ci	}
17562306a36Sopenharmony_ci}
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_cistatic void test_parman_prios_fini(struct test_parman *test_parman)
17862306a36Sopenharmony_ci{
17962306a36Sopenharmony_ci	int i;
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	for (i = 0; i < TEST_PARMAN_PRIO_COUNT; i++) {
18262306a36Sopenharmony_ci		struct test_parman_prio *prio = &test_parman->prios[i];
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci		parman_prio_fini(&prio->parman_prio);
18562306a36Sopenharmony_ci	}
18662306a36Sopenharmony_ci}
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_cistatic void test_parman_items_init(struct test_parman *test_parman)
18962306a36Sopenharmony_ci{
19062306a36Sopenharmony_ci	int i;
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci	for (i = 0; i < TEST_PARMAN_ITEM_COUNT; i++) {
19362306a36Sopenharmony_ci		struct test_parman_item *item = &test_parman->items[i];
19462306a36Sopenharmony_ci		unsigned int prio_index = test_parman_rnd_get(test_parman) &
19562306a36Sopenharmony_ci					  TEST_PARMAN_PRIO_MASK;
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci		/* Assign random prio to each item structure */
19862306a36Sopenharmony_ci		item->prio = &test_parman->prios[prio_index];
19962306a36Sopenharmony_ci	}
20062306a36Sopenharmony_ci}
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_cistatic void test_parman_items_fini(struct test_parman *test_parman)
20362306a36Sopenharmony_ci{
20462306a36Sopenharmony_ci	int i;
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	for (i = 0; i < TEST_PARMAN_ITEM_COUNT; i++) {
20762306a36Sopenharmony_ci		struct test_parman_item *item = &test_parman->items[i];
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci		if (!item->used)
21062306a36Sopenharmony_ci			continue;
21162306a36Sopenharmony_ci		parman_item_remove(test_parman->parman,
21262306a36Sopenharmony_ci				   &item->prio->parman_prio,
21362306a36Sopenharmony_ci				   &item->parman_item);
21462306a36Sopenharmony_ci	}
21562306a36Sopenharmony_ci}
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_cistatic struct test_parman *test_parman_create(const struct parman_ops *ops)
21862306a36Sopenharmony_ci{
21962306a36Sopenharmony_ci	struct test_parman *test_parman;
22062306a36Sopenharmony_ci	int err;
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	test_parman = kzalloc(sizeof(*test_parman), GFP_KERNEL);
22362306a36Sopenharmony_ci	if (!test_parman)
22462306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
22562306a36Sopenharmony_ci	err = test_parman_resize(test_parman, TEST_PARMAN_BASE_COUNT);
22662306a36Sopenharmony_ci	if (err)
22762306a36Sopenharmony_ci		goto err_resize;
22862306a36Sopenharmony_ci	test_parman->parman = parman_create(ops, test_parman);
22962306a36Sopenharmony_ci	if (!test_parman->parman) {
23062306a36Sopenharmony_ci		err = -ENOMEM;
23162306a36Sopenharmony_ci		goto err_parman_create;
23262306a36Sopenharmony_ci	}
23362306a36Sopenharmony_ci	test_parman_rnd_init(test_parman);
23462306a36Sopenharmony_ci	test_parman_prios_init(test_parman);
23562306a36Sopenharmony_ci	test_parman_items_init(test_parman);
23662306a36Sopenharmony_ci	test_parman->run_budget = TEST_PARMAN_RUN_BUDGET;
23762306a36Sopenharmony_ci	return test_parman;
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_cierr_parman_create:
24062306a36Sopenharmony_ci	test_parman_resize(test_parman, 0);
24162306a36Sopenharmony_cierr_resize:
24262306a36Sopenharmony_ci	kfree(test_parman);
24362306a36Sopenharmony_ci	return ERR_PTR(err);
24462306a36Sopenharmony_ci}
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_cistatic void test_parman_destroy(struct test_parman *test_parman)
24762306a36Sopenharmony_ci{
24862306a36Sopenharmony_ci	test_parman_items_fini(test_parman);
24962306a36Sopenharmony_ci	test_parman_prios_fini(test_parman);
25062306a36Sopenharmony_ci	parman_destroy(test_parman->parman);
25162306a36Sopenharmony_ci	test_parman_resize(test_parman, 0);
25262306a36Sopenharmony_ci	kfree(test_parman);
25362306a36Sopenharmony_ci}
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_cistatic bool test_parman_run_check_budgets(struct test_parman *test_parman)
25662306a36Sopenharmony_ci{
25762306a36Sopenharmony_ci	if (test_parman->run_budget-- == 0)
25862306a36Sopenharmony_ci		return false;
25962306a36Sopenharmony_ci	if (test_parman->bulk_budget-- != 0)
26062306a36Sopenharmony_ci		return true;
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci	test_parman->bulk_budget = test_parman_rnd_get(test_parman) &
26362306a36Sopenharmony_ci				   TEST_PARMAN_BULK_MAX_MASK;
26462306a36Sopenharmony_ci	test_parman->bulk_noop = test_parman_rnd_get(test_parman) & 1;
26562306a36Sopenharmony_ci	return true;
26662306a36Sopenharmony_ci}
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_cistatic int test_parman_run(struct test_parman *test_parman)
26962306a36Sopenharmony_ci{
27062306a36Sopenharmony_ci	unsigned int i = test_parman_rnd_get(test_parman);
27162306a36Sopenharmony_ci	int err;
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci	while (test_parman_run_check_budgets(test_parman)) {
27462306a36Sopenharmony_ci		unsigned int item_index = i++ & TEST_PARMAN_ITEM_MASK;
27562306a36Sopenharmony_ci		struct test_parman_item *item = &test_parman->items[item_index];
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci		if (test_parman->bulk_noop)
27862306a36Sopenharmony_ci			continue;
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci		if (!item->used) {
28162306a36Sopenharmony_ci			err = parman_item_add(test_parman->parman,
28262306a36Sopenharmony_ci					      &item->prio->parman_prio,
28362306a36Sopenharmony_ci					      &item->parman_item);
28462306a36Sopenharmony_ci			if (err)
28562306a36Sopenharmony_ci				return err;
28662306a36Sopenharmony_ci			test_parman->prio_array[item->parman_item.index] = item;
28762306a36Sopenharmony_ci			test_parman->used_items++;
28862306a36Sopenharmony_ci		} else {
28962306a36Sopenharmony_ci			test_parman->prio_array[item->parman_item.index] = NULL;
29062306a36Sopenharmony_ci			parman_item_remove(test_parman->parman,
29162306a36Sopenharmony_ci					   &item->prio->parman_prio,
29262306a36Sopenharmony_ci					   &item->parman_item);
29362306a36Sopenharmony_ci			test_parman->used_items--;
29462306a36Sopenharmony_ci		}
29562306a36Sopenharmony_ci		item->used = !item->used;
29662306a36Sopenharmony_ci	}
29762306a36Sopenharmony_ci	return 0;
29862306a36Sopenharmony_ci}
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_cistatic int test_parman_check_array(struct test_parman *test_parman,
30162306a36Sopenharmony_ci				   bool gaps_allowed)
30262306a36Sopenharmony_ci{
30362306a36Sopenharmony_ci	unsigned int last_unused_items = 0;
30462306a36Sopenharmony_ci	unsigned long last_priority = 0;
30562306a36Sopenharmony_ci	unsigned int used_items = 0;
30662306a36Sopenharmony_ci	int i;
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci	if (test_parman->prio_array_limit < TEST_PARMAN_BASE_COUNT) {
30962306a36Sopenharmony_ci		pr_err("Array limit is lower than the base count (%lu < %lu)\n",
31062306a36Sopenharmony_ci		       test_parman->prio_array_limit, TEST_PARMAN_BASE_COUNT);
31162306a36Sopenharmony_ci		return -EINVAL;
31262306a36Sopenharmony_ci	}
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci	for (i = 0; i < test_parman->prio_array_limit; i++) {
31562306a36Sopenharmony_ci		struct test_parman_item *item = test_parman->prio_array[i];
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci		if (!item) {
31862306a36Sopenharmony_ci			last_unused_items++;
31962306a36Sopenharmony_ci			continue;
32062306a36Sopenharmony_ci		}
32162306a36Sopenharmony_ci		if (last_unused_items && !gaps_allowed) {
32262306a36Sopenharmony_ci			pr_err("Gap found in array even though they are forbidden\n");
32362306a36Sopenharmony_ci			return -EINVAL;
32462306a36Sopenharmony_ci		}
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci		last_unused_items = 0;
32762306a36Sopenharmony_ci		used_items++;
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci		if (item->prio->priority < last_priority) {
33062306a36Sopenharmony_ci			pr_err("Item belongs under higher priority then the last one (current: %lu, previous: %lu)\n",
33162306a36Sopenharmony_ci			       item->prio->priority, last_priority);
33262306a36Sopenharmony_ci			return -EINVAL;
33362306a36Sopenharmony_ci		}
33462306a36Sopenharmony_ci		last_priority = item->prio->priority;
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci		if (item->parman_item.index != i) {
33762306a36Sopenharmony_ci			pr_err("Item has different index in compare to where it actually is (%lu != %d)\n",
33862306a36Sopenharmony_ci			       item->parman_item.index, i);
33962306a36Sopenharmony_ci			return -EINVAL;
34062306a36Sopenharmony_ci		}
34162306a36Sopenharmony_ci	}
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	if (used_items != test_parman->used_items) {
34462306a36Sopenharmony_ci		pr_err("Number of used items in array does not match (%u != %u)\n",
34562306a36Sopenharmony_ci		       used_items, test_parman->used_items);
34662306a36Sopenharmony_ci		return -EINVAL;
34762306a36Sopenharmony_ci	}
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	if (last_unused_items >= TEST_PARMAN_RESIZE_STEP_COUNT) {
35062306a36Sopenharmony_ci		pr_err("Number of unused item at the end of array is bigger than resize step (%u >= %lu)\n",
35162306a36Sopenharmony_ci		       last_unused_items, TEST_PARMAN_RESIZE_STEP_COUNT);
35262306a36Sopenharmony_ci		return -EINVAL;
35362306a36Sopenharmony_ci	}
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	pr_info("Priority array check successful\n");
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci	return 0;
35862306a36Sopenharmony_ci}
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_cistatic int test_parman_lsort(void)
36162306a36Sopenharmony_ci{
36262306a36Sopenharmony_ci	struct test_parman *test_parman;
36362306a36Sopenharmony_ci	int err;
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	test_parman = test_parman_create(&test_parman_lsort_ops);
36662306a36Sopenharmony_ci	if (IS_ERR(test_parman))
36762306a36Sopenharmony_ci		return PTR_ERR(test_parman);
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	err = test_parman_run(test_parman);
37062306a36Sopenharmony_ci	if (err)
37162306a36Sopenharmony_ci		goto out;
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	err = test_parman_check_array(test_parman, false);
37462306a36Sopenharmony_ci	if (err)
37562306a36Sopenharmony_ci		goto out;
37662306a36Sopenharmony_ciout:
37762306a36Sopenharmony_ci	test_parman_destroy(test_parman);
37862306a36Sopenharmony_ci	return err;
37962306a36Sopenharmony_ci}
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_cistatic int __init test_parman_init(void)
38262306a36Sopenharmony_ci{
38362306a36Sopenharmony_ci	return test_parman_lsort();
38462306a36Sopenharmony_ci}
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_cistatic void __exit test_parman_exit(void)
38762306a36Sopenharmony_ci{
38862306a36Sopenharmony_ci}
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_cimodule_init(test_parman_init);
39162306a36Sopenharmony_cimodule_exit(test_parman_exit);
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL");
39462306a36Sopenharmony_ciMODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
39562306a36Sopenharmony_ciMODULE_DESCRIPTION("Test module for parman");
396