Merge remote-tracking branch 'staging/staging-next'
[deliverable/linux.git] / drivers / staging / lustre / include / linux / libcfs / libcfs_private.h
CommitLineData
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, ...) \
53do { \
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 78void __noreturn lbug_with_loc(struct libcfs_debug_msg_data *);
d7e09d03
PT
79
80#define LBUG() \
81do { \
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) \
91do { \
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) \
98do { \
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) \
111do { \
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) \
136do { \
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) \
149do { \
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
172void libcfs_run_upcall(char **argv);
173void libcfs_run_lbug_upcall(struct libcfs_debug_msg_data *);
174void libcfs_debug_dumplog(void);
175int libcfs_debug_init(unsigned long bufsize);
176int libcfs_debug_cleanup(void);
177int libcfs_debug_clear_buffer(void);
178int 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 */
184void *cfs_array_alloc(int count, unsigned int size);
185void 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) \
193do { \
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) \
200do { \
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) \
207do { \
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) \
214do { \
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) \
221do { \
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) \
228do { \
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) \
235do { \
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) \
242do { \
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) \
249do { \
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) \
256do { \
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 313static inline int cfs_size_round4(int val)
d7e09d03
PT
314{
315 return (val + 3) & (~0x3);
316}
317
318#ifndef HAVE_CFS_SIZE_ROUND
a393fd54 319static 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
327static inline int cfs_size_round16(int val)
328{
329 return (val + 0xf) & (~0xf);
330}
331
332static inline int cfs_size_round32(int val)
333{
334 return (val + 0x1f) & (~0x1f);
335}
336
337static inline int cfs_size_round0(int val)
338{
339 if (!val)
340 return 0;
341 return (val + 1 + 7) & (~0x7);
342}
343
344static 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
350do { \
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
357do { \
358 if (var) \
359 memcpy((char *)var, (const char *)ptr, len); \
360 ptr += cfs_size_round(len); \
361} while (0)
362
d7e09d03 363#endif
This page took 0.512687 seconds and 5 git commands to generate.