1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef KUBLK_UTILS_H
#define KUBLK_UTILS_H
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
#endif
#ifndef container_of
#define container_of(ptr, type, member) ({ \
unsigned long __mptr = (unsigned long)(ptr); \
((type *)(__mptr - offsetof(type, member))); })
#endif
#define round_up(val, rnd) \
(((val) + ((rnd) - 1)) & ~((rnd) - 1))
/* small sized & per-thread allocator */
struct allocator {
unsigned int size;
cpu_set_t *set;
};
static inline int allocator_init(struct allocator *a, unsigned size)
{
a->set = CPU_ALLOC(size);
a->size = size;
if (a->set)
return 0;
return -ENOMEM;
}
static inline void allocator_deinit(struct allocator *a)
{
CPU_FREE(a->set);
a->set = NULL;
a->size = 0;
}
static inline int allocator_get(struct allocator *a)
{
int i;
for (i = 0; i < a->size; i += 1) {
size_t set_size = CPU_ALLOC_SIZE(a->size);
if (!CPU_ISSET_S(i, set_size, a->set)) {
CPU_SET_S(i, set_size, a->set);
return i;
}
}
return -1;
}
static inline void allocator_put(struct allocator *a, int i)
{
size_t set_size = CPU_ALLOC_SIZE(a->size);
if (i >= 0 && i < a->size)
CPU_CLR_S(i, set_size, a->set);
}
static inline int allocator_get_val(struct allocator *a, int i)
{
size_t set_size = CPU_ALLOC_SIZE(a->size);
return CPU_ISSET_S(i, set_size, a->set);
}
static inline unsigned int ilog2(unsigned int x)
{
if (x == 0)
return 0;
return (sizeof(x) * 8 - 1) - __builtin_clz(x);
}
#define UBLK_DBG_DEV (1U << 0)
#define UBLK_DBG_THREAD (1U << 1)
#define UBLK_DBG_IO_CMD (1U << 2)
#define UBLK_DBG_IO (1U << 3)
#define UBLK_DBG_CTRL_CMD (1U << 4)
#define UBLK_LOG (1U << 5)
extern unsigned int ublk_dbg_mask;
static inline void ublk_err(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
static inline void ublk_log(const char *fmt, ...)
{
if (ublk_dbg_mask & UBLK_LOG) {
va_list ap;
va_start(ap, fmt);
vfprintf(stdout, fmt, ap);
va_end(ap);
}
}
static inline void ublk_dbg(int level, const char *fmt, ...)
{
if (level & ublk_dbg_mask) {
va_list ap;
va_start(ap, fmt);
vfprintf(stdout, fmt, ap);
va_end(ap);
}
}
#define ublk_assert(x) do { \
if (!(x)) { \
ublk_err("%s %d: assert!\n", __func__, __LINE__); \
assert(x); \
} \
} while (0)
#endif
|