xref: /linux/lib/test_parman.c (revision 8118b7b7)
144091d29SJiri Pirko /*
244091d29SJiri Pirko  * lib/test_parman.c - Test module for parman
344091d29SJiri Pirko  * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
444091d29SJiri Pirko  * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com>
544091d29SJiri Pirko  *
644091d29SJiri Pirko  * Redistribution and use in source and binary forms, with or without
744091d29SJiri Pirko  * modification, are permitted provided that the following conditions are met:
844091d29SJiri Pirko  *
944091d29SJiri Pirko  * 1. Redistributions of source code must retain the above copyright
1044091d29SJiri Pirko  *    notice, this list of conditions and the following disclaimer.
1144091d29SJiri Pirko  * 2. Redistributions in binary form must reproduce the above copyright
1244091d29SJiri Pirko  *    notice, this list of conditions and the following disclaimer in the
1344091d29SJiri Pirko  *    documentation and/or other materials provided with the distribution.
1444091d29SJiri Pirko  * 3. Neither the names of the copyright holders nor the names of its
1544091d29SJiri Pirko  *    contributors may be used to endorse or promote products derived from
1644091d29SJiri Pirko  *    this software without specific prior written permission.
1744091d29SJiri Pirko  *
1844091d29SJiri Pirko  * Alternatively, this software may be distributed under the terms of the
1944091d29SJiri Pirko  * GNU General Public License ("GPL") version 2 as published by the Free
2044091d29SJiri Pirko  * Software Foundation.
2144091d29SJiri Pirko  *
2244091d29SJiri Pirko  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2344091d29SJiri Pirko  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2444091d29SJiri Pirko  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2544091d29SJiri Pirko  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2644091d29SJiri Pirko  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2744091d29SJiri Pirko  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2844091d29SJiri Pirko  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2944091d29SJiri Pirko  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3044091d29SJiri Pirko  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3144091d29SJiri Pirko  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3244091d29SJiri Pirko  * POSSIBILITY OF SUCH DAMAGE.
3344091d29SJiri Pirko  */
3444091d29SJiri Pirko 
3544091d29SJiri Pirko #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
3644091d29SJiri Pirko 
3744091d29SJiri Pirko #include <linux/kernel.h>
3844091d29SJiri Pirko #include <linux/module.h>
3944091d29SJiri Pirko #include <linux/slab.h>
4044091d29SJiri Pirko #include <linux/bitops.h>
4144091d29SJiri Pirko #include <linux/err.h>
4244091d29SJiri Pirko #include <linux/random.h>
4344091d29SJiri Pirko #include <linux/parman.h>
4444091d29SJiri Pirko 
4544091d29SJiri Pirko #define TEST_PARMAN_PRIO_SHIFT 7 /* defines number of prios for testing */
4644091d29SJiri Pirko #define TEST_PARMAN_PRIO_COUNT BIT(TEST_PARMAN_PRIO_SHIFT)
4744091d29SJiri Pirko #define TEST_PARMAN_PRIO_MASK (TEST_PARMAN_PRIO_COUNT - 1)
4844091d29SJiri Pirko 
4944091d29SJiri Pirko #define TEST_PARMAN_ITEM_SHIFT 13 /* defines a total number
5044091d29SJiri Pirko 				   * of items for testing
5144091d29SJiri Pirko 				   */
5244091d29SJiri Pirko #define TEST_PARMAN_ITEM_COUNT BIT(TEST_PARMAN_ITEM_SHIFT)
5344091d29SJiri Pirko #define TEST_PARMAN_ITEM_MASK (TEST_PARMAN_ITEM_COUNT - 1)
5444091d29SJiri Pirko 
5544091d29SJiri Pirko #define TEST_PARMAN_BASE_SHIFT 8
5644091d29SJiri Pirko #define TEST_PARMAN_BASE_COUNT BIT(TEST_PARMAN_BASE_SHIFT)
5744091d29SJiri Pirko #define TEST_PARMAN_RESIZE_STEP_SHIFT 7
5844091d29SJiri Pirko #define TEST_PARMAN_RESIZE_STEP_COUNT BIT(TEST_PARMAN_RESIZE_STEP_SHIFT)
5944091d29SJiri Pirko 
6044091d29SJiri Pirko #define TEST_PARMAN_BULK_MAX_SHIFT (2 + TEST_PARMAN_RESIZE_STEP_SHIFT)
6144091d29SJiri Pirko #define TEST_PARMAN_BULK_MAX_COUNT BIT(TEST_PARMAN_BULK_MAX_SHIFT)
6244091d29SJiri Pirko #define TEST_PARMAN_BULK_MAX_MASK (TEST_PARMAN_BULK_MAX_COUNT - 1)
6344091d29SJiri Pirko 
6444091d29SJiri Pirko #define TEST_PARMAN_RUN_BUDGET (TEST_PARMAN_ITEM_COUNT * 256)
6544091d29SJiri Pirko 
6644091d29SJiri Pirko struct test_parman_prio {
6744091d29SJiri Pirko 	struct parman_prio parman_prio;
6844091d29SJiri Pirko 	unsigned long priority;
6944091d29SJiri Pirko };
7044091d29SJiri Pirko 
7144091d29SJiri Pirko struct test_parman_item {
7244091d29SJiri Pirko 	struct parman_item parman_item;
7344091d29SJiri Pirko 	struct test_parman_prio *prio;
7444091d29SJiri Pirko 	bool used;
7544091d29SJiri Pirko };
7644091d29SJiri Pirko 
7744091d29SJiri Pirko struct test_parman {
7844091d29SJiri Pirko 	struct parman *parman;
7944091d29SJiri Pirko 	struct test_parman_item **prio_array;
8044091d29SJiri Pirko 	unsigned long prio_array_limit;
8144091d29SJiri Pirko 	struct test_parman_prio prios[TEST_PARMAN_PRIO_COUNT];
8244091d29SJiri Pirko 	struct test_parman_item items[TEST_PARMAN_ITEM_COUNT];
8344091d29SJiri Pirko 	struct rnd_state rnd;
8444091d29SJiri Pirko 	unsigned long run_budget;
8544091d29SJiri Pirko 	unsigned long bulk_budget;
8644091d29SJiri Pirko 	bool bulk_noop;
8744091d29SJiri Pirko 	unsigned int used_items;
8844091d29SJiri Pirko };
8944091d29SJiri Pirko 
9044091d29SJiri Pirko #define ITEM_PTRS_SIZE(count) (sizeof(struct test_parman_item *) * (count))
9144091d29SJiri Pirko 
test_parman_resize(void * priv,unsigned long new_count)9244091d29SJiri Pirko static int test_parman_resize(void *priv, unsigned long new_count)
9344091d29SJiri Pirko {
9444091d29SJiri Pirko 	struct test_parman *test_parman = priv;
9544091d29SJiri Pirko 	struct test_parman_item **prio_array;
9644091d29SJiri Pirko 	unsigned long old_count;
9744091d29SJiri Pirko 
9844091d29SJiri Pirko 	prio_array = krealloc(test_parman->prio_array,
9944091d29SJiri Pirko 			      ITEM_PTRS_SIZE(new_count), GFP_KERNEL);
10044091d29SJiri Pirko 	if (new_count == 0)
10144091d29SJiri Pirko 		return 0;
10244091d29SJiri Pirko 	if (!prio_array)
10344091d29SJiri Pirko 		return -ENOMEM;
10444091d29SJiri Pirko 	old_count = test_parman->prio_array_limit;
10544091d29SJiri Pirko 	if (new_count > old_count)
10644091d29SJiri Pirko 		memset(&prio_array[old_count], 0,
10744091d29SJiri Pirko 		       ITEM_PTRS_SIZE(new_count - old_count));
10844091d29SJiri Pirko 	test_parman->prio_array = prio_array;
10944091d29SJiri Pirko 	test_parman->prio_array_limit = new_count;
11044091d29SJiri Pirko 	return 0;
11144091d29SJiri Pirko }
11244091d29SJiri Pirko 
test_parman_move(void * priv,unsigned long from_index,unsigned long to_index,unsigned long count)11344091d29SJiri Pirko static void test_parman_move(void *priv, unsigned long from_index,
11444091d29SJiri Pirko 			     unsigned long to_index, unsigned long count)
11544091d29SJiri Pirko {
11644091d29SJiri Pirko 	struct test_parman *test_parman = priv;
11744091d29SJiri Pirko 	struct test_parman_item **prio_array = test_parman->prio_array;
11844091d29SJiri Pirko 
11944091d29SJiri Pirko 	memmove(&prio_array[to_index], &prio_array[from_index],
12044091d29SJiri Pirko 		ITEM_PTRS_SIZE(count));
12144091d29SJiri Pirko 	memset(&prio_array[from_index], 0, ITEM_PTRS_SIZE(count));
12244091d29SJiri Pirko }
12344091d29SJiri Pirko 
12444091d29SJiri Pirko static const struct parman_ops test_parman_lsort_ops = {
12544091d29SJiri Pirko 	.base_count	= TEST_PARMAN_BASE_COUNT,
12644091d29SJiri Pirko 	.resize_step	= TEST_PARMAN_RESIZE_STEP_COUNT,
12744091d29SJiri Pirko 	.resize		= test_parman_resize,
12844091d29SJiri Pirko 	.move		= test_parman_move,
12944091d29SJiri Pirko 	.algo		= PARMAN_ALGO_TYPE_LSORT,
13044091d29SJiri Pirko };
13144091d29SJiri Pirko 
test_parman_rnd_init(struct test_parman * test_parman)13244091d29SJiri Pirko static void test_parman_rnd_init(struct test_parman *test_parman)
13344091d29SJiri Pirko {
13444091d29SJiri Pirko 	prandom_seed_state(&test_parman->rnd, 3141592653589793238ULL);
13544091d29SJiri Pirko }
13644091d29SJiri Pirko 
test_parman_rnd_get(struct test_parman * test_parman)13744091d29SJiri Pirko static u32 test_parman_rnd_get(struct test_parman *test_parman)
13844091d29SJiri Pirko {
13944091d29SJiri Pirko 	return prandom_u32_state(&test_parman->rnd);
14044091d29SJiri Pirko }
14144091d29SJiri Pirko 
test_parman_priority_gen(struct test_parman * test_parman)14244091d29SJiri Pirko static unsigned long test_parman_priority_gen(struct test_parman *test_parman)
14344091d29SJiri Pirko {
14444091d29SJiri Pirko 	unsigned long priority;
14544091d29SJiri Pirko 	int i;
14644091d29SJiri Pirko 
14744091d29SJiri Pirko again:
14844091d29SJiri Pirko 	priority = test_parman_rnd_get(test_parman);
14944091d29SJiri Pirko 	if (priority == 0)
15044091d29SJiri Pirko 		goto again;
15144091d29SJiri Pirko 
15244091d29SJiri Pirko 	for (i = 0; i < TEST_PARMAN_PRIO_COUNT; i++) {
15344091d29SJiri Pirko 		struct test_parman_prio *prio = &test_parman->prios[i];
15444091d29SJiri Pirko 
15544091d29SJiri Pirko 		if (prio->priority == 0)
15644091d29SJiri Pirko 			break;
15744091d29SJiri Pirko 		if (prio->priority == priority)
15844091d29SJiri Pirko 			goto again;
15944091d29SJiri Pirko 	}
16044091d29SJiri Pirko 	return priority;
16144091d29SJiri Pirko }
16244091d29SJiri Pirko 
test_parman_prios_init(struct test_parman * test_parman)16344091d29SJiri Pirko static void test_parman_prios_init(struct test_parman *test_parman)
16444091d29SJiri Pirko {
16544091d29SJiri Pirko 	int i;
16644091d29SJiri Pirko 
16744091d29SJiri Pirko 	for (i = 0; i < TEST_PARMAN_PRIO_COUNT; i++) {
16844091d29SJiri Pirko 		struct test_parman_prio *prio = &test_parman->prios[i];
16944091d29SJiri Pirko 
17044091d29SJiri Pirko 		/* Assign random uniqueue priority to each prio structure */
17144091d29SJiri Pirko 		prio->priority = test_parman_priority_gen(test_parman);
17244091d29SJiri Pirko 		parman_prio_init(test_parman->parman, &prio->parman_prio,
17344091d29SJiri Pirko 				 prio->priority);
17444091d29SJiri Pirko 	}
17544091d29SJiri Pirko }
17644091d29SJiri Pirko 
test_parman_prios_fini(struct test_parman * test_parman)17744091d29SJiri Pirko static void test_parman_prios_fini(struct test_parman *test_parman)
17844091d29SJiri Pirko {
17944091d29SJiri Pirko 	int i;
18044091d29SJiri Pirko 
18144091d29SJiri Pirko 	for (i = 0; i < TEST_PARMAN_PRIO_COUNT; i++) {
18244091d29SJiri Pirko 		struct test_parman_prio *prio = &test_parman->prios[i];
18344091d29SJiri Pirko 
18444091d29SJiri Pirko 		parman_prio_fini(&prio->parman_prio);
18544091d29SJiri Pirko 	}
18644091d29SJiri Pirko }
18744091d29SJiri Pirko 
test_parman_items_init(struct test_parman * test_parman)18844091d29SJiri Pirko static void test_parman_items_init(struct test_parman *test_parman)
18944091d29SJiri Pirko {
19044091d29SJiri Pirko 	int i;
19144091d29SJiri Pirko 
19244091d29SJiri Pirko 	for (i = 0; i < TEST_PARMAN_ITEM_COUNT; i++) {
19344091d29SJiri Pirko 		struct test_parman_item *item = &test_parman->items[i];
19444091d29SJiri Pirko 		unsigned int prio_index = test_parman_rnd_get(test_parman) &
19544091d29SJiri Pirko 					  TEST_PARMAN_PRIO_MASK;
19644091d29SJiri Pirko 
19744091d29SJiri Pirko 		/* Assign random prio to each item structure */
19844091d29SJiri Pirko 		item->prio = &test_parman->prios[prio_index];
19944091d29SJiri Pirko 	}
20044091d29SJiri Pirko }
20144091d29SJiri Pirko 
test_parman_items_fini(struct test_parman * test_parman)20244091d29SJiri Pirko static void test_parman_items_fini(struct test_parman *test_parman)
20344091d29SJiri Pirko {
20444091d29SJiri Pirko 	int i;
20544091d29SJiri Pirko 
20644091d29SJiri Pirko 	for (i = 0; i < TEST_PARMAN_ITEM_COUNT; i++) {
20744091d29SJiri Pirko 		struct test_parman_item *item = &test_parman->items[i];
20844091d29SJiri Pirko 
20944091d29SJiri Pirko 		if (!item->used)
21044091d29SJiri Pirko 			continue;
21144091d29SJiri Pirko 		parman_item_remove(test_parman->parman,
21244091d29SJiri Pirko 				   &item->prio->parman_prio,
21344091d29SJiri Pirko 				   &item->parman_item);
21444091d29SJiri Pirko 	}
21544091d29SJiri Pirko }
21644091d29SJiri Pirko 
test_parman_create(const struct parman_ops * ops)21744091d29SJiri Pirko static struct test_parman *test_parman_create(const struct parman_ops *ops)
21844091d29SJiri Pirko {
21944091d29SJiri Pirko 	struct test_parman *test_parman;
22044091d29SJiri Pirko 	int err;
22144091d29SJiri Pirko 
22244091d29SJiri Pirko 	test_parman = kzalloc(sizeof(*test_parman), GFP_KERNEL);
22344091d29SJiri Pirko 	if (!test_parman)
22444091d29SJiri Pirko 		return ERR_PTR(-ENOMEM);
22544091d29SJiri Pirko 	err = test_parman_resize(test_parman, TEST_PARMAN_BASE_COUNT);
22644091d29SJiri Pirko 	if (err)
22744091d29SJiri Pirko 		goto err_resize;
22844091d29SJiri Pirko 	test_parman->parman = parman_create(ops, test_parman);
22944091d29SJiri Pirko 	if (!test_parman->parman) {
23044091d29SJiri Pirko 		err = -ENOMEM;
23144091d29SJiri Pirko 		goto err_parman_create;
23244091d29SJiri Pirko 	}
23344091d29SJiri Pirko 	test_parman_rnd_init(test_parman);
23444091d29SJiri Pirko 	test_parman_prios_init(test_parman);
23544091d29SJiri Pirko 	test_parman_items_init(test_parman);
23644091d29SJiri Pirko 	test_parman->run_budget = TEST_PARMAN_RUN_BUDGET;
23744091d29SJiri Pirko 	return test_parman;
23844091d29SJiri Pirko 
23944091d29SJiri Pirko err_parman_create:
24044091d29SJiri Pirko 	test_parman_resize(test_parman, 0);
24144091d29SJiri Pirko err_resize:
24244091d29SJiri Pirko 	kfree(test_parman);
24344091d29SJiri Pirko 	return ERR_PTR(err);
24444091d29SJiri Pirko }
24544091d29SJiri Pirko 
test_parman_destroy(struct test_parman * test_parman)24644091d29SJiri Pirko static void test_parman_destroy(struct test_parman *test_parman)
24744091d29SJiri Pirko {
24844091d29SJiri Pirko 	test_parman_items_fini(test_parman);
24944091d29SJiri Pirko 	test_parman_prios_fini(test_parman);
25044091d29SJiri Pirko 	parman_destroy(test_parman->parman);
25144091d29SJiri Pirko 	test_parman_resize(test_parman, 0);
25244091d29SJiri Pirko 	kfree(test_parman);
25344091d29SJiri Pirko }
25444091d29SJiri Pirko 
test_parman_run_check_budgets(struct test_parman * test_parman)25544091d29SJiri Pirko static bool test_parman_run_check_budgets(struct test_parman *test_parman)
25644091d29SJiri Pirko {
25744091d29SJiri Pirko 	if (test_parman->run_budget-- == 0)
25844091d29SJiri Pirko 		return false;
25944091d29SJiri Pirko 	if (test_parman->bulk_budget-- != 0)
26044091d29SJiri Pirko 		return true;
26144091d29SJiri Pirko 
26244091d29SJiri Pirko 	test_parman->bulk_budget = test_parman_rnd_get(test_parman) &
26344091d29SJiri Pirko 				   TEST_PARMAN_BULK_MAX_MASK;
26444091d29SJiri Pirko 	test_parman->bulk_noop = test_parman_rnd_get(test_parman) & 1;
26544091d29SJiri Pirko 	return true;
26644091d29SJiri Pirko }
26744091d29SJiri Pirko 
test_parman_run(struct test_parman * test_parman)26844091d29SJiri Pirko static int test_parman_run(struct test_parman *test_parman)
26944091d29SJiri Pirko {
27044091d29SJiri Pirko 	unsigned int i = test_parman_rnd_get(test_parman);
27144091d29SJiri Pirko 	int err;
27244091d29SJiri Pirko 
27344091d29SJiri Pirko 	while (test_parman_run_check_budgets(test_parman)) {
27444091d29SJiri Pirko 		unsigned int item_index = i++ & TEST_PARMAN_ITEM_MASK;
27544091d29SJiri Pirko 		struct test_parman_item *item = &test_parman->items[item_index];
27644091d29SJiri Pirko 
27744091d29SJiri Pirko 		if (test_parman->bulk_noop)
27844091d29SJiri Pirko 			continue;
27944091d29SJiri Pirko 
28044091d29SJiri Pirko 		if (!item->used) {
28144091d29SJiri Pirko 			err = parman_item_add(test_parman->parman,
28244091d29SJiri Pirko 					      &item->prio->parman_prio,
28344091d29SJiri Pirko 					      &item->parman_item);
28444091d29SJiri Pirko 			if (err)
28544091d29SJiri Pirko 				return err;
28644091d29SJiri Pirko 			test_parman->prio_array[item->parman_item.index] = item;
28744091d29SJiri Pirko 			test_parman->used_items++;
28844091d29SJiri Pirko 		} else {
28944091d29SJiri Pirko 			test_parman->prio_array[item->parman_item.index] = NULL;
29044091d29SJiri Pirko 			parman_item_remove(test_parman->parman,
29144091d29SJiri Pirko 					   &item->prio->parman_prio,
29244091d29SJiri Pirko 					   &item->parman_item);
29344091d29SJiri Pirko 			test_parman->used_items--;
29444091d29SJiri Pirko 		}
29544091d29SJiri Pirko 		item->used = !item->used;
29644091d29SJiri Pirko 	}
29744091d29SJiri Pirko 	return 0;
29844091d29SJiri Pirko }
29944091d29SJiri Pirko 
test_parman_check_array(struct test_parman * test_parman,bool gaps_allowed)30044091d29SJiri Pirko static int test_parman_check_array(struct test_parman *test_parman,
30144091d29SJiri Pirko 				   bool gaps_allowed)
30244091d29SJiri Pirko {
30344091d29SJiri Pirko 	unsigned int last_unused_items = 0;
30444091d29SJiri Pirko 	unsigned long last_priority = 0;
30544091d29SJiri Pirko 	unsigned int used_items = 0;
30644091d29SJiri Pirko 	int i;
30744091d29SJiri Pirko 
30844091d29SJiri Pirko 	if (test_parman->prio_array_limit < TEST_PARMAN_BASE_COUNT) {
30944091d29SJiri Pirko 		pr_err("Array limit is lower than the base count (%lu < %lu)\n",
31044091d29SJiri Pirko 		       test_parman->prio_array_limit, TEST_PARMAN_BASE_COUNT);
31144091d29SJiri Pirko 		return -EINVAL;
31244091d29SJiri Pirko 	}
31344091d29SJiri Pirko 
31444091d29SJiri Pirko 	for (i = 0; i < test_parman->prio_array_limit; i++) {
31544091d29SJiri Pirko 		struct test_parman_item *item = test_parman->prio_array[i];
31644091d29SJiri Pirko 
31744091d29SJiri Pirko 		if (!item) {
31844091d29SJiri Pirko 			last_unused_items++;
31944091d29SJiri Pirko 			continue;
32044091d29SJiri Pirko 		}
32144091d29SJiri Pirko 		if (last_unused_items && !gaps_allowed) {
32244091d29SJiri Pirko 			pr_err("Gap found in array even though they are forbidden\n");
32344091d29SJiri Pirko 			return -EINVAL;
32444091d29SJiri Pirko 		}
32544091d29SJiri Pirko 
32644091d29SJiri Pirko 		last_unused_items = 0;
32744091d29SJiri Pirko 		used_items++;
32844091d29SJiri Pirko 
32944091d29SJiri Pirko 		if (item->prio->priority < last_priority) {
33044091d29SJiri Pirko 			pr_err("Item belongs under higher priority then the last one (current: %lu, previous: %lu)\n",
33144091d29SJiri Pirko 			       item->prio->priority, last_priority);
33244091d29SJiri Pirko 			return -EINVAL;
33344091d29SJiri Pirko 		}
33444091d29SJiri Pirko 		last_priority = item->prio->priority;
33544091d29SJiri Pirko 
33644091d29SJiri Pirko 		if (item->parman_item.index != i) {
337*8118b7b7SColin Ian King 			pr_err("Item has different index in compare to where it actually is (%lu != %d)\n",
33844091d29SJiri Pirko 			       item->parman_item.index, i);
33944091d29SJiri Pirko 			return -EINVAL;
34044091d29SJiri Pirko 		}
34144091d29SJiri Pirko 	}
34244091d29SJiri Pirko 
34344091d29SJiri Pirko 	if (used_items != test_parman->used_items) {
34444091d29SJiri Pirko 		pr_err("Number of used items in array does not match (%u != %u)\n",
34544091d29SJiri Pirko 		       used_items, test_parman->used_items);
34644091d29SJiri Pirko 		return -EINVAL;
34744091d29SJiri Pirko 	}
34844091d29SJiri Pirko 
34944091d29SJiri Pirko 	if (last_unused_items >= TEST_PARMAN_RESIZE_STEP_COUNT) {
35044091d29SJiri Pirko 		pr_err("Number of unused item at the end of array is bigger than resize step (%u >= %lu)\n",
35144091d29SJiri Pirko 		       last_unused_items, TEST_PARMAN_RESIZE_STEP_COUNT);
35244091d29SJiri Pirko 		return -EINVAL;
35344091d29SJiri Pirko 	}
35444091d29SJiri Pirko 
35544091d29SJiri Pirko 	pr_info("Priority array check successful\n");
35644091d29SJiri Pirko 
35744091d29SJiri Pirko 	return 0;
35844091d29SJiri Pirko }
35944091d29SJiri Pirko 
test_parman_lsort(void)36044091d29SJiri Pirko static int test_parman_lsort(void)
36144091d29SJiri Pirko {
36244091d29SJiri Pirko 	struct test_parman *test_parman;
36344091d29SJiri Pirko 	int err;
36444091d29SJiri Pirko 
36544091d29SJiri Pirko 	test_parman = test_parman_create(&test_parman_lsort_ops);
36644091d29SJiri Pirko 	if (IS_ERR(test_parman))
36744091d29SJiri Pirko 		return PTR_ERR(test_parman);
36844091d29SJiri Pirko 
36944091d29SJiri Pirko 	err = test_parman_run(test_parman);
37044091d29SJiri Pirko 	if (err)
37144091d29SJiri Pirko 		goto out;
37244091d29SJiri Pirko 
37344091d29SJiri Pirko 	err = test_parman_check_array(test_parman, false);
37444091d29SJiri Pirko 	if (err)
37544091d29SJiri Pirko 		goto out;
37644091d29SJiri Pirko out:
37744091d29SJiri Pirko 	test_parman_destroy(test_parman);
37844091d29SJiri Pirko 	return err;
37944091d29SJiri Pirko }
38044091d29SJiri Pirko 
test_parman_init(void)38144091d29SJiri Pirko static int __init test_parman_init(void)
38244091d29SJiri Pirko {
38344091d29SJiri Pirko 	return test_parman_lsort();
38444091d29SJiri Pirko }
38544091d29SJiri Pirko 
test_parman_exit(void)38644091d29SJiri Pirko static void __exit test_parman_exit(void)
38744091d29SJiri Pirko {
38844091d29SJiri Pirko }
38944091d29SJiri Pirko 
39044091d29SJiri Pirko module_init(test_parman_init);
39144091d29SJiri Pirko module_exit(test_parman_exit);
39244091d29SJiri Pirko 
39344091d29SJiri Pirko MODULE_LICENSE("Dual BSD/GPL");
39444091d29SJiri Pirko MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
39544091d29SJiri Pirko MODULE_DESCRIPTION("Test module for parman");
396