]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/test/common/lib/test_env.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / test / common / lib / test_env.c
CommitLineData
11fdf7f2
TL
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
36#include "spdk_internal/mock.h"
37
38#include "spdk/env.h"
39#include "spdk/queue.h"
9f95a23c 40#include "spdk/util.h"
11fdf7f2
TL
41
42DEFINE_STUB(spdk_process_is_primary, bool, (void), true)
43DEFINE_STUB(spdk_memzone_lookup, void *, (const char *name), NULL)
9f95a23c
TL
44DEFINE_STUB(spdk_pci_nvme_get_driver, struct spdk_pci_driver *, (void), NULL)
45DEFINE_STUB(spdk_pci_ioat_get_driver, struct spdk_pci_driver *, (void), NULL)
46DEFINE_STUB(spdk_pci_virtio_get_driver, struct spdk_pci_driver *, (void), NULL)
11fdf7f2
TL
47
48/*
49 * These mocks don't use the DEFINE_STUB macros because
50 * their default implementation is more complex.
51 */
52
53DEFINE_RETURN_MOCK(spdk_memzone_reserve, void *);
54void *
55spdk_memzone_reserve(const char *name, size_t len, int socket_id, unsigned flags)
56{
57 HANDLE_RETURN_MOCK(spdk_memzone_reserve);
58
59 return malloc(len);
60}
61
62DEFINE_RETURN_MOCK(spdk_memzone_reserve_aligned, void *);
63void *
64spdk_memzone_reserve_aligned(const char *name, size_t len, int socket_id,
65 unsigned flags, unsigned align)
66{
67 HANDLE_RETURN_MOCK(spdk_memzone_reserve_aligned);
68
69 return malloc(len);
70}
71
72DEFINE_RETURN_MOCK(spdk_malloc, void *);
73void *
74spdk_malloc(size_t size, size_t align, uint64_t *phys_addr, int socket_id, uint32_t flags)
75{
76 HANDLE_RETURN_MOCK(spdk_malloc);
77
78 void *buf = NULL;
9f95a23c
TL
79
80 if (align == 0) {
81 align = 8;
82 }
83
11fdf7f2
TL
84 if (posix_memalign(&buf, align, size)) {
85 return NULL;
86 }
87 if (phys_addr) {
88 *phys_addr = (uint64_t)buf;
89 }
90
91 return buf;
92}
93
94DEFINE_RETURN_MOCK(spdk_zmalloc, void *);
95void *
96spdk_zmalloc(size_t size, size_t align, uint64_t *phys_addr, int socket_id, uint32_t flags)
97{
98 HANDLE_RETURN_MOCK(spdk_zmalloc);
99
100 void *buf = spdk_malloc(size, align, phys_addr, -1, 1);
101
102 if (buf != NULL) {
103 memset(buf, 0, size);
104 }
105 return buf;
106}
107
108DEFINE_RETURN_MOCK(spdk_dma_malloc, void *);
109void *
110spdk_dma_malloc(size_t size, size_t align, uint64_t *phys_addr)
111{
112 HANDLE_RETURN_MOCK(spdk_dma_malloc);
113
114 return spdk_malloc(size, align, phys_addr, -1, 1);
115}
116
9f95a23c
TL
117DEFINE_RETURN_MOCK(spdk_realloc, void *);
118void *
119spdk_realloc(void *buf, size_t size, size_t align)
120{
121 HANDLE_RETURN_MOCK(spdk_realloc);
122
123 return realloc(buf, size);
124}
125
11fdf7f2
TL
126DEFINE_RETURN_MOCK(spdk_dma_zmalloc, void *);
127void *
128spdk_dma_zmalloc(size_t size, size_t align, uint64_t *phys_addr)
129{
130 HANDLE_RETURN_MOCK(spdk_dma_zmalloc);
131
132 return spdk_zmalloc(size, align, phys_addr, -1, 1);
133}
134
135DEFINE_RETURN_MOCK(spdk_dma_malloc_socket, void *);
136void *
137spdk_dma_malloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id)
138{
139 HANDLE_RETURN_MOCK(spdk_dma_malloc_socket);
140
141 return spdk_dma_malloc(size, align, phys_addr);
142}
143
144DEFINE_RETURN_MOCK(spdk_dma_zmalloc_socket, void *);
145void *
146spdk_dma_zmalloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id)
147{
148 HANDLE_RETURN_MOCK(spdk_dma_zmalloc_socket);
149
150 return spdk_dma_zmalloc(size, align, phys_addr);
151}
152
153DEFINE_RETURN_MOCK(spdk_dma_realloc, void *);
154void *
155spdk_dma_realloc(void *buf, size_t size, size_t align, uint64_t *phys_addr)
156{
157 HANDLE_RETURN_MOCK(spdk_dma_realloc);
158
159 return realloc(buf, size);
160}
161
162void
163spdk_free(void *buf)
164{
9f95a23c
TL
165 /* fix for false-positives in *certain* static analysis tools. */
166 assert((uintptr_t)buf != UINTPTR_MAX);
11fdf7f2
TL
167 free(buf);
168}
169
170void
171spdk_dma_free(void *buf)
172{
173 return spdk_free(buf);
174}
175
9f95a23c 176#ifndef UNIT_TEST_NO_VTOPHYS
11fdf7f2
TL
177DEFINE_RETURN_MOCK(spdk_vtophys, uint64_t);
178uint64_t
9f95a23c 179spdk_vtophys(void *buf, uint64_t *size)
11fdf7f2
TL
180{
181 HANDLE_RETURN_MOCK(spdk_vtophys);
182
183 return (uintptr_t)buf;
184}
9f95a23c 185#endif
11fdf7f2
TL
186
187void
188spdk_memzone_dump(FILE *f)
189{
190 return;
191}
192
193DEFINE_RETURN_MOCK(spdk_memzone_free, int);
194int
195spdk_memzone_free(const char *name)
196{
197 HANDLE_RETURN_MOCK(spdk_memzone_free);
198
199 return 0;
200}
201
202struct test_mempool {
203 size_t count;
9f95a23c 204 size_t ele_size;
11fdf7f2
TL
205};
206
207DEFINE_RETURN_MOCK(spdk_mempool_create, struct spdk_mempool *);
208struct spdk_mempool *
209spdk_mempool_create(const char *name, size_t count,
210 size_t ele_size, size_t cache_size, int socket_id)
211{
212 struct test_mempool *mp;
213
214 HANDLE_RETURN_MOCK(spdk_mempool_create);
215
216 mp = calloc(1, sizeof(*mp));
217 if (mp == NULL) {
218 return NULL;
219 }
220
221 mp->count = count;
9f95a23c 222 mp->ele_size = ele_size;
11fdf7f2
TL
223
224 return (struct spdk_mempool *)mp;
225}
226
227void
228spdk_mempool_free(struct spdk_mempool *_mp)
229{
230 struct test_mempool *mp = (struct test_mempool *)_mp;
231
232 free(mp);
233}
234
235DEFINE_RETURN_MOCK(spdk_mempool_get, void *);
236void *
237spdk_mempool_get(struct spdk_mempool *_mp)
238{
239 struct test_mempool *mp = (struct test_mempool *)_mp;
9f95a23c 240 size_t ele_size = 0x10000;
11fdf7f2
TL
241 void *buf;
242
243 HANDLE_RETURN_MOCK(spdk_mempool_get);
244
245 if (mp && mp->count == 0) {
246 return NULL;
247 }
248
9f95a23c
TL
249 if (mp) {
250 ele_size = mp->ele_size;
251 }
252
253 if (posix_memalign(&buf, 64, spdk_align32pow2(ele_size))) {
11fdf7f2
TL
254 return NULL;
255 } else {
256 if (mp) {
257 mp->count--;
258 }
259 return buf;
260 }
261}
262
263int
264spdk_mempool_get_bulk(struct spdk_mempool *mp, void **ele_arr, size_t count)
265{
266 for (size_t i = 0; i < count; i++) {
267 ele_arr[i] = spdk_mempool_get(mp);
268 if (ele_arr[i] == NULL) {
269 return -1;
270 }
271 }
272 return 0;
273}
274
275void
276spdk_mempool_put(struct spdk_mempool *_mp, void *ele)
277{
278 struct test_mempool *mp = (struct test_mempool *)_mp;
279
280 if (mp) {
281 mp->count++;
282 }
283 free(ele);
284}
285
286void
287spdk_mempool_put_bulk(struct spdk_mempool *mp, void **ele_arr, size_t count)
288{
289 for (size_t i = 0; i < count; i++) {
290 spdk_mempool_put(mp, ele_arr[i]);
291 }
292}
293
294DEFINE_RETURN_MOCK(spdk_mempool_count, size_t);
295size_t
296spdk_mempool_count(const struct spdk_mempool *_mp)
297{
298 struct test_mempool *mp = (struct test_mempool *)_mp;
299
300 HANDLE_RETURN_MOCK(spdk_mempool_count);
301
302 if (mp) {
303 return mp->count;
304 } else {
305 return 1024;
306 }
307}
308
309struct spdk_ring_ele {
310 void *ele;
311 TAILQ_ENTRY(spdk_ring_ele) link;
312};
313
314struct spdk_ring {
315 TAILQ_HEAD(, spdk_ring_ele) elements;
9f95a23c
TL
316 pthread_mutex_t lock;
317 size_t count;
11fdf7f2
TL
318};
319
320DEFINE_RETURN_MOCK(spdk_ring_create, struct spdk_ring *);
321struct spdk_ring *
322spdk_ring_create(enum spdk_ring_type type, size_t count, int socket_id)
323{
324 struct spdk_ring *ring;
325
326 HANDLE_RETURN_MOCK(spdk_ring_create);
327
328 ring = calloc(1, sizeof(*ring));
9f95a23c
TL
329 if (!ring) {
330 return NULL;
331 }
332
333 if (pthread_mutex_init(&ring->lock, NULL)) {
334 free(ring);
335 return NULL;
11fdf7f2
TL
336 }
337
9f95a23c 338 TAILQ_INIT(&ring->elements);
11fdf7f2
TL
339 return ring;
340}
341
342void
343spdk_ring_free(struct spdk_ring *ring)
344{
9f95a23c
TL
345 struct spdk_ring_ele *ele, *tmp;
346
347 if (!ring) {
348 return;
349 }
350
351 TAILQ_FOREACH_SAFE(ele, &ring->elements, link, tmp) {
352 free(ele);
353 }
354
355 pthread_mutex_destroy(&ring->lock);
11fdf7f2
TL
356 free(ring);
357}
358
359DEFINE_RETURN_MOCK(spdk_ring_enqueue, size_t);
360size_t
9f95a23c
TL
361spdk_ring_enqueue(struct spdk_ring *ring, void **objs, size_t count,
362 size_t *free_space)
11fdf7f2
TL
363{
364 struct spdk_ring_ele *ele;
365 size_t i;
366
367 HANDLE_RETURN_MOCK(spdk_ring_enqueue);
368
9f95a23c
TL
369 pthread_mutex_lock(&ring->lock);
370
11fdf7f2
TL
371 for (i = 0; i < count; i++) {
372 ele = calloc(1, sizeof(*ele));
373 if (!ele) {
374 break;
375 }
376
377 ele->ele = objs[i];
378 TAILQ_INSERT_TAIL(&ring->elements, ele, link);
9f95a23c 379 ring->count++;
11fdf7f2
TL
380 }
381
9f95a23c 382 pthread_mutex_unlock(&ring->lock);
11fdf7f2
TL
383 return i;
384}
385
386DEFINE_RETURN_MOCK(spdk_ring_dequeue, size_t);
387size_t
388spdk_ring_dequeue(struct spdk_ring *ring, void **objs, size_t count)
389{
390 struct spdk_ring_ele *ele, *tmp;
391 size_t i = 0;
392
393 HANDLE_RETURN_MOCK(spdk_ring_dequeue);
394
395 if (count == 0) {
396 return 0;
397 }
398
9f95a23c
TL
399 pthread_mutex_lock(&ring->lock);
400
11fdf7f2
TL
401 TAILQ_FOREACH_SAFE(ele, &ring->elements, link, tmp) {
402 TAILQ_REMOVE(&ring->elements, ele, link);
9f95a23c 403 ring->count--;
11fdf7f2
TL
404 objs[i] = ele->ele;
405 free(ele);
406 i++;
407 if (i >= count) {
408 break;
409 }
410 }
411
9f95a23c 412 pthread_mutex_unlock(&ring->lock);
11fdf7f2
TL
413 return i;
414
415}
416
9f95a23c
TL
417
418DEFINE_RETURN_MOCK(spdk_ring_count, size_t);
419size_t
420spdk_ring_count(struct spdk_ring *ring)
421{
422 HANDLE_RETURN_MOCK(spdk_ring_count);
423 return ring->count;
424}
425
11fdf7f2
TL
426DEFINE_RETURN_MOCK(spdk_get_ticks, uint64_t);
427uint64_t
428spdk_get_ticks(void)
429{
430 HANDLE_RETURN_MOCK(spdk_get_ticks);
431
432 return ut_spdk_get_ticks;
433}
434
435DEFINE_RETURN_MOCK(spdk_get_ticks_hz, uint64_t);
436uint64_t
437spdk_get_ticks_hz(void)
438{
439 HANDLE_RETURN_MOCK(spdk_get_ticks_hz);
440
441 return 1000000;
442}
443
444void
445spdk_delay_us(unsigned int us)
446{
447 /* spdk_get_ticks_hz is 1000000, meaning 1 tick per us. */
448 ut_spdk_get_ticks += us;
449}
450
9f95a23c 451#ifndef UNIT_TEST_NO_PCI_ADDR
11fdf7f2
TL
452DEFINE_RETURN_MOCK(spdk_pci_addr_parse, int);
453int
454spdk_pci_addr_parse(struct spdk_pci_addr *addr, const char *bdf)
455{
456 unsigned domain, bus, dev, func;
457
458 HANDLE_RETURN_MOCK(spdk_pci_addr_parse);
459
460 if (addr == NULL || bdf == NULL) {
461 return -EINVAL;
462 }
463
464 if ((sscanf(bdf, "%x:%x:%x.%x", &domain, &bus, &dev, &func) == 4) ||
465 (sscanf(bdf, "%x.%x.%x.%x", &domain, &bus, &dev, &func) == 4)) {
466 /* Matched a full address - all variables are initialized */
467 } else if (sscanf(bdf, "%x:%x:%x", &domain, &bus, &dev) == 3) {
468 func = 0;
469 } else if ((sscanf(bdf, "%x:%x.%x", &bus, &dev, &func) == 3) ||
470 (sscanf(bdf, "%x.%x.%x", &bus, &dev, &func) == 3)) {
471 domain = 0;
472 } else if ((sscanf(bdf, "%x:%x", &bus, &dev) == 2) ||
473 (sscanf(bdf, "%x.%x", &bus, &dev) == 2)) {
474 domain = 0;
475 func = 0;
476 } else {
477 return -EINVAL;
478 }
479
480 if (bus > 0xFF || dev > 0x1F || func > 7) {
481 return -EINVAL;
482 }
483
484 addr->domain = domain;
485 addr->bus = bus;
486 addr->dev = dev;
487 addr->func = func;
488
489 return 0;
490}
491
492DEFINE_RETURN_MOCK(spdk_pci_addr_fmt, int);
493int
494spdk_pci_addr_fmt(char *bdf, size_t sz, const struct spdk_pci_addr *addr)
495{
496 int rc;
497
498 HANDLE_RETURN_MOCK(spdk_pci_addr_fmt);
499
500 rc = snprintf(bdf, sz, "%04x:%02x:%02x.%x",
501 addr->domain, addr->bus,
502 addr->dev, addr->func);
503
504 if (rc > 0 && (size_t)rc < sz) {
505 return 0;
506 }
507
508 return -1;
509}
510
511DEFINE_RETURN_MOCK(spdk_pci_addr_compare, int);
512int
513spdk_pci_addr_compare(const struct spdk_pci_addr *a1, const struct spdk_pci_addr *a2)
514{
515 HANDLE_RETURN_MOCK(spdk_pci_addr_compare);
516
517 if (a1->domain > a2->domain) {
518 return 1;
519 } else if (a1->domain < a2->domain) {
520 return -1;
521 } else if (a1->bus > a2->bus) {
522 return 1;
523 } else if (a1->bus < a2->bus) {
524 return -1;
525 } else if (a1->dev > a2->dev) {
526 return 1;
527 } else if (a1->dev < a2->dev) {
528 return -1;
529 } else if (a1->func > a2->func) {
530 return 1;
531 } else if (a1->func < a2->func) {
532 return -1;
533 }
534
535 return 0;
536}
9f95a23c 537#endif