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