1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 #include "spdk/cpuset.h" 36 37 #include "spdk_cunit.h" 38 39 #include "util/cpuset.c" 40 41 static int 42 cpuset_check_range(struct spdk_cpuset *core_mask, uint32_t min, uint32_t max, bool isset) 43 { 44 uint32_t core; 45 for (core = min; core <= max; core++) { 46 if (isset != spdk_cpuset_get_cpu(core_mask, core)) { 47 return -1; 48 } 49 } 50 return 0; 51 } 52 53 static void 54 test_cpuset(void) 55 { 56 uint32_t cpu; 57 struct spdk_cpuset *set = spdk_cpuset_alloc(); 58 59 SPDK_CU_ASSERT_FATAL(set != NULL); 60 CU_ASSERT(spdk_cpuset_count(set) == 0); 61 62 /* Set cpu 0 */ 63 spdk_cpuset_set_cpu(set, 0, true); 64 CU_ASSERT(spdk_cpuset_get_cpu(set, 0) == true); 65 CU_ASSERT(cpuset_check_range(set, 1, SPDK_CPUSET_SIZE - 1, false) == 0); 66 CU_ASSERT(spdk_cpuset_count(set) == 1); 67 68 /* Set last cpu (cpu 0 already set) */ 69 spdk_cpuset_set_cpu(set, SPDK_CPUSET_SIZE - 1, true); 70 CU_ASSERT(spdk_cpuset_get_cpu(set, 0) == true); 71 CU_ASSERT(spdk_cpuset_get_cpu(set, SPDK_CPUSET_SIZE - 1) == true); 72 CU_ASSERT(cpuset_check_range(set, 1, SPDK_CPUSET_SIZE - 2, false) == 0); 73 CU_ASSERT(spdk_cpuset_count(set) == 2); 74 75 /* Clear cpu 0 (last cpu already set) */ 76 spdk_cpuset_set_cpu(set, 0, false); 77 CU_ASSERT(spdk_cpuset_get_cpu(set, 0) == false); 78 CU_ASSERT(cpuset_check_range(set, 1, SPDK_CPUSET_SIZE - 2, false) == 0); 79 CU_ASSERT(spdk_cpuset_get_cpu(set, SPDK_CPUSET_SIZE - 1) == true); 80 CU_ASSERT(spdk_cpuset_count(set) == 1); 81 82 /* Set middle cpu (last cpu already set) */ 83 cpu = (SPDK_CPUSET_SIZE - 1) / 2; 84 spdk_cpuset_set_cpu(set, cpu, true); 85 CU_ASSERT(spdk_cpuset_get_cpu(set, cpu) == true); 86 CU_ASSERT(spdk_cpuset_get_cpu(set, SPDK_CPUSET_SIZE - 1) == true); 87 CU_ASSERT(cpuset_check_range(set, 1, cpu - 1, false) == 0); 88 CU_ASSERT(cpuset_check_range(set, cpu + 1, SPDK_CPUSET_SIZE - 2, false) == 0); 89 CU_ASSERT(spdk_cpuset_count(set) == 2); 90 91 /* Set all cpus */ 92 for (cpu = 0; cpu < SPDK_CPUSET_SIZE; cpu++) { 93 spdk_cpuset_set_cpu(set, cpu, true); 94 } 95 CU_ASSERT(cpuset_check_range(set, 0, SPDK_CPUSET_SIZE - 1, true) == 0); 96 CU_ASSERT(spdk_cpuset_count(set) == SPDK_CPUSET_SIZE); 97 98 /* Clear all cpus */ 99 spdk_cpuset_zero(set); 100 CU_ASSERT(cpuset_check_range(set, 0, SPDK_CPUSET_SIZE - 1, false) == 0); 101 CU_ASSERT(spdk_cpuset_count(set) == 0); 102 103 spdk_cpuset_free(set); 104 } 105 106 static void 107 test_cpuset_parse(void) 108 { 109 int rc; 110 struct spdk_cpuset *core_mask; 111 char buf[1024]; 112 113 core_mask = spdk_cpuset_alloc(); 114 SPDK_CU_ASSERT_FATAL(core_mask != NULL); 115 116 /* Only core 0 should be set */ 117 rc = spdk_cpuset_parse(core_mask, "0x1"); 118 CU_ASSERT(rc >= 0); 119 CU_ASSERT(cpuset_check_range(core_mask, 0, 0, true) == 0); 120 CU_ASSERT(cpuset_check_range(core_mask, 1, SPDK_CPUSET_SIZE - 1, false) == 0); 121 122 /* Only core 1 should be set */ 123 rc = spdk_cpuset_parse(core_mask, "[1]"); 124 CU_ASSERT(rc >= 0); 125 CU_ASSERT(cpuset_check_range(core_mask, 0, 0, false) == 0); 126 CU_ASSERT(cpuset_check_range(core_mask, 1, 1, true) == 0); 127 CU_ASSERT(cpuset_check_range(core_mask, 2, SPDK_CPUSET_SIZE - 1, false) == 0); 128 129 /* Set cores 0-10,12,128-254 */ 130 rc = spdk_cpuset_parse(core_mask, "[0-10,12,128-254]"); 131 CU_ASSERT(rc >= 0); 132 CU_ASSERT(cpuset_check_range(core_mask, 0, 10, true) == 0); 133 CU_ASSERT(cpuset_check_range(core_mask, 11, 11, false) == 0); 134 CU_ASSERT(cpuset_check_range(core_mask, 12, 12, true) == 0); 135 CU_ASSERT(cpuset_check_range(core_mask, 13, 127, false) == 0); 136 CU_ASSERT(cpuset_check_range(core_mask, 128, 254, true) == 0); 137 CU_ASSERT(cpuset_check_range(core_mask, 255, SPDK_CPUSET_SIZE - 1, false) == 0); 138 139 /* Set all cores */ 140 snprintf(buf, sizeof(buf), "[0-%d]", SPDK_CPUSET_SIZE - 1); 141 rc = spdk_cpuset_parse(core_mask, buf); 142 CU_ASSERT(rc >= 0); 143 CU_ASSERT(cpuset_check_range(core_mask, 0, SPDK_CPUSET_SIZE - 1, true) == 0); 144 145 /* Null parameters not allowed */ 146 rc = spdk_cpuset_parse(core_mask, NULL); 147 CU_ASSERT(rc < 0); 148 149 rc = spdk_cpuset_parse(NULL, "[1]"); 150 CU_ASSERT(rc < 0); 151 152 /* Wrong formated core lists */ 153 rc = spdk_cpuset_parse(core_mask, ""); 154 CU_ASSERT(rc < 0); 155 156 rc = spdk_cpuset_parse(core_mask, "["); 157 CU_ASSERT(rc < 0); 158 159 rc = spdk_cpuset_parse(core_mask, "[]"); 160 CU_ASSERT(rc < 0); 161 162 rc = spdk_cpuset_parse(core_mask, "[10--11]"); 163 CU_ASSERT(rc < 0); 164 165 rc = spdk_cpuset_parse(core_mask, "[11-10]"); 166 CU_ASSERT(rc < 0); 167 168 rc = spdk_cpuset_parse(core_mask, "[10-11,]"); 169 CU_ASSERT(rc < 0); 170 171 rc = spdk_cpuset_parse(core_mask, "[,10-11]"); 172 CU_ASSERT(rc < 0); 173 174 /* Out of range value */ 175 snprintf(buf, sizeof(buf), "[%d]", SPDK_CPUSET_SIZE + 1); 176 rc = spdk_cpuset_parse(core_mask, buf); 177 CU_ASSERT(rc < 0); 178 179 /* Overflow value (UINT64_MAX * 10) */ 180 rc = spdk_cpuset_parse(core_mask, "[184467440737095516150]"); 181 CU_ASSERT(rc < 0); 182 183 spdk_cpuset_free(core_mask); 184 } 185 186 static void 187 test_cpuset_fmt(void) 188 { 189 int i; 190 uint32_t lcore; 191 struct spdk_cpuset *core_mask = spdk_cpuset_alloc(); 192 const char *hex_mask; 193 char hex_mask_ref[SPDK_CPUSET_SIZE / 4 + 1]; 194 195 /* Clear coremask. hex_mask should be "0" */ 196 spdk_cpuset_zero(core_mask); 197 hex_mask = spdk_cpuset_fmt(core_mask); 198 SPDK_CU_ASSERT_FATAL(hex_mask != NULL); 199 CU_ASSERT(strcmp("0", hex_mask) == 0); 200 201 /* Set coremask 0x51234. Result should be "51234" */ 202 spdk_cpuset_zero(core_mask); 203 spdk_cpuset_set_cpu(core_mask, 2, true); 204 spdk_cpuset_set_cpu(core_mask, 4, true); 205 spdk_cpuset_set_cpu(core_mask, 5, true); 206 spdk_cpuset_set_cpu(core_mask, 9, true); 207 spdk_cpuset_set_cpu(core_mask, 12, true); 208 spdk_cpuset_set_cpu(core_mask, 16, true); 209 spdk_cpuset_set_cpu(core_mask, 18, true); 210 hex_mask = spdk_cpuset_fmt(core_mask); 211 SPDK_CU_ASSERT_FATAL(hex_mask != NULL); 212 CU_ASSERT(strcmp("51234", hex_mask) == 0); 213 214 /* Set all cores */ 215 spdk_cpuset_zero(core_mask); 216 CU_ASSERT(cpuset_check_range(core_mask, 0, SPDK_CPUSET_SIZE - 1, false) == 0); 217 218 for (lcore = 0; lcore < SPDK_CPUSET_SIZE; lcore++) { 219 spdk_cpuset_set_cpu(core_mask, lcore, true); 220 } 221 for (i = 0; i < SPDK_CPUSET_SIZE / 4; i++) { 222 hex_mask_ref[i] = 'f'; 223 } 224 hex_mask_ref[SPDK_CPUSET_SIZE / 4] = '\0'; 225 226 /* Check data before format */ 227 CU_ASSERT(cpuset_check_range(core_mask, 0, SPDK_CPUSET_SIZE - 1, true) == 0); 228 229 hex_mask = spdk_cpuset_fmt(core_mask); 230 SPDK_CU_ASSERT_FATAL(hex_mask != NULL); 231 CU_ASSERT(strcmp(hex_mask_ref, hex_mask) == 0); 232 233 /* Check data integrity after format */ 234 CU_ASSERT(cpuset_check_range(core_mask, 0, SPDK_CPUSET_SIZE - 1, true) == 0); 235 236 spdk_cpuset_free(core_mask); 237 } 238 239 int 240 main(int argc, char **argv) 241 { 242 CU_pSuite suite = NULL; 243 unsigned int num_failures; 244 245 if (CU_initialize_registry() != CUE_SUCCESS) { 246 return CU_get_error(); 247 } 248 249 suite = CU_add_suite("cpuset", NULL, NULL); 250 if (suite == NULL) { 251 CU_cleanup_registry(); 252 return CU_get_error(); 253 } 254 255 if ( 256 CU_add_test(suite, "test_cpuset", test_cpuset) == NULL || 257 CU_add_test(suite, "test_cpuset_parse", test_cpuset_parse) == NULL || 258 CU_add_test(suite, "test_cpuset_fmt", test_cpuset_fmt) == NULL) { 259 CU_cleanup_registry(); 260 return CU_get_error(); 261 } 262 263 CU_basic_set_mode(CU_BRM_VERBOSE); 264 265 CU_basic_run_tests(); 266 267 num_failures = CU_get_number_of_failures(); 268 CU_cleanup_registry(); 269 270 return num_failures; 271 } 272