4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2011, 2012, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * libcfs/include/libcfs/libcfs_private.h
34 * Various defines for libcfs.
38 #ifndef __LIBCFS_PRIVATE_H__
39 #define __LIBCFS_PRIVATE_H__
41 #ifndef DEBUG_SUBSYSTEM
42 # define DEBUG_SUBSYSTEM S_UNDEFINED
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.
50 #define LASSERT_CHECKED (0)
52 #define LASSERTF(cond, fmt, ...) \
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, \
59 lbug_with_loc(&__msg_data); \
63 #define LASSERT(cond) LASSERTF(cond, "\n")
65 #ifdef CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK
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.
71 # define LINVRNT(exp) LASSERT(exp)
73 # define LINVRNT(exp) ((void)sizeof !!(exp))
76 #define KLASSERT(e) LASSERT(e)
78 void __noreturn lbug_with_loc(struct libcfs_debug_msg_data *msg);
82 LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_EMERG, NULL); \
83 lbug_with_loc(&msgdata); \
86 #ifndef LIBCFS_VMALLOC_SIZE
87 #define LIBCFS_VMALLOC_SIZE (2 << PAGE_SHIFT) /* 2 pages */
90 #define LIBCFS_ALLOC_PRE(size, mask) \
91 LASSERT(!in_interrupt() || ((size) <= LIBCFS_VMALLOC_SIZE && \
92 !gfpflags_allow_blocking(mask)))
94 #define LIBCFS_ALLOC_POST(ptr, size) \
96 if (unlikely(!(ptr))) { \
97 CERROR("LNET: out of memory at %s:%d (tried to alloc '" \
98 #ptr "' = %d)\n", __FILE__, __LINE__, (int)(size)); \
100 memset((ptr), 0, (size)); \
105 * allocate memory with GFP flags @mask
107 #define LIBCFS_ALLOC_GFP(ptr, size, mask) \
109 LIBCFS_ALLOC_PRE((size), (mask)); \
110 (ptr) = (size) <= LIBCFS_VMALLOC_SIZE ? \
111 kmalloc((size), (mask)) : vmalloc(size); \
112 LIBCFS_ALLOC_POST((ptr), (size)); \
118 #define LIBCFS_ALLOC(ptr, size) \
119 LIBCFS_ALLOC_GFP(ptr, size, GFP_NOFS)
122 * non-sleeping allocator
124 #define LIBCFS_ALLOC_ATOMIC(ptr, size) \
125 LIBCFS_ALLOC_GFP(ptr, size, GFP_ATOMIC)
128 * allocate memory for specified CPU partition
129 * \a cptab != NULL, \a cpt is CPU partition id of \a cptab
130 * \a cptab == NULL, \a cpt is HW NUMA node id
132 #define LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, mask) \
134 LIBCFS_ALLOC_PRE((size), (mask)); \
135 (ptr) = (size) <= LIBCFS_VMALLOC_SIZE ? \
136 kmalloc_node((size), (mask), cfs_cpt_spread_node(cptab, cpt)) :\
137 vmalloc_node(size, cfs_cpt_spread_node(cptab, cpt)); \
138 LIBCFS_ALLOC_POST((ptr), (size)); \
141 /** default numa allocator */
142 #define LIBCFS_CPT_ALLOC(ptr, cptab, cpt, size) \
143 LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, GFP_NOFS)
145 #define LIBCFS_FREE(ptr, size) \
147 if (unlikely(!(ptr))) { \
148 CERROR("LIBCFS: free NULL '" #ptr "' (%d bytes) at " \
149 "%s:%d\n", (int)(size), __FILE__, __LINE__); \
155 /******************************************************************************/
157 void libcfs_debug_dumplog(void);
158 int libcfs_debug_init(unsigned long bufsize);
159 int libcfs_debug_cleanup(void);
160 int libcfs_debug_clear_buffer(void);
161 int libcfs_debug_mark_buffer(const char *text);
164 * allocate a variable array, returned value is an array of pointers.
165 * Caller can specify length of array by count.
167 void *cfs_array_alloc(int count, unsigned int size);
168 void cfs_array_free(void *vars);
170 #define LASSERT_ATOMIC_ENABLED (1)
172 #if LASSERT_ATOMIC_ENABLED
174 /** assert value of @a is equal to @v */
175 #define LASSERT_ATOMIC_EQ(a, v) \
176 LASSERTF(atomic_read(a) == v, "value: %d\n", atomic_read((a)))
178 /** assert value of @a is unequal to @v */
179 #define LASSERT_ATOMIC_NE(a, v) \
180 LASSERTF(atomic_read(a) != v, "value: %d\n", atomic_read((a)))
182 /** assert value of @a is little than @v */
183 #define LASSERT_ATOMIC_LT(a, v) \
184 LASSERTF(atomic_read(a) < v, "value: %d\n", atomic_read((a)))
186 /** assert value of @a is little/equal to @v */
187 #define LASSERT_ATOMIC_LE(a, v) \
188 LASSERTF(atomic_read(a) <= v, "value: %d\n", atomic_read((a)))
190 /** assert value of @a is great than @v */
191 #define LASSERT_ATOMIC_GT(a, v) \
192 LASSERTF(atomic_read(a) > v, "value: %d\n", atomic_read((a)))
194 /** assert value of @a is great/equal to @v */
195 #define LASSERT_ATOMIC_GE(a, v) \
196 LASSERTF(atomic_read(a) >= v, "value: %d\n", atomic_read((a)))
198 /** assert value of @a is great than @v1 and little than @v2 */
199 #define LASSERT_ATOMIC_GT_LT(a, v1, v2) \
201 int __v = atomic_read(a); \
202 LASSERTF(__v > v1 && __v < v2, "value: %d\n", __v); \
205 /** assert value of @a is great than @v1 and little/equal to @v2 */
206 #define LASSERT_ATOMIC_GT_LE(a, v1, v2) \
208 int __v = atomic_read(a); \
209 LASSERTF(__v > v1 && __v <= v2, "value: %d\n", __v); \
212 /** assert value of @a is great/equal to @v1 and little than @v2 */
213 #define LASSERT_ATOMIC_GE_LT(a, v1, v2) \
215 int __v = atomic_read(a); \
216 LASSERTF(__v >= v1 && __v < v2, "value: %d\n", __v); \
219 /** assert value of @a is great/equal to @v1 and little/equal to @v2 */
220 #define LASSERT_ATOMIC_GE_LE(a, v1, v2) \
222 int __v = atomic_read(a); \
223 LASSERTF(__v >= v1 && __v <= v2, "value: %d\n", __v); \
226 #else /* !LASSERT_ATOMIC_ENABLED */
228 #define LASSERT_ATOMIC_EQ(a, v) do {} while (0)
229 #define LASSERT_ATOMIC_NE(a, v) do {} while (0)
230 #define LASSERT_ATOMIC_LT(a, v) do {} while (0)
231 #define LASSERT_ATOMIC_LE(a, v) do {} while (0)
232 #define LASSERT_ATOMIC_GT(a, v) do {} while (0)
233 #define LASSERT_ATOMIC_GE(a, v) do {} while (0)
234 #define LASSERT_ATOMIC_GT_LT(a, v1, v2) do {} while (0)
235 #define LASSERT_ATOMIC_GT_LE(a, v1, v2) do {} while (0)
236 #define LASSERT_ATOMIC_GE_LT(a, v1, v2) do {} while (0)
237 #define LASSERT_ATOMIC_GE_LE(a, v1, v2) do {} while (0)
239 #endif /* LASSERT_ATOMIC_ENABLED */
241 #define LASSERT_ATOMIC_ZERO(a) LASSERT_ATOMIC_EQ(a, 0)
242 #define LASSERT_ATOMIC_POS(a) LASSERT_ATOMIC_GT(a, 0)
244 #define CFS_ALLOC_PTR(ptr) LIBCFS_ALLOC(ptr, sizeof(*(ptr)))
245 #define CFS_FREE_PTR(ptr) LIBCFS_FREE(ptr, sizeof(*(ptr)))
247 /* max value for numeric network address */
248 #define MAX_NUMERIC_VALUE 0xffffffff
251 #define ergo(a, b) (!(a) || (b))
252 /* logical equivalence */
253 #define equi(a, b) (!!(a) == !!(b))
255 /* --------------------------------------------------------------------
257 * Support for temporary event tracing with minimal Heisenberg effect.
258 * --------------------------------------------------------------------
261 #define MKSTR(ptr) ((ptr)) ? (ptr) : ""
263 static inline size_t cfs_size_round4(int val)
265 return (val + 3) & (~0x3);
268 #ifndef HAVE_CFS_SIZE_ROUND
269 static inline size_t cfs_size_round(int val)
271 return (val + 7) & (~0x7);
274 #define HAVE_CFS_SIZE_ROUND
277 static inline size_t cfs_size_round16(int val)
279 return (val + 0xf) & (~0xf);
282 static inline size_t cfs_size_round32(int val)
284 return (val + 0x1f) & (~0x1f);
287 static inline size_t cfs_size_round0(int val)
291 return (val + 1 + 7) & (~0x7);
294 static inline size_t cfs_round_strlen(char *fset)
296 return cfs_size_round((int)strlen(fset) + 1);