]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/lib/bdev/ocf/env/ocf_env.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / lib / bdev / ocf / env / ocf_env.h
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
35 #ifndef __LIBOCF_ENV_H__
36 #define __LIBOCF_ENV_H__
37
38 #ifndef _GNU_SOURCE
39 #define _GNU_SOURCE
40 #endif
41 #ifndef __USE_GNU
42 #define __USE_GNU
43 #endif
44
45 #include <linux/limits.h>
46 #include <linux/stddef.h>
47
48 #include "spdk/stdinc.h"
49 #include "spdk/likely.h"
50 #include "spdk/env.h"
51 #include "spdk/util.h"
52 #include "spdk_internal/log.h"
53
54 #include "ocf_env_list.h"
55 #include "ocf/ocf_err.h"
56
57 typedef uint8_t u8;
58 typedef uint16_t u16;
59 typedef uint32_t u32;
60 typedef uint64_t u64;
61
62 typedef uint64_t sector_t;
63
64 #define __packed __attribute__((packed))
65 #define __aligned(x) __attribute__((aligned(x)))
66
67 /* linux sector 512-bytes */
68 #define ENV_SECTOR_SHIFT 9
69 #define ENV_SECTOR_SIZE (1<<ENV_SECTOR_SHIFT)
70 #define BYTES_TO_SECTOR(x) ((x) >> ENV_SECTOR_SHIFT)
71
72 /* *** MEMORY MANAGEMENT *** */
73
74 #define ENV_MEM_NORMAL 0
75 #define ENV_MEM_NOIO 0
76 #define ENV_MEM_ATOMIC 0
77
78 #define likely spdk_likely
79 #define unlikely spdk_unlikely
80
81 #define min(x, y) MIN(x, y)
82 #ifndef MIN
83 #define MIN(x, y) spdk_min(x, y)
84 #endif
85
86 #define ARRAY_SIZE(x) SPDK_COUNTOF(x)
87
88 /* LOGGING */
89 #define ENV_PRIu64 PRIu64
90
91 #define ENV_WARN(cond, fmt, args...) ({ \
92 if (spdk_unlikely((uintptr_t)(cond))) \
93 SPDK_NOTICELOG("WARNING" fmt, ##args); \
94 })
95
96 #define ENV_WARN_ON(cond) ({ \
97 if (spdk_unlikely((uintptr_t)(cond))) \
98 SPDK_NOTICELOG("WARNING\n"); \
99 })
100
101 #define ENV_BUG() ({ \
102 SPDK_ERRLOG("BUG\n"); \
103 assert(0); \
104 abort(); \
105 })
106
107 #define ENV_BUG_ON(cond) ({ \
108 if (spdk_unlikely((uintptr_t)(cond))) { \
109 SPDK_ERRLOG("BUG\n"); \
110 assert(0); \
111 abort(); \
112 } \
113 })
114
115 #define container_of(ptr, type, member) SPDK_CONTAINEROF(ptr, type, member)
116
117 static inline void *env_malloc(size_t size, int flags)
118 {
119 return spdk_malloc(size, 0, NULL, SPDK_ENV_LCORE_ID_ANY,
120 SPDK_MALLOC_DMA);
121 }
122
123 static inline void *env_zalloc(size_t size, int flags)
124 {
125 return spdk_zmalloc(size, 0, NULL, SPDK_ENV_LCORE_ID_ANY,
126 SPDK_MALLOC_DMA);
127 }
128
129 static inline void env_free(const void *ptr)
130 {
131 return spdk_free((void *)ptr);
132 }
133
134 static inline void *env_vmalloc(size_t size)
135 {
136 return spdk_malloc(size, 0, NULL, SPDK_ENV_LCORE_ID_ANY,
137 SPDK_MALLOC_DMA);
138 }
139
140 static inline void *env_vzalloc(size_t size)
141 {
142 /* TODO: raw_ram init can request huge amount of memory to store
143 * hashtable in it. need to ensure that allocation succedds */
144 return spdk_zmalloc(size, 0, NULL, SPDK_ENV_LCORE_ID_ANY,
145 SPDK_MALLOC_DMA);
146 }
147
148 static inline void *env_secure_alloc(size_t size)
149 {
150 return spdk_zmalloc(size, 0, NULL, SPDK_ENV_LCORE_ID_ANY,
151 SPDK_MALLOC_DMA);
152 }
153
154 static inline void env_secure_free(const void *ptr, size_t size)
155 {
156 return spdk_free((void *)ptr);
157 }
158
159 static inline void env_vfree(const void *ptr)
160 {
161 return spdk_free((void *)ptr);
162 }
163
164 static inline uint64_t env_get_free_memory(void)
165 {
166 /* TODO: do we need implementation for this function? */
167 return sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES);
168 }
169
170 /* *** ALLOCATOR *** */
171
172 #define OCF_ALLOCATOR_NAME_MAX 128
173
174 typedef struct {
175 struct spdk_mempool *mempool;
176 size_t element_size;
177 } env_allocator;
178
179 env_allocator *env_allocator_create(uint32_t size, const char *name);
180
181 void env_allocator_destroy(env_allocator *allocator);
182
183 void *env_allocator_new(env_allocator *allocator);
184
185 void env_allocator_del(env_allocator *allocator, void *item);
186
187 uint32_t env_allocator_item_count(env_allocator *allocator);
188
189 /* *** MUTEX *** */
190
191 typedef struct {
192 pthread_mutex_t m;
193 } env_mutex;
194
195 static inline int env_mutex_init(env_mutex *mutex)
196 {
197 return !!pthread_mutex_init(&mutex->m, NULL);
198 }
199
200 static inline void env_mutex_lock(env_mutex *mutex)
201 {
202 ENV_BUG_ON(pthread_mutex_lock(&mutex->m));
203 }
204
205 static inline int env_mutex_lock_interruptible(env_mutex *mutex)
206 {
207 env_mutex_lock(mutex);
208 return 0;
209 }
210
211 static inline int env_mutex_trylock(env_mutex *mutex)
212 {
213 return pthread_mutex_trylock(&mutex->m) ? -OCF_ERR_NO_LOCK : 0;
214 }
215
216 static inline void env_mutex_unlock(env_mutex *mutex)
217 {
218 ENV_BUG_ON(pthread_mutex_unlock(&mutex->m));
219 }
220
221 static inline int env_mutex_is_locked(env_mutex *mutex)
222 {
223 if (env_mutex_trylock(mutex) == 0) {
224 env_mutex_unlock(mutex);
225 return 0;
226 }
227
228 return 1;
229 }
230
231 /* *** RECURSIVE MUTEX *** */
232
233 typedef env_mutex env_rmutex;
234
235 static inline int env_rmutex_init(env_rmutex *rmutex)
236 {
237 return env_mutex_init(rmutex);
238 }
239
240 static inline void env_rmutex_lock(env_rmutex *rmutex)
241 {
242 env_mutex_lock(rmutex);
243 }
244
245 static inline int env_rmutex_lock_interruptible(env_rmutex *rmutex)
246 {
247 return env_mutex_lock_interruptible(rmutex);
248 }
249
250 static inline int env_rmutex_trylock(env_rmutex *rmutex)
251 {
252 return env_mutex_trylock(rmutex);
253 }
254
255 static inline void env_rmutex_unlock(env_rmutex *rmutex)
256 {
257 env_mutex_unlock(rmutex);
258 }
259
260 static inline int env_rmutex_is_locked(env_rmutex *rmutex)
261 {
262 return env_mutex_is_locked(rmutex);
263 }
264
265 /* *** RW SEMAPHORE *** */
266 typedef struct {
267 pthread_rwlock_t lock;
268 } env_rwsem;
269
270 static inline int env_rwsem_init(env_rwsem *s)
271 {
272 return !!pthread_rwlock_init(&s->lock, NULL);
273 }
274
275 static inline void env_rwsem_up_read(env_rwsem *s)
276 {
277 ENV_BUG_ON(pthread_rwlock_unlock(&s->lock));
278 }
279
280 static inline void env_rwsem_down_read(env_rwsem *s)
281 {
282 ENV_BUG_ON(pthread_rwlock_rdlock(&s->lock));
283 }
284
285 static inline int env_rwsem_down_read_trylock(env_rwsem *s)
286 {
287 return pthread_rwlock_tryrdlock(&s->lock) ? -OCF_ERR_NO_LOCK : 0;
288 }
289
290 static inline void env_rwsem_up_write(env_rwsem *s)
291 {
292 ENV_BUG_ON(pthread_rwlock_unlock(&s->lock));
293 }
294
295 static inline void env_rwsem_down_write(env_rwsem *s)
296 {
297 ENV_BUG_ON(pthread_rwlock_wrlock(&s->lock));
298 }
299
300 static inline int env_rwsem_down_write_trylock(env_rwsem *s)
301 {
302 return pthread_rwlock_trywrlock(&s->lock) ? -OCF_ERR_NO_LOCK : 0;
303 }
304
305 static inline int env_rwsem_is_locked(env_rwsem *s)
306 {
307 if (env_rwsem_down_read_trylock(s) == 0) {
308 env_rwsem_up_read(s);
309 return 0;
310 }
311
312 return 1;
313 }
314
315 static inline int env_rwsem_down_read_interruptible(env_rwsem *s)
316 {
317 return pthread_rwlock_rdlock(&s->lock);
318 }
319 static inline int env_rwsem_down_write_interruptible(env_rwsem *s)
320 {
321 return pthread_rwlock_wrlock(&s->lock);
322 }
323
324 /* *** ATOMIC VARIABLES *** */
325
326 typedef int env_atomic;
327
328 typedef long env_atomic64;
329
330 #ifndef atomic_read
331 #define atomic_read(ptr) (*(__typeof__(*ptr) *volatile) (ptr))
332 #endif
333
334 #ifndef atomic_set
335 #define atomic_set(ptr, i) ((*(__typeof__(*ptr) *volatile) (ptr)) = (i))
336 #endif
337
338 #define atomic_inc(ptr) ((void) __sync_fetch_and_add(ptr, 1))
339 #define atomic_dec(ptr) ((void) __sync_fetch_and_add(ptr, -1))
340 #define atomic_add(ptr, n) ((void) __sync_fetch_and_add(ptr, n))
341 #define atomic_sub(ptr, n) ((void) __sync_fetch_and_sub(ptr, n))
342
343 #define atomic_cmpxchg __sync_val_compare_and_swap
344
345 static inline int env_atomic_read(const env_atomic *a)
346 {
347 return atomic_read(a);
348 }
349
350 static inline void env_atomic_set(env_atomic *a, int i)
351 {
352 atomic_set(a, i);
353 }
354
355 static inline void env_atomic_add(int i, env_atomic *a)
356 {
357 atomic_add(a, i);
358 }
359
360 static inline void env_atomic_sub(int i, env_atomic *a)
361 {
362 atomic_sub(a, i);
363 }
364
365 static inline bool env_atomic_sub_and_test(int i, env_atomic *a)
366 {
367 return __sync_sub_and_fetch(a, i) == 0;
368 }
369
370 static inline void env_atomic_inc(env_atomic *a)
371 {
372 atomic_inc(a);
373 }
374
375 static inline void env_atomic_dec(env_atomic *a)
376 {
377 atomic_dec(a);
378 }
379
380 static inline bool env_atomic_dec_and_test(env_atomic *a)
381 {
382 return __sync_sub_and_fetch(a, 1) == 0;
383 }
384
385 static inline bool env_atomic_inc_and_test(env_atomic *a)
386 {
387 return __sync_add_and_fetch(a, 1) == 0;
388 }
389
390 static inline int env_atomic_add_return(int i, env_atomic *a)
391 {
392 return __sync_add_and_fetch(a, i);
393 }
394
395 static inline int env_atomic_sub_return(int i, env_atomic *a)
396 {
397 return __sync_sub_and_fetch(a, i);
398 }
399
400 static inline int env_atomic_inc_return(env_atomic *a)
401 {
402 return env_atomic_add_return(1, a);
403 }
404
405 static inline int env_atomic_dec_return(env_atomic *a)
406 {
407 return env_atomic_sub_return(1, a);
408 }
409
410 static inline int env_atomic_cmpxchg(env_atomic *a, int old, int new_value)
411 {
412 return atomic_cmpxchg(a, old, new_value);
413 }
414
415 static inline int env_atomic_add_unless(env_atomic *a, int i, int u)
416 {
417 int c, old;
418 c = env_atomic_read(a);
419 for (;;) {
420 if (spdk_unlikely(c == (u))) {
421 break;
422 }
423 old = env_atomic_cmpxchg((a), c, c + (i));
424 if (spdk_likely(old == c)) {
425 break;
426 }
427 c = old;
428 }
429 return c != (u);
430 }
431
432 static inline long env_atomic64_read(const env_atomic64 *a)
433 {
434 return atomic_read(a);
435 }
436
437 static inline void env_atomic64_set(env_atomic64 *a, long i)
438 {
439 atomic_set(a, i);
440 }
441
442 static inline void env_atomic64_add(long i, env_atomic64 *a)
443 {
444 atomic_add(a, i);
445 }
446
447 static inline void env_atomic64_sub(long i, env_atomic64 *a)
448 {
449 atomic_sub(a, i);
450 }
451
452 static inline void env_atomic64_inc(env_atomic64 *a)
453 {
454 atomic_inc(a);
455 }
456
457 static inline void env_atomic64_dec(env_atomic64 *a)
458 {
459 atomic_dec(a);
460 }
461
462 static inline int env_atomic64_add_return(int i, env_atomic *a)
463 {
464 return __sync_add_and_fetch(a, i);
465 }
466
467 static inline int env_atomic64_sub_return(int i, env_atomic *a)
468 {
469 return __sync_sub_and_fetch(a, i);
470 }
471
472 static inline int env_atomic64_inc_return(env_atomic *a)
473 {
474 return env_atomic64_add_return(1, a);
475 }
476
477 static inline int env_atomic64_dec_return(env_atomic *a)
478 {
479 return env_atomic_sub_return(1, a);
480 }
481
482 static inline long env_atomic64_cmpxchg(env_atomic64 *a, long old, long new)
483 {
484 return atomic_cmpxchg(a, old, new);
485 }
486
487 /* *** COMPLETION *** */
488 struct completion {
489 env_atomic atom;
490 };
491
492 typedef struct completion env_completion;
493
494 void env_completion_init(env_completion *completion);
495 void env_completion_wait(env_completion *completion);
496 void env_completion_complete(env_completion *completion);
497
498 /* *** SPIN LOCKS *** */
499
500 typedef env_mutex env_spinlock;
501
502 static inline void env_spinlock_init(env_spinlock *l)
503 {
504 env_mutex_init(l);
505 }
506
507 static inline void env_spinlock_lock(env_spinlock *l)
508 {
509 env_mutex_lock(l);
510 }
511
512 static inline void env_spinlock_unlock(env_spinlock *l)
513 {
514 env_mutex_unlock(l);
515 }
516
517 static inline void env_spinlock_lock_irq(env_spinlock *l)
518 {
519 env_spinlock_lock(l);
520 }
521
522 static inline void env_spinlock_unlock_irq(env_spinlock *l)
523 {
524 env_spinlock_unlock(l);
525 }
526
527 static inline void env_spinlock_lock_irqsave(env_spinlock *l, int flags)
528 {
529 env_spinlock_lock(l);
530 (void)flags;
531 }
532
533 static inline void env_spinlock_unlock_irqrestore(env_spinlock *l, int flags)
534 {
535 env_spinlock_unlock(l);
536 (void)flags;
537 }
538
539 /* *** RW LOCKS *** */
540
541 typedef env_rwsem env_rwlock;
542
543 static inline void env_rwlock_init(env_rwlock *l)
544 {
545 env_rwsem_init(l);
546 }
547
548 static inline void env_rwlock_read_lock(env_rwlock *l)
549 {
550 env_rwsem_down_read(l);
551 }
552
553 static inline void env_rwlock_read_unlock(env_rwlock *l)
554 {
555 env_rwsem_up_read(l);
556 }
557
558 static inline void env_rwlock_write_lock(env_rwlock *l)
559 {
560 env_rwsem_down_write(l);
561 }
562
563 static inline void env_rwlock_write_unlock(env_rwlock *l)
564 {
565 env_rwsem_up_write(l);
566 }
567
568 static inline void env_bit_set(int nr, volatile void *addr)
569 {
570 char *byte = (char *)addr + (nr >> 3);
571 char mask = 1 << (nr & 7);
572
573 __sync_or_and_fetch(byte, mask);
574 }
575
576 static inline void env_bit_clear(int nr, volatile void *addr)
577 {
578 char *byte = (char *)addr + (nr >> 3);
579 char mask = 1 << (nr & 7);
580
581 mask = ~mask;
582 __sync_and_and_fetch(byte, mask);
583 }
584
585 static inline bool env_bit_test(int nr, const volatile unsigned long *addr)
586 {
587 const char *byte = (char *)addr + (nr >> 3);
588 char mask = 1 << (nr & 7);
589
590 return !!(*byte & mask);
591 }
592
593 /* *** WAITQUEUE *** */
594
595 typedef struct {
596 sem_t sem;
597 } env_waitqueue;
598
599 static inline void env_waitqueue_init(env_waitqueue *w)
600 {
601 sem_init(&w->sem, 0, 0);
602 }
603
604 static inline void env_waitqueue_wake_up(env_waitqueue *w)
605 {
606 sem_post(&w->sem);
607 }
608
609 #define env_waitqueue_wait(w, condition) \
610 ({ \
611 int __ret = 0; \
612 if (!(condition)) \
613 sem_wait(&w.sem); \
614 __ret = __ret; \
615 })
616
617 /* *** SCHEDULING *** */
618
619 /* CAS does not need this while in user-space */
620 static inline void env_schedule(void)
621 {
622 }
623
624 #define env_cond_resched env_schedule
625
626 static inline int env_in_interrupt(void)
627 {
628 return 0;
629 }
630
631 static inline uint64_t env_get_tick_count(void)
632 {
633 return spdk_get_ticks();
634 }
635
636 static inline uint64_t env_ticks_to_secs(uint64_t j)
637 {
638 return j / spdk_get_ticks_hz();
639 }
640
641 static inline uint64_t env_ticks_to_msecs(uint64_t j)
642 {
643 return env_ticks_to_secs(j) * 1000;
644 }
645
646 static inline uint64_t env_ticks_to_nsecs(uint64_t j)
647 {
648 return env_ticks_to_secs(j) * 1000 * 1000;
649 }
650
651 static inline uint64_t env_ticks_to_usecs(uint64_t j)
652 {
653 return env_ticks_to_secs(j) * 1000 * 1000 * 1000;
654 }
655
656 static inline uint64_t env_secs_to_ticks(uint64_t j)
657 {
658 return j * spdk_get_ticks_hz();
659 }
660
661 /* *** STRING OPERATIONS *** */
662
663 /* 256 KB is sufficient amount of memory for OCF operations */
664 #define ENV_MAX_MEM (256 * 1024)
665
666 static inline int env_memset(void *dest, size_t len, uint8_t value)
667 {
668 if (dest == NULL || len == 0) {
669 return 1;
670 }
671
672 memset(dest, value, len);
673 return 0;
674 }
675
676 static inline int env_memcpy(void *dest, size_t dmax, const void *src, size_t len)
677 {
678 if (dest == NULL || src == NULL) {
679 return 1;
680 }
681 if (dmax == 0 || dmax > ENV_MAX_MEM) {
682 return 1;
683 }
684 if (len == 0 || len > dmax) {
685 return 1;
686 }
687
688 memcpy(dest, src, len);
689 return 0;
690 }
691
692 static inline int env_memcmp(const void *aptr, size_t dmax, const void *bptr, size_t len,
693 int *diff)
694 {
695 if (diff == NULL || aptr == NULL || bptr == NULL) {
696 return 1;
697 }
698 if (dmax == 0 || dmax > ENV_MAX_MEM) {
699 return 1;
700 }
701 if (len == 0 || len > dmax) {
702 return 1;
703 }
704
705 *diff = memcmp(aptr, bptr, len);
706 return 0;
707 }
708
709 /* 4096 is sufficient max length for any OCF operation on string */
710 #define ENV_MAX_STR (4 * 1024)
711
712 static inline size_t env_strnlen(const char *src, size_t dmax)
713 {
714 return strnlen(src, dmax);
715 }
716
717 static inline int env_strncpy(char *dest, size_t dmax, const char *src, size_t len)
718 {
719 if (dest == NULL || src == NULL) {
720 return 1;
721 }
722 if (dmax == 0 || dmax > ENV_MAX_STR) {
723 return 1;
724 }
725 if (len == 0 || len > dmax) {
726 return 1;
727 }
728
729 strncpy(dest, src, len);
730 return 0;
731 }
732
733 #define env_strncmp strncmp
734
735 static inline char *env_strdup(const char *src, int flags)
736 {
737 int len;
738 char *ret;
739
740 if (src == NULL) {
741 return NULL;
742 }
743
744 len = env_strnlen(src, ENV_MAX_STR) + 1;
745 ret = env_malloc(len, flags);
746
747 if (env_strncpy(ret, ENV_MAX_STR, src, len)) {
748 return NULL;
749 } else {
750 return ret;
751 }
752 }
753
754 /* *** SORTING *** */
755
756 static inline void env_sort(void *base, size_t num, size_t size,
757 int (*cmp_fn)(const void *, const void *),
758 void (*swap_fn)(void *, void *, int size))
759 {
760 qsort(base, num, size, cmp_fn);
761 }
762
763 static inline void env_msleep(uint64_t n)
764 {
765 usleep(n * 1000);
766 }
767
768 static inline void env_touch_softlockup_wd(void)
769 {
770 }
771
772 /* *** CRC *** */
773
774 uint32_t env_crc32(uint32_t crc, uint8_t const *data, size_t len);
775
776 #endif /* __OCF_ENV_H__ */