Commit | Line | Data |
---|---|---|
d7e09d03 PT |
1 | /* |
2 | * GPL HEADER START | |
3 | * | |
4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 only, | |
8 | * as published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but | |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | * General Public License version 2 for more details (a copy is included | |
14 | * in the LICENSE file that accompanied this code). | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * version 2 along with this program; If not, see | |
6a5b99a4 | 18 | * http://www.gnu.org/licenses/gpl-2.0.html |
d7e09d03 | 19 | * |
d7e09d03 PT |
20 | * GPL HEADER END |
21 | */ | |
22 | /* | |
23 | * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. | |
24 | * Use is subject to license terms. | |
25 | * | |
26 | * Copyright (c) 2011, 2012, Intel Corporation. | |
27 | */ | |
28 | /* | |
29 | * This file is part of Lustre, http://www.lustre.org/ | |
30 | * Lustre is a trademark of Sun Microsystems, Inc. | |
31 | * | |
32 | * libcfs/include/libcfs/libcfs_private.h | |
33 | * | |
34 | * Various defines for libcfs. | |
35 | * | |
36 | */ | |
37 | ||
38 | #ifndef __LIBCFS_PRIVATE_H__ | |
39 | #define __LIBCFS_PRIVATE_H__ | |
40 | ||
d7e09d03 PT |
41 | #ifndef DEBUG_SUBSYSTEM |
42 | # define DEBUG_SUBSYSTEM S_UNDEFINED | |
43 | #endif | |
44 | ||
d7e09d03 PT |
45 | /* |
46 | * When this is on, LASSERT macro includes check for assignment used instead | |
47 | * of equality check, but doesn't have unlikely(). Turn this on from time to | |
48 | * time to make test-builds. This shouldn't be on for production release. | |
49 | */ | |
50 | #define LASSERT_CHECKED (0) | |
51 | ||
d7e09d03 PT |
52 | #define LASSERTF(cond, fmt, ...) \ |
53 | do { \ | |
54 | if (unlikely(!(cond))) { \ | |
55 | LIBCFS_DEBUG_MSG_DATA_DECL(__msg_data, D_EMERG, NULL); \ | |
56 | libcfs_debug_msg(&__msg_data, \ | |
57 | "ASSERTION( %s ) failed: " fmt, #cond, \ | |
58 | ## __VA_ARGS__); \ | |
59 | lbug_with_loc(&__msg_data); \ | |
60 | } \ | |
61 | } while (0) | |
62 | ||
63 | #define LASSERT(cond) LASSERTF(cond, "\n") | |
64 | ||
4b5b4c72 PT |
65 | #ifdef CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK |
66 | /** | |
67 | * This is for more expensive checks that one doesn't want to be enabled all | |
68 | * the time. LINVRNT() has to be explicitly enabled by | |
69 | * CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK option. | |
70 | */ | |
71 | # define LINVRNT(exp) LASSERT(exp) | |
72 | #else | |
a393fd54 | 73 | # define LINVRNT(exp) ((void)sizeof !!(exp)) |
4b5b4c72 | 74 | #endif |
d7e09d03 PT |
75 | |
76 | #define KLASSERT(e) LASSERT(e) | |
77 | ||
2877f245 | 78 | void __noreturn lbug_with_loc(struct libcfs_debug_msg_data *); |
d7e09d03 PT |
79 | |
80 | #define LBUG() \ | |
81 | do { \ | |
82 | LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_EMERG, NULL); \ | |
83 | lbug_with_loc(&msgdata); \ | |
a393fd54 | 84 | } while (0) |
d7e09d03 | 85 | |
d7e09d03 | 86 | #ifndef LIBCFS_VMALLOC_SIZE |
09cbfeaf | 87 | #define LIBCFS_VMALLOC_SIZE (2 << PAGE_SHIFT) /* 2 pages */ |
d7e09d03 PT |
88 | #endif |
89 | ||
90 | #define LIBCFS_ALLOC_PRE(size, mask) \ | |
91 | do { \ | |
92 | LASSERT(!in_interrupt() || \ | |
93 | ((size) <= LIBCFS_VMALLOC_SIZE && \ | |
d0164adc | 94 | !gfpflags_allow_blocking(mask))); \ |
d7e09d03 PT |
95 | } while (0) |
96 | ||
97 | #define LIBCFS_ALLOC_POST(ptr, size) \ | |
98 | do { \ | |
99 | if (unlikely((ptr) == NULL)) { \ | |
100 | CERROR("LNET: out of memory at %s:%d (tried to alloc '" \ | |
101 | #ptr "' = %d)\n", __FILE__, __LINE__, (int)(size)); \ | |
d7e09d03 PT |
102 | } else { \ |
103 | memset((ptr), 0, (size)); \ | |
323b0b2c | 104 | } \ |
d7e09d03 PT |
105 | } while (0) |
106 | ||
107 | /** | |
108 | * allocate memory with GFP flags @mask | |
109 | */ | |
110 | #define LIBCFS_ALLOC_GFP(ptr, size, mask) \ | |
111 | do { \ | |
112 | LIBCFS_ALLOC_PRE((size), (mask)); \ | |
113 | (ptr) = (size) <= LIBCFS_VMALLOC_SIZE ? \ | |
114 | kmalloc((size), (mask)) : vmalloc(size); \ | |
115 | LIBCFS_ALLOC_POST((ptr), (size)); \ | |
116 | } while (0) | |
117 | ||
118 | /** | |
119 | * default allocator | |
120 | */ | |
121 | #define LIBCFS_ALLOC(ptr, size) \ | |
0be19afa | 122 | LIBCFS_ALLOC_GFP(ptr, size, GFP_NOFS) |
d7e09d03 PT |
123 | |
124 | /** | |
125 | * non-sleeping allocator | |
126 | */ | |
127 | #define LIBCFS_ALLOC_ATOMIC(ptr, size) \ | |
128 | LIBCFS_ALLOC_GFP(ptr, size, GFP_ATOMIC) | |
129 | ||
130 | /** | |
131 | * allocate memory for specified CPU partition | |
132 | * \a cptab != NULL, \a cpt is CPU partition id of \a cptab | |
133 | * \a cptab == NULL, \a cpt is HW NUMA node id | |
134 | */ | |
135 | #define LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, mask) \ | |
136 | do { \ | |
137 | LIBCFS_ALLOC_PRE((size), (mask)); \ | |
138 | (ptr) = (size) <= LIBCFS_VMALLOC_SIZE ? \ | |
49c02a75 PT |
139 | kmalloc_node((size), (mask), cfs_cpt_spread_node(cptab, cpt)) :\ |
140 | vmalloc_node(size, cfs_cpt_spread_node(cptab, cpt)); \ | |
d7e09d03 PT |
141 | LIBCFS_ALLOC_POST((ptr), (size)); \ |
142 | } while (0) | |
143 | ||
144 | /** default numa allocator */ | |
145 | #define LIBCFS_CPT_ALLOC(ptr, cptab, cpt, size) \ | |
0be19afa | 146 | LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, GFP_NOFS) |
d7e09d03 PT |
147 | |
148 | #define LIBCFS_FREE(ptr, size) \ | |
149 | do { \ | |
d7e09d03 PT |
150 | if (unlikely((ptr) == NULL)) { \ |
151 | CERROR("LIBCFS: free NULL '" #ptr "' (%d bytes) at " \ | |
1d5cfdb0 | 152 | "%s:%d\n", (int)(size), __FILE__, __LINE__); \ |
d7e09d03 PT |
153 | break; \ |
154 | } \ | |
1d5cfdb0 | 155 | kvfree(ptr); \ |
d7e09d03 PT |
156 | } while (0) |
157 | ||
158 | /******************************************************************************/ | |
159 | ||
160 | /* htonl hack - either this, or compile with -O2. Stupid byteorder/generic.h */ | |
161 | #if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__) | |
162 | #define ___htonl(x) __cpu_to_be32(x) | |
163 | #define ___htons(x) __cpu_to_be16(x) | |
164 | #define ___ntohl(x) __be32_to_cpu(x) | |
165 | #define ___ntohs(x) __be16_to_cpu(x) | |
166 | #define htonl(x) ___htonl(x) | |
167 | #define ntohl(x) ___ntohl(x) | |
168 | #define htons(x) ___htons(x) | |
169 | #define ntohs(x) ___ntohs(x) | |
170 | #endif | |
171 | ||
d7e09d03 PT |
172 | void libcfs_run_upcall(char **argv); |
173 | void libcfs_run_lbug_upcall(struct libcfs_debug_msg_data *); | |
174 | void libcfs_debug_dumplog(void); | |
175 | int libcfs_debug_init(unsigned long bufsize); | |
176 | int libcfs_debug_cleanup(void); | |
177 | int libcfs_debug_clear_buffer(void); | |
178 | int libcfs_debug_mark_buffer(const char *text); | |
179 | ||
d7e09d03 PT |
180 | /* |
181 | * allocate a variable array, returned value is an array of pointers. | |
182 | * Caller can specify length of array by count. | |
183 | */ | |
184 | void *cfs_array_alloc(int count, unsigned int size); | |
185 | void cfs_array_free(void *vars); | |
186 | ||
187 | #define LASSERT_ATOMIC_ENABLED (1) | |
188 | ||
189 | #if LASSERT_ATOMIC_ENABLED | |
190 | ||
191 | /** assert value of @a is equal to @v */ | |
192 | #define LASSERT_ATOMIC_EQ(a, v) \ | |
193 | do { \ | |
194 | LASSERTF(atomic_read(a) == v, \ | |
195 | "value: %d\n", atomic_read((a))); \ | |
196 | } while (0) | |
197 | ||
198 | /** assert value of @a is unequal to @v */ | |
199 | #define LASSERT_ATOMIC_NE(a, v) \ | |
200 | do { \ | |
201 | LASSERTF(atomic_read(a) != v, \ | |
202 | "value: %d\n", atomic_read((a))); \ | |
203 | } while (0) | |
204 | ||
205 | /** assert value of @a is little than @v */ | |
206 | #define LASSERT_ATOMIC_LT(a, v) \ | |
207 | do { \ | |
208 | LASSERTF(atomic_read(a) < v, \ | |
209 | "value: %d\n", atomic_read((a))); \ | |
210 | } while (0) | |
211 | ||
212 | /** assert value of @a is little/equal to @v */ | |
213 | #define LASSERT_ATOMIC_LE(a, v) \ | |
214 | do { \ | |
215 | LASSERTF(atomic_read(a) <= v, \ | |
216 | "value: %d\n", atomic_read((a))); \ | |
217 | } while (0) | |
218 | ||
219 | /** assert value of @a is great than @v */ | |
220 | #define LASSERT_ATOMIC_GT(a, v) \ | |
221 | do { \ | |
222 | LASSERTF(atomic_read(a) > v, \ | |
223 | "value: %d\n", atomic_read((a))); \ | |
224 | } while (0) | |
225 | ||
226 | /** assert value of @a is great/equal to @v */ | |
227 | #define LASSERT_ATOMIC_GE(a, v) \ | |
228 | do { \ | |
229 | LASSERTF(atomic_read(a) >= v, \ | |
230 | "value: %d\n", atomic_read((a))); \ | |
231 | } while (0) | |
232 | ||
233 | /** assert value of @a is great than @v1 and little than @v2 */ | |
234 | #define LASSERT_ATOMIC_GT_LT(a, v1, v2) \ | |
235 | do { \ | |
236 | int __v = atomic_read(a); \ | |
237 | LASSERTF(__v > v1 && __v < v2, "value: %d\n", __v); \ | |
238 | } while (0) | |
239 | ||
240 | /** assert value of @a is great than @v1 and little/equal to @v2 */ | |
241 | #define LASSERT_ATOMIC_GT_LE(a, v1, v2) \ | |
242 | do { \ | |
243 | int __v = atomic_read(a); \ | |
244 | LASSERTF(__v > v1 && __v <= v2, "value: %d\n", __v); \ | |
245 | } while (0) | |
246 | ||
247 | /** assert value of @a is great/equal to @v1 and little than @v2 */ | |
248 | #define LASSERT_ATOMIC_GE_LT(a, v1, v2) \ | |
249 | do { \ | |
250 | int __v = atomic_read(a); \ | |
251 | LASSERTF(__v >= v1 && __v < v2, "value: %d\n", __v); \ | |
252 | } while (0) | |
253 | ||
254 | /** assert value of @a is great/equal to @v1 and little/equal to @v2 */ | |
255 | #define LASSERT_ATOMIC_GE_LE(a, v1, v2) \ | |
256 | do { \ | |
257 | int __v = atomic_read(a); \ | |
258 | LASSERTF(__v >= v1 && __v <= v2, "value: %d\n", __v); \ | |
259 | } while (0) | |
260 | ||
261 | #else /* !LASSERT_ATOMIC_ENABLED */ | |
262 | ||
263 | #define LASSERT_ATOMIC_EQ(a, v) do {} while (0) | |
264 | #define LASSERT_ATOMIC_NE(a, v) do {} while (0) | |
265 | #define LASSERT_ATOMIC_LT(a, v) do {} while (0) | |
266 | #define LASSERT_ATOMIC_LE(a, v) do {} while (0) | |
267 | #define LASSERT_ATOMIC_GT(a, v) do {} while (0) | |
268 | #define LASSERT_ATOMIC_GE(a, v) do {} while (0) | |
269 | #define LASSERT_ATOMIC_GT_LT(a, v1, v2) do {} while (0) | |
270 | #define LASSERT_ATOMIC_GT_LE(a, v1, v2) do {} while (0) | |
271 | #define LASSERT_ATOMIC_GE_LT(a, v1, v2) do {} while (0) | |
272 | #define LASSERT_ATOMIC_GE_LE(a, v1, v2) do {} while (0) | |
273 | ||
274 | #endif /* LASSERT_ATOMIC_ENABLED */ | |
275 | ||
276 | #define LASSERT_ATOMIC_ZERO(a) LASSERT_ATOMIC_EQ(a, 0) | |
277 | #define LASSERT_ATOMIC_POS(a) LASSERT_ATOMIC_GT(a, 0) | |
278 | ||
06133e80 MR |
279 | #define CFS_ALLOC_PTR(ptr) LIBCFS_ALLOC(ptr, sizeof(*(ptr))) |
280 | #define CFS_FREE_PTR(ptr) LIBCFS_FREE(ptr, sizeof(*(ptr))) | |
d7e09d03 | 281 | |
d7e09d03 PT |
282 | /** Compile-time assertion. |
283 | ||
284 | * Check an invariant described by a constant expression at compile time by | |
285 | * forcing a compiler error if it does not hold. \a cond must be a constant | |
286 | * expression as defined by the ISO C Standard: | |
287 | * | |
288 | * 6.8.4.2 The switch statement | |
289 | * .... | |
290 | * [#3] The expression of each case label shall be an integer | |
291 | * constant expression and no two of the case constant | |
292 | * expressions in the same switch statement shall have the same | |
293 | * value after conversion... | |
294 | * | |
295 | */ | |
a393fd54 | 296 | #define CLASSERT(cond) do {switch (42) {case (cond): case 0: break; } } while (0) |
d7e09d03 | 297 | |
d7e09d03 PT |
298 | /* max value for numeric network address */ |
299 | #define MAX_NUMERIC_VALUE 0xffffffff | |
300 | ||
301 | /* implication */ | |
302 | #define ergo(a, b) (!(a) || (b)) | |
303 | /* logical equivalence */ | |
304 | #define equi(a, b) (!!(a) == !!(b)) | |
305 | ||
d7e09d03 PT |
306 | /* -------------------------------------------------------------------- |
307 | * Light-weight trace | |
308 | * Support for temporary event tracing with minimal Heisenberg effect. | |
d7e09d03 PT |
309 | * -------------------------------------------------------------------- */ |
310 | ||
a393fd54 | 311 | #define MKSTR(ptr) ((ptr)) ? (ptr) : "" |
d7e09d03 | 312 | |
a393fd54 | 313 | static inline int cfs_size_round4(int val) |
d7e09d03 PT |
314 | { |
315 | return (val + 3) & (~0x3); | |
316 | } | |
317 | ||
318 | #ifndef HAVE_CFS_SIZE_ROUND | |
a393fd54 | 319 | static inline int cfs_size_round(int val) |
d7e09d03 PT |
320 | { |
321 | return (val + 7) & (~0x7); | |
322 | } | |
a393fd54 | 323 | |
d7e09d03 PT |
324 | #define HAVE_CFS_SIZE_ROUND |
325 | #endif | |
326 | ||
327 | static inline int cfs_size_round16(int val) | |
328 | { | |
329 | return (val + 0xf) & (~0xf); | |
330 | } | |
331 | ||
332 | static inline int cfs_size_round32(int val) | |
333 | { | |
334 | return (val + 0x1f) & (~0x1f); | |
335 | } | |
336 | ||
337 | static inline int cfs_size_round0(int val) | |
338 | { | |
339 | if (!val) | |
340 | return 0; | |
341 | return (val + 1 + 7) & (~0x7); | |
342 | } | |
343 | ||
344 | static inline size_t cfs_round_strlen(char *fset) | |
345 | { | |
346 | return (size_t)cfs_size_round((int)strlen(fset) + 1); | |
347 | } | |
348 | ||
a393fd54 | 349 | #define LOGL(var, len, ptr) \ |
d7e09d03 PT |
350 | do { \ |
351 | if (var) \ | |
352 | memcpy((char *)ptr, (const char *)var, len); \ | |
353 | ptr += cfs_size_round(len); \ | |
354 | } while (0) | |
355 | ||
a393fd54 | 356 | #define LOGU(var, len, ptr) \ |
d7e09d03 PT |
357 | do { \ |
358 | if (var) \ | |
359 | memcpy((char *)var, (const char *)ptr, len); \ | |
360 | ptr += cfs_size_round(len); \ | |
361 | } while (0) | |
362 | ||
d7e09d03 | 363 | #endif |