18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * lib/test_parman.c - Test module for parman 38c2ecf20Sopenharmony_ci * Copyright (c) 2017 Mellanox Technologies. All rights reserved. 48c2ecf20Sopenharmony_ci * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com> 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 78c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions are met: 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 108c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 118c2ecf20Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 128c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer in the 138c2ecf20Sopenharmony_ci * documentation and/or other materials provided with the distribution. 148c2ecf20Sopenharmony_ci * 3. Neither the names of the copyright holders nor the names of its 158c2ecf20Sopenharmony_ci * contributors may be used to endorse or promote products derived from 168c2ecf20Sopenharmony_ci * this software without specific prior written permission. 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the 198c2ecf20Sopenharmony_ci * GNU General Public License ("GPL") version 2 as published by the Free 208c2ecf20Sopenharmony_ci * Software Foundation. 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 238c2ecf20Sopenharmony_ci * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 248c2ecf20Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 258c2ecf20Sopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 268c2ecf20Sopenharmony_ci * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 278c2ecf20Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 288c2ecf20Sopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 298c2ecf20Sopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 308c2ecf20Sopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 318c2ecf20Sopenharmony_ci * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 328c2ecf20Sopenharmony_ci * POSSIBILITY OF SUCH DAMAGE. 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#include <linux/kernel.h> 388c2ecf20Sopenharmony_ci#include <linux/module.h> 398c2ecf20Sopenharmony_ci#include <linux/slab.h> 408c2ecf20Sopenharmony_ci#include <linux/bitops.h> 418c2ecf20Sopenharmony_ci#include <linux/err.h> 428c2ecf20Sopenharmony_ci#include <linux/random.h> 438c2ecf20Sopenharmony_ci#include <linux/parman.h> 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#define TEST_PARMAN_PRIO_SHIFT 7 /* defines number of prios for testing */ 468c2ecf20Sopenharmony_ci#define TEST_PARMAN_PRIO_COUNT BIT(TEST_PARMAN_PRIO_SHIFT) 478c2ecf20Sopenharmony_ci#define TEST_PARMAN_PRIO_MASK (TEST_PARMAN_PRIO_COUNT - 1) 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define TEST_PARMAN_ITEM_SHIFT 13 /* defines a total number 508c2ecf20Sopenharmony_ci * of items for testing 518c2ecf20Sopenharmony_ci */ 528c2ecf20Sopenharmony_ci#define TEST_PARMAN_ITEM_COUNT BIT(TEST_PARMAN_ITEM_SHIFT) 538c2ecf20Sopenharmony_ci#define TEST_PARMAN_ITEM_MASK (TEST_PARMAN_ITEM_COUNT - 1) 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#define TEST_PARMAN_BASE_SHIFT 8 568c2ecf20Sopenharmony_ci#define TEST_PARMAN_BASE_COUNT BIT(TEST_PARMAN_BASE_SHIFT) 578c2ecf20Sopenharmony_ci#define TEST_PARMAN_RESIZE_STEP_SHIFT 7 588c2ecf20Sopenharmony_ci#define TEST_PARMAN_RESIZE_STEP_COUNT BIT(TEST_PARMAN_RESIZE_STEP_SHIFT) 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci#define TEST_PARMAN_BULK_MAX_SHIFT (2 + TEST_PARMAN_RESIZE_STEP_SHIFT) 618c2ecf20Sopenharmony_ci#define TEST_PARMAN_BULK_MAX_COUNT BIT(TEST_PARMAN_BULK_MAX_SHIFT) 628c2ecf20Sopenharmony_ci#define TEST_PARMAN_BULK_MAX_MASK (TEST_PARMAN_BULK_MAX_COUNT - 1) 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci#define TEST_PARMAN_RUN_BUDGET (TEST_PARMAN_ITEM_COUNT * 256) 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistruct test_parman_prio { 678c2ecf20Sopenharmony_ci struct parman_prio parman_prio; 688c2ecf20Sopenharmony_ci unsigned long priority; 698c2ecf20Sopenharmony_ci}; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistruct test_parman_item { 728c2ecf20Sopenharmony_ci struct parman_item parman_item; 738c2ecf20Sopenharmony_ci struct test_parman_prio *prio; 748c2ecf20Sopenharmony_ci bool used; 758c2ecf20Sopenharmony_ci}; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistruct test_parman { 788c2ecf20Sopenharmony_ci struct parman *parman; 798c2ecf20Sopenharmony_ci struct test_parman_item **prio_array; 808c2ecf20Sopenharmony_ci unsigned long prio_array_limit; 818c2ecf20Sopenharmony_ci struct test_parman_prio prios[TEST_PARMAN_PRIO_COUNT]; 828c2ecf20Sopenharmony_ci struct test_parman_item items[TEST_PARMAN_ITEM_COUNT]; 838c2ecf20Sopenharmony_ci struct rnd_state rnd; 848c2ecf20Sopenharmony_ci unsigned long run_budget; 858c2ecf20Sopenharmony_ci unsigned long bulk_budget; 868c2ecf20Sopenharmony_ci bool bulk_noop; 878c2ecf20Sopenharmony_ci unsigned int used_items; 888c2ecf20Sopenharmony_ci}; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci#define ITEM_PTRS_SIZE(count) (sizeof(struct test_parman_item *) * (count)) 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cistatic int test_parman_resize(void *priv, unsigned long new_count) 938c2ecf20Sopenharmony_ci{ 948c2ecf20Sopenharmony_ci struct test_parman *test_parman = priv; 958c2ecf20Sopenharmony_ci struct test_parman_item **prio_array; 968c2ecf20Sopenharmony_ci unsigned long old_count; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci prio_array = krealloc(test_parman->prio_array, 998c2ecf20Sopenharmony_ci ITEM_PTRS_SIZE(new_count), GFP_KERNEL); 1008c2ecf20Sopenharmony_ci if (new_count == 0) 1018c2ecf20Sopenharmony_ci return 0; 1028c2ecf20Sopenharmony_ci if (!prio_array) 1038c2ecf20Sopenharmony_ci return -ENOMEM; 1048c2ecf20Sopenharmony_ci old_count = test_parman->prio_array_limit; 1058c2ecf20Sopenharmony_ci if (new_count > old_count) 1068c2ecf20Sopenharmony_ci memset(&prio_array[old_count], 0, 1078c2ecf20Sopenharmony_ci ITEM_PTRS_SIZE(new_count - old_count)); 1088c2ecf20Sopenharmony_ci test_parman->prio_array = prio_array; 1098c2ecf20Sopenharmony_ci test_parman->prio_array_limit = new_count; 1108c2ecf20Sopenharmony_ci return 0; 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cistatic void test_parman_move(void *priv, unsigned long from_index, 1148c2ecf20Sopenharmony_ci unsigned long to_index, unsigned long count) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci struct test_parman *test_parman = priv; 1178c2ecf20Sopenharmony_ci struct test_parman_item **prio_array = test_parman->prio_array; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci memmove(&prio_array[to_index], &prio_array[from_index], 1208c2ecf20Sopenharmony_ci ITEM_PTRS_SIZE(count)); 1218c2ecf20Sopenharmony_ci memset(&prio_array[from_index], 0, ITEM_PTRS_SIZE(count)); 1228c2ecf20Sopenharmony_ci} 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cistatic const struct parman_ops test_parman_lsort_ops = { 1258c2ecf20Sopenharmony_ci .base_count = TEST_PARMAN_BASE_COUNT, 1268c2ecf20Sopenharmony_ci .resize_step = TEST_PARMAN_RESIZE_STEP_COUNT, 1278c2ecf20Sopenharmony_ci .resize = test_parman_resize, 1288c2ecf20Sopenharmony_ci .move = test_parman_move, 1298c2ecf20Sopenharmony_ci .algo = PARMAN_ALGO_TYPE_LSORT, 1308c2ecf20Sopenharmony_ci}; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cistatic void test_parman_rnd_init(struct test_parman *test_parman) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci prandom_seed_state(&test_parman->rnd, 3141592653589793238ULL); 1358c2ecf20Sopenharmony_ci} 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_cistatic u32 test_parman_rnd_get(struct test_parman *test_parman) 1388c2ecf20Sopenharmony_ci{ 1398c2ecf20Sopenharmony_ci return prandom_u32_state(&test_parman->rnd); 1408c2ecf20Sopenharmony_ci} 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic unsigned long test_parman_priority_gen(struct test_parman *test_parman) 1438c2ecf20Sopenharmony_ci{ 1448c2ecf20Sopenharmony_ci unsigned long priority; 1458c2ecf20Sopenharmony_ci int i; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ciagain: 1488c2ecf20Sopenharmony_ci priority = test_parman_rnd_get(test_parman); 1498c2ecf20Sopenharmony_ci if (priority == 0) 1508c2ecf20Sopenharmony_ci goto again; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci for (i = 0; i < TEST_PARMAN_PRIO_COUNT; i++) { 1538c2ecf20Sopenharmony_ci struct test_parman_prio *prio = &test_parman->prios[i]; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci if (prio->priority == 0) 1568c2ecf20Sopenharmony_ci break; 1578c2ecf20Sopenharmony_ci if (prio->priority == priority) 1588c2ecf20Sopenharmony_ci goto again; 1598c2ecf20Sopenharmony_ci } 1608c2ecf20Sopenharmony_ci return priority; 1618c2ecf20Sopenharmony_ci} 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_cistatic void test_parman_prios_init(struct test_parman *test_parman) 1648c2ecf20Sopenharmony_ci{ 1658c2ecf20Sopenharmony_ci int i; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci for (i = 0; i < TEST_PARMAN_PRIO_COUNT; i++) { 1688c2ecf20Sopenharmony_ci struct test_parman_prio *prio = &test_parman->prios[i]; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci /* Assign random uniqueue priority to each prio structure */ 1718c2ecf20Sopenharmony_ci prio->priority = test_parman_priority_gen(test_parman); 1728c2ecf20Sopenharmony_ci parman_prio_init(test_parman->parman, &prio->parman_prio, 1738c2ecf20Sopenharmony_ci prio->priority); 1748c2ecf20Sopenharmony_ci } 1758c2ecf20Sopenharmony_ci} 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cistatic void test_parman_prios_fini(struct test_parman *test_parman) 1788c2ecf20Sopenharmony_ci{ 1798c2ecf20Sopenharmony_ci int i; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci for (i = 0; i < TEST_PARMAN_PRIO_COUNT; i++) { 1828c2ecf20Sopenharmony_ci struct test_parman_prio *prio = &test_parman->prios[i]; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci parman_prio_fini(&prio->parman_prio); 1858c2ecf20Sopenharmony_ci } 1868c2ecf20Sopenharmony_ci} 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_cistatic void test_parman_items_init(struct test_parman *test_parman) 1898c2ecf20Sopenharmony_ci{ 1908c2ecf20Sopenharmony_ci int i; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci for (i = 0; i < TEST_PARMAN_ITEM_COUNT; i++) { 1938c2ecf20Sopenharmony_ci struct test_parman_item *item = &test_parman->items[i]; 1948c2ecf20Sopenharmony_ci unsigned int prio_index = test_parman_rnd_get(test_parman) & 1958c2ecf20Sopenharmony_ci TEST_PARMAN_PRIO_MASK; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci /* Assign random prio to each item structure */ 1988c2ecf20Sopenharmony_ci item->prio = &test_parman->prios[prio_index]; 1998c2ecf20Sopenharmony_ci } 2008c2ecf20Sopenharmony_ci} 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_cistatic void test_parman_items_fini(struct test_parman *test_parman) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci int i; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci for (i = 0; i < TEST_PARMAN_ITEM_COUNT; i++) { 2078c2ecf20Sopenharmony_ci struct test_parman_item *item = &test_parman->items[i]; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci if (!item->used) 2108c2ecf20Sopenharmony_ci continue; 2118c2ecf20Sopenharmony_ci parman_item_remove(test_parman->parman, 2128c2ecf20Sopenharmony_ci &item->prio->parman_prio, 2138c2ecf20Sopenharmony_ci &item->parman_item); 2148c2ecf20Sopenharmony_ci } 2158c2ecf20Sopenharmony_ci} 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_cistatic struct test_parman *test_parman_create(const struct parman_ops *ops) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci struct test_parman *test_parman; 2208c2ecf20Sopenharmony_ci int err; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci test_parman = kzalloc(sizeof(*test_parman), GFP_KERNEL); 2238c2ecf20Sopenharmony_ci if (!test_parman) 2248c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 2258c2ecf20Sopenharmony_ci err = test_parman_resize(test_parman, TEST_PARMAN_BASE_COUNT); 2268c2ecf20Sopenharmony_ci if (err) 2278c2ecf20Sopenharmony_ci goto err_resize; 2288c2ecf20Sopenharmony_ci test_parman->parman = parman_create(ops, test_parman); 2298c2ecf20Sopenharmony_ci if (!test_parman->parman) { 2308c2ecf20Sopenharmony_ci err = -ENOMEM; 2318c2ecf20Sopenharmony_ci goto err_parman_create; 2328c2ecf20Sopenharmony_ci } 2338c2ecf20Sopenharmony_ci test_parman_rnd_init(test_parman); 2348c2ecf20Sopenharmony_ci test_parman_prios_init(test_parman); 2358c2ecf20Sopenharmony_ci test_parman_items_init(test_parman); 2368c2ecf20Sopenharmony_ci test_parman->run_budget = TEST_PARMAN_RUN_BUDGET; 2378c2ecf20Sopenharmony_ci return test_parman; 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_cierr_parman_create: 2408c2ecf20Sopenharmony_ci test_parman_resize(test_parman, 0); 2418c2ecf20Sopenharmony_cierr_resize: 2428c2ecf20Sopenharmony_ci kfree(test_parman); 2438c2ecf20Sopenharmony_ci return ERR_PTR(err); 2448c2ecf20Sopenharmony_ci} 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_cistatic void test_parman_destroy(struct test_parman *test_parman) 2478c2ecf20Sopenharmony_ci{ 2488c2ecf20Sopenharmony_ci test_parman_items_fini(test_parman); 2498c2ecf20Sopenharmony_ci test_parman_prios_fini(test_parman); 2508c2ecf20Sopenharmony_ci parman_destroy(test_parman->parman); 2518c2ecf20Sopenharmony_ci test_parman_resize(test_parman, 0); 2528c2ecf20Sopenharmony_ci kfree(test_parman); 2538c2ecf20Sopenharmony_ci} 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_cistatic bool test_parman_run_check_budgets(struct test_parman *test_parman) 2568c2ecf20Sopenharmony_ci{ 2578c2ecf20Sopenharmony_ci if (test_parman->run_budget-- == 0) 2588c2ecf20Sopenharmony_ci return false; 2598c2ecf20Sopenharmony_ci if (test_parman->bulk_budget-- != 0) 2608c2ecf20Sopenharmony_ci return true; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci test_parman->bulk_budget = test_parman_rnd_get(test_parman) & 2638c2ecf20Sopenharmony_ci TEST_PARMAN_BULK_MAX_MASK; 2648c2ecf20Sopenharmony_ci test_parman->bulk_noop = test_parman_rnd_get(test_parman) & 1; 2658c2ecf20Sopenharmony_ci return true; 2668c2ecf20Sopenharmony_ci} 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_cistatic int test_parman_run(struct test_parman *test_parman) 2698c2ecf20Sopenharmony_ci{ 2708c2ecf20Sopenharmony_ci unsigned int i = test_parman_rnd_get(test_parman); 2718c2ecf20Sopenharmony_ci int err; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci while (test_parman_run_check_budgets(test_parman)) { 2748c2ecf20Sopenharmony_ci unsigned int item_index = i++ & TEST_PARMAN_ITEM_MASK; 2758c2ecf20Sopenharmony_ci struct test_parman_item *item = &test_parman->items[item_index]; 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci if (test_parman->bulk_noop) 2788c2ecf20Sopenharmony_ci continue; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci if (!item->used) { 2818c2ecf20Sopenharmony_ci err = parman_item_add(test_parman->parman, 2828c2ecf20Sopenharmony_ci &item->prio->parman_prio, 2838c2ecf20Sopenharmony_ci &item->parman_item); 2848c2ecf20Sopenharmony_ci if (err) 2858c2ecf20Sopenharmony_ci return err; 2868c2ecf20Sopenharmony_ci test_parman->prio_array[item->parman_item.index] = item; 2878c2ecf20Sopenharmony_ci test_parman->used_items++; 2888c2ecf20Sopenharmony_ci } else { 2898c2ecf20Sopenharmony_ci test_parman->prio_array[item->parman_item.index] = NULL; 2908c2ecf20Sopenharmony_ci parman_item_remove(test_parman->parman, 2918c2ecf20Sopenharmony_ci &item->prio->parman_prio, 2928c2ecf20Sopenharmony_ci &item->parman_item); 2938c2ecf20Sopenharmony_ci test_parman->used_items--; 2948c2ecf20Sopenharmony_ci } 2958c2ecf20Sopenharmony_ci item->used = !item->used; 2968c2ecf20Sopenharmony_ci } 2978c2ecf20Sopenharmony_ci return 0; 2988c2ecf20Sopenharmony_ci} 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_cistatic int test_parman_check_array(struct test_parman *test_parman, 3018c2ecf20Sopenharmony_ci bool gaps_allowed) 3028c2ecf20Sopenharmony_ci{ 3038c2ecf20Sopenharmony_ci unsigned int last_unused_items = 0; 3048c2ecf20Sopenharmony_ci unsigned long last_priority = 0; 3058c2ecf20Sopenharmony_ci unsigned int used_items = 0; 3068c2ecf20Sopenharmony_ci int i; 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci if (test_parman->prio_array_limit < TEST_PARMAN_BASE_COUNT) { 3098c2ecf20Sopenharmony_ci pr_err("Array limit is lower than the base count (%lu < %lu)\n", 3108c2ecf20Sopenharmony_ci test_parman->prio_array_limit, TEST_PARMAN_BASE_COUNT); 3118c2ecf20Sopenharmony_ci return -EINVAL; 3128c2ecf20Sopenharmony_ci } 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci for (i = 0; i < test_parman->prio_array_limit; i++) { 3158c2ecf20Sopenharmony_ci struct test_parman_item *item = test_parman->prio_array[i]; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci if (!item) { 3188c2ecf20Sopenharmony_ci last_unused_items++; 3198c2ecf20Sopenharmony_ci continue; 3208c2ecf20Sopenharmony_ci } 3218c2ecf20Sopenharmony_ci if (last_unused_items && !gaps_allowed) { 3228c2ecf20Sopenharmony_ci pr_err("Gap found in array even though they are forbidden\n"); 3238c2ecf20Sopenharmony_ci return -EINVAL; 3248c2ecf20Sopenharmony_ci } 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci last_unused_items = 0; 3278c2ecf20Sopenharmony_ci used_items++; 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci if (item->prio->priority < last_priority) { 3308c2ecf20Sopenharmony_ci pr_err("Item belongs under higher priority then the last one (current: %lu, previous: %lu)\n", 3318c2ecf20Sopenharmony_ci item->prio->priority, last_priority); 3328c2ecf20Sopenharmony_ci return -EINVAL; 3338c2ecf20Sopenharmony_ci } 3348c2ecf20Sopenharmony_ci last_priority = item->prio->priority; 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci if (item->parman_item.index != i) { 3378c2ecf20Sopenharmony_ci pr_err("Item has different index in compare to where it actually is (%lu != %d)\n", 3388c2ecf20Sopenharmony_ci item->parman_item.index, i); 3398c2ecf20Sopenharmony_ci return -EINVAL; 3408c2ecf20Sopenharmony_ci } 3418c2ecf20Sopenharmony_ci } 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci if (used_items != test_parman->used_items) { 3448c2ecf20Sopenharmony_ci pr_err("Number of used items in array does not match (%u != %u)\n", 3458c2ecf20Sopenharmony_ci used_items, test_parman->used_items); 3468c2ecf20Sopenharmony_ci return -EINVAL; 3478c2ecf20Sopenharmony_ci } 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ci if (last_unused_items >= TEST_PARMAN_RESIZE_STEP_COUNT) { 3508c2ecf20Sopenharmony_ci pr_err("Number of unused item at the end of array is bigger than resize step (%u >= %lu)\n", 3518c2ecf20Sopenharmony_ci last_unused_items, TEST_PARMAN_RESIZE_STEP_COUNT); 3528c2ecf20Sopenharmony_ci return -EINVAL; 3538c2ecf20Sopenharmony_ci } 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci pr_info("Priority array check successful\n"); 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci return 0; 3588c2ecf20Sopenharmony_ci} 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_cistatic int test_parman_lsort(void) 3618c2ecf20Sopenharmony_ci{ 3628c2ecf20Sopenharmony_ci struct test_parman *test_parman; 3638c2ecf20Sopenharmony_ci int err; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci test_parman = test_parman_create(&test_parman_lsort_ops); 3668c2ecf20Sopenharmony_ci if (IS_ERR(test_parman)) 3678c2ecf20Sopenharmony_ci return PTR_ERR(test_parman); 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci err = test_parman_run(test_parman); 3708c2ecf20Sopenharmony_ci if (err) 3718c2ecf20Sopenharmony_ci goto out; 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci err = test_parman_check_array(test_parman, false); 3748c2ecf20Sopenharmony_ci if (err) 3758c2ecf20Sopenharmony_ci goto out; 3768c2ecf20Sopenharmony_ciout: 3778c2ecf20Sopenharmony_ci test_parman_destroy(test_parman); 3788c2ecf20Sopenharmony_ci return err; 3798c2ecf20Sopenharmony_ci} 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_cistatic int __init test_parman_init(void) 3828c2ecf20Sopenharmony_ci{ 3838c2ecf20Sopenharmony_ci return test_parman_lsort(); 3848c2ecf20Sopenharmony_ci} 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_cistatic void __exit test_parman_exit(void) 3878c2ecf20Sopenharmony_ci{ 3888c2ecf20Sopenharmony_ci} 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_cimodule_init(test_parman_init); 3918c2ecf20Sopenharmony_cimodule_exit(test_parman_exit); 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 3948c2ecf20Sopenharmony_ciMODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>"); 3958c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Test module for parman"); 396