xref: /spdk/test/unit/lib/util/cpuset.c/cpuset_ut.c (revision a6dbe3721eb3b5990707fc3e378c95e505dd8ab5)
1  /*   SPDX-License-Identifier: BSD-3-Clause
2   *   Copyright (C) 2017 Intel Corporation.
3   *   All rights reserved.
4   */
5  
6  #include "spdk/stdinc.h"
7  #include "spdk/cpuset.h"
8  
9  #include "spdk_cunit.h"
10  
11  #include "util/cpuset.c"
12  
13  static int
14  cpuset_check_range(struct spdk_cpuset *core_mask, uint32_t min, uint32_t max, bool isset)
15  {
16  	uint32_t core;
17  	for (core = min; core <= max; core++) {
18  		if (isset != spdk_cpuset_get_cpu(core_mask, core)) {
19  			return -1;
20  		}
21  	}
22  	return 0;
23  }
24  
25  static void
26  test_cpuset(void)
27  {
28  	uint32_t cpu;
29  	struct spdk_cpuset *set = spdk_cpuset_alloc();
30  
31  	SPDK_CU_ASSERT_FATAL(set != NULL);
32  	CU_ASSERT(spdk_cpuset_count(set) == 0);
33  
34  	/* Set cpu 0 */
35  	spdk_cpuset_set_cpu(set, 0, true);
36  	CU_ASSERT(spdk_cpuset_get_cpu(set, 0) == true);
37  	CU_ASSERT(cpuset_check_range(set, 1, SPDK_CPUSET_SIZE - 1, false) == 0);
38  	CU_ASSERT(spdk_cpuset_count(set) == 1);
39  
40  	/* Set last cpu (cpu 0 already set) */
41  	spdk_cpuset_set_cpu(set, SPDK_CPUSET_SIZE - 1, true);
42  	CU_ASSERT(spdk_cpuset_get_cpu(set, 0) == true);
43  	CU_ASSERT(spdk_cpuset_get_cpu(set, SPDK_CPUSET_SIZE - 1) == true);
44  	CU_ASSERT(cpuset_check_range(set, 1, SPDK_CPUSET_SIZE - 2, false) == 0);
45  	CU_ASSERT(spdk_cpuset_count(set) == 2);
46  
47  	/* Clear cpu 0 (last cpu already set) */
48  	spdk_cpuset_set_cpu(set, 0, false);
49  	CU_ASSERT(spdk_cpuset_get_cpu(set, 0) == false);
50  	CU_ASSERT(cpuset_check_range(set, 1, SPDK_CPUSET_SIZE - 2, false) == 0);
51  	CU_ASSERT(spdk_cpuset_get_cpu(set, SPDK_CPUSET_SIZE - 1) == true);
52  	CU_ASSERT(spdk_cpuset_count(set) == 1);
53  
54  	/* Set middle cpu (last cpu already set) */
55  	cpu = (SPDK_CPUSET_SIZE - 1) / 2;
56  	spdk_cpuset_set_cpu(set, cpu, true);
57  	CU_ASSERT(spdk_cpuset_get_cpu(set, cpu) == true);
58  	CU_ASSERT(spdk_cpuset_get_cpu(set, SPDK_CPUSET_SIZE - 1) == true);
59  	CU_ASSERT(cpuset_check_range(set, 1, cpu - 1, false) == 0);
60  	CU_ASSERT(cpuset_check_range(set, cpu + 1, SPDK_CPUSET_SIZE - 2, false) == 0);
61  	CU_ASSERT(spdk_cpuset_count(set) == 2);
62  
63  	/* Set all cpus */
64  	for (cpu = 0; cpu < SPDK_CPUSET_SIZE; cpu++) {
65  		spdk_cpuset_set_cpu(set, cpu, true);
66  	}
67  	CU_ASSERT(cpuset_check_range(set, 0, SPDK_CPUSET_SIZE - 1, true) == 0);
68  	CU_ASSERT(spdk_cpuset_count(set) == SPDK_CPUSET_SIZE);
69  
70  	/* Clear all cpus */
71  	spdk_cpuset_zero(set);
72  	CU_ASSERT(cpuset_check_range(set, 0, SPDK_CPUSET_SIZE - 1, false) == 0);
73  	CU_ASSERT(spdk_cpuset_count(set) == 0);
74  
75  	spdk_cpuset_free(set);
76  }
77  
78  static void
79  test_cpuset_parse(void)
80  {
81  	int rc;
82  	struct spdk_cpuset *core_mask;
83  	char buf[1024];
84  
85  	core_mask = spdk_cpuset_alloc();
86  	SPDK_CU_ASSERT_FATAL(core_mask != NULL);
87  
88  	/* Only core 0 should be set */
89  	rc = spdk_cpuset_parse(core_mask, "0x1");
90  	CU_ASSERT(rc >= 0);
91  	CU_ASSERT(cpuset_check_range(core_mask, 0, 0, true) == 0);
92  	CU_ASSERT(cpuset_check_range(core_mask, 1, SPDK_CPUSET_SIZE - 1, false) == 0);
93  
94  	/* Only core 1 should be set */
95  	rc = spdk_cpuset_parse(core_mask, "[1]");
96  	CU_ASSERT(rc >= 0);
97  	CU_ASSERT(cpuset_check_range(core_mask, 0, 0, false) == 0);
98  	CU_ASSERT(cpuset_check_range(core_mask, 1, 1, true) == 0);
99  	CU_ASSERT(cpuset_check_range(core_mask, 2, SPDK_CPUSET_SIZE - 1, false) == 0);
100  
101  	/* Set cores 0-10,12,128-254 */
102  	rc = spdk_cpuset_parse(core_mask, "[0-10,12,128-254]");
103  	CU_ASSERT(rc >= 0);
104  	CU_ASSERT(cpuset_check_range(core_mask, 0, 10, true) == 0);
105  	CU_ASSERT(cpuset_check_range(core_mask, 11, 11, false) == 0);
106  	CU_ASSERT(cpuset_check_range(core_mask, 12, 12, true) == 0);
107  	CU_ASSERT(cpuset_check_range(core_mask, 13, 127, false) == 0);
108  	CU_ASSERT(cpuset_check_range(core_mask, 128, 254, true) == 0);
109  	CU_ASSERT(cpuset_check_range(core_mask, 255, SPDK_CPUSET_SIZE - 1, false) == 0);
110  
111  	/* Set all cores */
112  	snprintf(buf, sizeof(buf), "[0-%d]", SPDK_CPUSET_SIZE - 1);
113  	rc = spdk_cpuset_parse(core_mask, buf);
114  	CU_ASSERT(rc >= 0);
115  	CU_ASSERT(cpuset_check_range(core_mask, 0, SPDK_CPUSET_SIZE - 1, true) == 0);
116  
117  	/* Null parameters not allowed */
118  	rc = spdk_cpuset_parse(core_mask, NULL);
119  	CU_ASSERT(rc < 0);
120  
121  	rc = spdk_cpuset_parse(NULL, "[1]");
122  	CU_ASSERT(rc < 0);
123  
124  	/* Wrong formated core lists */
125  	rc = spdk_cpuset_parse(core_mask, "");
126  	CU_ASSERT(rc < 0);
127  
128  	rc = spdk_cpuset_parse(core_mask, "[");
129  	CU_ASSERT(rc < 0);
130  
131  	rc = spdk_cpuset_parse(core_mask, "[]");
132  	CU_ASSERT(rc < 0);
133  
134  	rc = spdk_cpuset_parse(core_mask, "[10--11]");
135  	CU_ASSERT(rc < 0);
136  
137  	rc = spdk_cpuset_parse(core_mask, "[11-10]");
138  	CU_ASSERT(rc < 0);
139  
140  	rc = spdk_cpuset_parse(core_mask, "[10-11,]");
141  	CU_ASSERT(rc < 0);
142  
143  	rc = spdk_cpuset_parse(core_mask, "[,10-11]");
144  	CU_ASSERT(rc < 0);
145  
146  	/* Out of range value */
147  	snprintf(buf, sizeof(buf), "[%d]", SPDK_CPUSET_SIZE + 1);
148  	rc = spdk_cpuset_parse(core_mask, buf);
149  	CU_ASSERT(rc < 0);
150  
151  	/* Overflow value (UINT64_MAX * 10) */
152  	rc = spdk_cpuset_parse(core_mask, "[184467440737095516150]");
153  	CU_ASSERT(rc < 0);
154  
155  	/* Test mask with cores 4-7 and 168-171 set. */
156  	rc = spdk_cpuset_parse(core_mask, "0xF0000000000000000000000000000000000000000F0");
157  	CU_ASSERT(rc == 0);
158  	CU_ASSERT(cpuset_check_range(core_mask, 0, 3, false) == 0);
159  	CU_ASSERT(cpuset_check_range(core_mask, 4, 7, true) == 0);
160  	CU_ASSERT(cpuset_check_range(core_mask, 8, 167, false) == 0);
161  	CU_ASSERT(cpuset_check_range(core_mask, 168, 171, true) == 0);
162  	CU_ASSERT(cpuset_check_range(core_mask, 172, SPDK_CPUSET_SIZE - 1, false) == 0);
163  
164  	spdk_cpuset_free(core_mask);
165  }
166  
167  static void
168  test_cpuset_fmt(void)
169  {
170  	int i;
171  	uint32_t lcore;
172  	struct spdk_cpuset *core_mask = spdk_cpuset_alloc();
173  	const char *hex_mask;
174  	char hex_mask_ref[SPDK_CPUSET_SIZE / 4 + 1];
175  
176  	/* Clear coremask. hex_mask should be "0" */
177  	spdk_cpuset_zero(core_mask);
178  	hex_mask = spdk_cpuset_fmt(core_mask);
179  	SPDK_CU_ASSERT_FATAL(hex_mask != NULL);
180  	CU_ASSERT(strcmp("0", hex_mask) == 0);
181  
182  	/* Set coremask 0x51234. Result should be "51234" */
183  	spdk_cpuset_zero(core_mask);
184  	spdk_cpuset_set_cpu(core_mask, 2, true);
185  	spdk_cpuset_set_cpu(core_mask, 4, true);
186  	spdk_cpuset_set_cpu(core_mask, 5, true);
187  	spdk_cpuset_set_cpu(core_mask, 9, true);
188  	spdk_cpuset_set_cpu(core_mask, 12, true);
189  	spdk_cpuset_set_cpu(core_mask, 16, true);
190  	spdk_cpuset_set_cpu(core_mask, 18, true);
191  	hex_mask = spdk_cpuset_fmt(core_mask);
192  	SPDK_CU_ASSERT_FATAL(hex_mask != NULL);
193  	CU_ASSERT(strcmp("51234", hex_mask) == 0);
194  
195  	/* Set all cores */
196  	spdk_cpuset_zero(core_mask);
197  	CU_ASSERT(cpuset_check_range(core_mask, 0, SPDK_CPUSET_SIZE - 1, false) == 0);
198  
199  	for (lcore = 0; lcore < SPDK_CPUSET_SIZE; lcore++) {
200  		spdk_cpuset_set_cpu(core_mask, lcore, true);
201  	}
202  	for (i = 0; i < SPDK_CPUSET_SIZE / 4; i++) {
203  		hex_mask_ref[i] = 'f';
204  	}
205  	hex_mask_ref[SPDK_CPUSET_SIZE / 4] = '\0';
206  
207  	/* Check data before format */
208  	CU_ASSERT(cpuset_check_range(core_mask, 0, SPDK_CPUSET_SIZE - 1, true) == 0);
209  
210  	hex_mask = spdk_cpuset_fmt(core_mask);
211  	SPDK_CU_ASSERT_FATAL(hex_mask != NULL);
212  	CU_ASSERT(strcmp(hex_mask_ref, hex_mask) == 0);
213  
214  	/* Check data integrity after format */
215  	CU_ASSERT(cpuset_check_range(core_mask, 0, SPDK_CPUSET_SIZE - 1, true) == 0);
216  
217  	spdk_cpuset_free(core_mask);
218  }
219  
220  int
221  main(int argc, char **argv)
222  {
223  	CU_pSuite	suite = NULL;
224  	unsigned int	num_failures;
225  
226  	CU_set_error_action(CUEA_ABORT);
227  	CU_initialize_registry();
228  
229  	suite = CU_add_suite("cpuset", NULL, NULL);
230  
231  	CU_ADD_TEST(suite, test_cpuset);
232  	CU_ADD_TEST(suite, test_cpuset_parse);
233  	CU_ADD_TEST(suite, test_cpuset_fmt);
234  
235  	CU_basic_set_mode(CU_BRM_VERBOSE);
236  
237  	CU_basic_run_tests();
238  
239  	num_failures = CU_get_number_of_failures();
240  	CU_cleanup_registry();
241  
242  	return num_failures;
243  }
244