44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 1) /*
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 2) * lib/test_parman.c - Test module for parman
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 3) * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 4) * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com>
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 5) *
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 6) * Redistribution and use in source and binary forms, with or without
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 7) * modification, are permitted provided that the following conditions are met:
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 8) *
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 9) * 1. Redistributions of source code must retain the above copyright
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 10) * notice, this list of conditions and the following disclaimer.
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 11) * 2. Redistributions in binary form must reproduce the above copyright
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 12) * notice, this list of conditions and the following disclaimer in the
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 13) * documentation and/or other materials provided with the distribution.
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 14) * 3. Neither the names of the copyright holders nor the names of its
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 15) * contributors may be used to endorse or promote products derived from
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 16) * this software without specific prior written permission.
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 17) *
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 18) * Alternatively, this software may be distributed under the terms of the
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 19) * GNU General Public License ("GPL") version 2 as published by the Free
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 20) * Software Foundation.
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 21) *
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 22) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 23) * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 24) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 25) * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 26) * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 27) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 28) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 29) * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 30) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 31) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 32) * POSSIBILITY OF SUCH DAMAGE.
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 33) */
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 34)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 35) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 36)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 37) #include <linux/kernel.h>
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 38) #include <linux/module.h>
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 39) #include <linux/slab.h>
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 40) #include <linux/bitops.h>
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 41) #include <linux/err.h>
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 42) #include <linux/random.h>
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 43) #include <linux/parman.h>
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 44)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 45) #define TEST_PARMAN_PRIO_SHIFT 7 /* defines number of prios for testing */
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 46) #define TEST_PARMAN_PRIO_COUNT BIT(TEST_PARMAN_PRIO_SHIFT)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 47) #define TEST_PARMAN_PRIO_MASK (TEST_PARMAN_PRIO_COUNT - 1)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 48)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 49) #define TEST_PARMAN_ITEM_SHIFT 13 /* defines a total number
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 50) * of items for testing
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 51) */
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 52) #define TEST_PARMAN_ITEM_COUNT BIT(TEST_PARMAN_ITEM_SHIFT)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 53) #define TEST_PARMAN_ITEM_MASK (TEST_PARMAN_ITEM_COUNT - 1)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 54)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 55) #define TEST_PARMAN_BASE_SHIFT 8
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 56) #define TEST_PARMAN_BASE_COUNT BIT(TEST_PARMAN_BASE_SHIFT)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 57) #define TEST_PARMAN_RESIZE_STEP_SHIFT 7
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 58) #define TEST_PARMAN_RESIZE_STEP_COUNT BIT(TEST_PARMAN_RESIZE_STEP_SHIFT)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 59)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 60) #define TEST_PARMAN_BULK_MAX_SHIFT (2 + TEST_PARMAN_RESIZE_STEP_SHIFT)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 61) #define TEST_PARMAN_BULK_MAX_COUNT BIT(TEST_PARMAN_BULK_MAX_SHIFT)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 62) #define TEST_PARMAN_BULK_MAX_MASK (TEST_PARMAN_BULK_MAX_COUNT - 1)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 63)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 64) #define TEST_PARMAN_RUN_BUDGET (TEST_PARMAN_ITEM_COUNT * 256)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 65)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 66) struct test_parman_prio {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 67) struct parman_prio parman_prio;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 68) unsigned long priority;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 69) };
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 70)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 71) struct test_parman_item {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 72) struct parman_item parman_item;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 73) struct test_parman_prio *prio;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 74) bool used;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 75) };
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 76)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 77) struct test_parman {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 78) struct parman *parman;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 79) struct test_parman_item **prio_array;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 80) unsigned long prio_array_limit;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 81) struct test_parman_prio prios[TEST_PARMAN_PRIO_COUNT];
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 82) struct test_parman_item items[TEST_PARMAN_ITEM_COUNT];
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 83) struct rnd_state rnd;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 84) unsigned long run_budget;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 85) unsigned long bulk_budget;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 86) bool bulk_noop;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 87) unsigned int used_items;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 88) };
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 89)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 90) #define ITEM_PTRS_SIZE(count) (sizeof(struct test_parman_item *) * (count))
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 91)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 92) static int test_parman_resize(void *priv, unsigned long new_count)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 93) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 94) struct test_parman *test_parman = priv;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 95) struct test_parman_item **prio_array;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 96) unsigned long old_count;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 97)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 98) prio_array = krealloc(test_parman->prio_array,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 99) ITEM_PTRS_SIZE(new_count), GFP_KERNEL);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 100) if (new_count == 0)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 101) return 0;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 102) if (!prio_array)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 103) return -ENOMEM;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 104) old_count = test_parman->prio_array_limit;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 105) if (new_count > old_count)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 106) memset(&prio_array[old_count], 0,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 107) ITEM_PTRS_SIZE(new_count - old_count));
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 108) test_parman->prio_array = prio_array;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 109) test_parman->prio_array_limit = new_count;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 110) return 0;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 111) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 112)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 113) static void test_parman_move(void *priv, unsigned long from_index,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 114) unsigned long to_index, unsigned long count)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 115) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 116) struct test_parman *test_parman = priv;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 117) struct test_parman_item **prio_array = test_parman->prio_array;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 118)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 119) memmove(&prio_array[to_index], &prio_array[from_index],
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 120) ITEM_PTRS_SIZE(count));
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 121) memset(&prio_array[from_index], 0, ITEM_PTRS_SIZE(count));
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 122) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 123)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 124) static const struct parman_ops test_parman_lsort_ops = {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 125) .base_count = TEST_PARMAN_BASE_COUNT,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 126) .resize_step = TEST_PARMAN_RESIZE_STEP_COUNT,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 127) .resize = test_parman_resize,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 128) .move = test_parman_move,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 129) .algo = PARMAN_ALGO_TYPE_LSORT,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 130) };
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 131)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 132) static void test_parman_rnd_init(struct test_parman *test_parman)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 133) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 134) prandom_seed_state(&test_parman->rnd, 3141592653589793238ULL);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 135) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 136)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 137) static u32 test_parman_rnd_get(struct test_parman *test_parman)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 138) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 139) return prandom_u32_state(&test_parman->rnd);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 140) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 141)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 142) static unsigned long test_parman_priority_gen(struct test_parman *test_parman)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 143) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 144) unsigned long priority;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 145) int i;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 146)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 147) again:
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 148) priority = test_parman_rnd_get(test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 149) if (priority == 0)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 150) goto again;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 151)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 152) for (i = 0; i < TEST_PARMAN_PRIO_COUNT; i++) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 153) struct test_parman_prio *prio = &test_parman->prios[i];
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 154)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 155) if (prio->priority == 0)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 156) break;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 157) if (prio->priority == priority)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 158) goto again;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 159) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 160) return priority;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 161) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 162)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 163) static void test_parman_prios_init(struct test_parman *test_parman)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 164) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 165) int i;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 166)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 167) for (i = 0; i < TEST_PARMAN_PRIO_COUNT; i++) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 168) struct test_parman_prio *prio = &test_parman->prios[i];
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 169)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 170) /* Assign random uniqueue priority to each prio structure */
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 171) prio->priority = test_parman_priority_gen(test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 172) parman_prio_init(test_parman->parman, &prio->parman_prio,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 173) prio->priority);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 174) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 175) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 176)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 177) static void test_parman_prios_fini(struct test_parman *test_parman)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 178) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 179) int i;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 180)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 181) for (i = 0; i < TEST_PARMAN_PRIO_COUNT; i++) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 182) struct test_parman_prio *prio = &test_parman->prios[i];
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 183)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 184) parman_prio_fini(&prio->parman_prio);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 185) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 186) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 187)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 188) static void test_parman_items_init(struct test_parman *test_parman)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 189) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 190) int i;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 191)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 192) for (i = 0; i < TEST_PARMAN_ITEM_COUNT; i++) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 193) struct test_parman_item *item = &test_parman->items[i];
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 194) unsigned int prio_index = test_parman_rnd_get(test_parman) &
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 195) TEST_PARMAN_PRIO_MASK;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 196)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 197) /* Assign random prio to each item structure */
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 198) item->prio = &test_parman->prios[prio_index];
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 199) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 200) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 201)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 202) static void test_parman_items_fini(struct test_parman *test_parman)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 203) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 204) int i;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 205)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 206) for (i = 0; i < TEST_PARMAN_ITEM_COUNT; i++) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 207) struct test_parman_item *item = &test_parman->items[i];
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 208)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 209) if (!item->used)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 210) continue;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 211) parman_item_remove(test_parman->parman,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 212) &item->prio->parman_prio,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 213) &item->parman_item);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 214) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 215) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 216)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 217) static struct test_parman *test_parman_create(const struct parman_ops *ops)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 218) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 219) struct test_parman *test_parman;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 220) int err;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 221)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 222) test_parman = kzalloc(sizeof(*test_parman), GFP_KERNEL);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 223) if (!test_parman)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 224) return ERR_PTR(-ENOMEM);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 225) err = test_parman_resize(test_parman, TEST_PARMAN_BASE_COUNT);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 226) if (err)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 227) goto err_resize;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 228) test_parman->parman = parman_create(ops, test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 229) if (!test_parman->parman) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 230) err = -ENOMEM;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 231) goto err_parman_create;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 232) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 233) test_parman_rnd_init(test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 234) test_parman_prios_init(test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 235) test_parman_items_init(test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 236) test_parman->run_budget = TEST_PARMAN_RUN_BUDGET;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 237) return test_parman;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 238)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 239) err_parman_create:
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 240) test_parman_resize(test_parman, 0);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 241) err_resize:
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 242) kfree(test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 243) return ERR_PTR(err);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 244) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 245)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 246) static void test_parman_destroy(struct test_parman *test_parman)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 247) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 248) test_parman_items_fini(test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 249) test_parman_prios_fini(test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 250) parman_destroy(test_parman->parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 251) test_parman_resize(test_parman, 0);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 252) kfree(test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 253) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 254)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 255) static bool test_parman_run_check_budgets(struct test_parman *test_parman)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 256) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 257) if (test_parman->run_budget-- == 0)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 258) return false;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 259) if (test_parman->bulk_budget-- != 0)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 260) return true;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 261)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 262) test_parman->bulk_budget = test_parman_rnd_get(test_parman) &
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 263) TEST_PARMAN_BULK_MAX_MASK;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 264) test_parman->bulk_noop = test_parman_rnd_get(test_parman) & 1;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 265) return true;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 266) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 267)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 268) static int test_parman_run(struct test_parman *test_parman)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 269) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 270) unsigned int i = test_parman_rnd_get(test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 271) int err;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 272)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 273) while (test_parman_run_check_budgets(test_parman)) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 274) unsigned int item_index = i++ & TEST_PARMAN_ITEM_MASK;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 275) struct test_parman_item *item = &test_parman->items[item_index];
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 276)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 277) if (test_parman->bulk_noop)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 278) continue;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 279)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 280) if (!item->used) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 281) err = parman_item_add(test_parman->parman,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 282) &item->prio->parman_prio,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 283) &item->parman_item);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 284) if (err)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 285) return err;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 286) test_parman->prio_array[item->parman_item.index] = item;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 287) test_parman->used_items++;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 288) } else {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 289) test_parman->prio_array[item->parman_item.index] = NULL;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 290) parman_item_remove(test_parman->parman,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 291) &item->prio->parman_prio,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 292) &item->parman_item);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 293) test_parman->used_items--;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 294) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 295) item->used = !item->used;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 296) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 297) return 0;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 298) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 299)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 300) static int test_parman_check_array(struct test_parman *test_parman,
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 301) bool gaps_allowed)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 302) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 303) unsigned int last_unused_items = 0;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 304) unsigned long last_priority = 0;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 305) unsigned int used_items = 0;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 306) int i;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 307)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 308) if (test_parman->prio_array_limit < TEST_PARMAN_BASE_COUNT) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 309) pr_err("Array limit is lower than the base count (%lu < %lu)\n",
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 310) test_parman->prio_array_limit, TEST_PARMAN_BASE_COUNT);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 311) return -EINVAL;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 312) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 313)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 314) for (i = 0; i < test_parman->prio_array_limit; i++) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 315) struct test_parman_item *item = test_parman->prio_array[i];
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 316)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 317) if (!item) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 318) last_unused_items++;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 319) continue;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 320) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 321) if (last_unused_items && !gaps_allowed) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 322) pr_err("Gap found in array even though they are forbidden\n");
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 323) return -EINVAL;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 324) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 325)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 326) last_unused_items = 0;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 327) used_items++;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 328)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 329) if (item->prio->priority < last_priority) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 330) pr_err("Item belongs under higher priority then the last one (current: %lu, previous: %lu)\n",
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 331) item->prio->priority, last_priority);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 332) return -EINVAL;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 333) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 334) last_priority = item->prio->priority;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 335)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 336) if (item->parman_item.index != i) {
8118b7b76c8c0 (Colin Ian King 2017-02-26 12:10:12 +0000 337) pr_err("Item has different index in compare to where it actually is (%lu != %d)\n",
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 338) item->parman_item.index, i);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 339) return -EINVAL;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 340) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 341) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 342)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 343) if (used_items != test_parman->used_items) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 344) pr_err("Number of used items in array does not match (%u != %u)\n",
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 345) used_items, test_parman->used_items);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 346) return -EINVAL;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 347) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 348)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 349) if (last_unused_items >= TEST_PARMAN_RESIZE_STEP_COUNT) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 350) pr_err("Number of unused item at the end of array is bigger than resize step (%u >= %lu)\n",
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 351) last_unused_items, TEST_PARMAN_RESIZE_STEP_COUNT);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 352) return -EINVAL;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 353) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 354)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 355) pr_info("Priority array check successful\n");
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 356)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 357) return 0;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 358) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 359)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 360) static int test_parman_lsort(void)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 361) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 362) struct test_parman *test_parman;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 363) int err;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 364)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 365) test_parman = test_parman_create(&test_parman_lsort_ops);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 366) if (IS_ERR(test_parman))
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 367) return PTR_ERR(test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 368)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 369) err = test_parman_run(test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 370) if (err)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 371) goto out;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 372)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 373) err = test_parman_check_array(test_parman, false);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 374) if (err)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 375) goto out;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 376) out:
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 377) test_parman_destroy(test_parman);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 378) return err;
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 379) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 380)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 381) static int __init test_parman_init(void)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 382) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 383) return test_parman_lsort();
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 384) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 385)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 386) static void __exit test_parman_exit(void)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 387) {
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 388) }
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 389)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 390) module_init(test_parman_init);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 391) module_exit(test_parman_exit);
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 392)
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 393) MODULE_LICENSE("Dual BSD/GPL");
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 394) MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
44091d29f2075 (Jiri Pirko 2017-02-03 10:29:06 +0100 395) MODULE_DESCRIPTION("Test module for parman");