Whamcloud - gitweb
LU-12564 libcfs: Use vfree_atomic instead of vfree
[fs/lustre-release.git] / libcfs / include / libcfs / libcfs_private.h
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
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
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, 2014, 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
41 #ifndef DEBUG_SUBSYSTEM
42 # define DEBUG_SUBSYSTEM S_UNDEFINED
43 #endif
44
45 #include <linux/slab.h>
46 #include <linux/vmalloc.h>
47
48 #ifdef LIBCFS_DEBUG
49
50 /*
51  * When this is on, LASSERT macro includes check for assignment used instead
52  * of equality check, but doesn't have unlikely(). Turn this on from time to
53  * time to make test-builds. This shouldn't be on for production release.
54  */
55 #define LASSERT_CHECKED (0)
56
57 #if LASSERT_CHECKED
58 /*
59  * Assertion.
60  *
61  * Strange construction with empty "then" clause is used to trigger compiler
62  * warnings on the assertions of the form LASSERT(a = b);
63  *
64  * "warning: suggest parentheses around assignment used as truth value"
65  *
66  * requires -Wall. Unfortunately this rules out use of likely/unlikely.
67  */
68 #define LASSERTF(cond, fmt, ...)                                        \
69 do {                                                                    \
70         if (cond)                                                       \
71                 ;                                                       \
72         else {                                                          \
73                 LIBCFS_DEBUG_MSG_DATA_DECL(__msg_data, D_EMERG, NULL);  \
74                 libcfs_debug_msg(&__msg_data,                           \
75                                  "ASSERTION( %s ) failed: " fmt, #cond, \
76                                  ## __VA_ARGS__);                       \
77                 lbug_with_loc(&__msg_data);                             \
78         }                                                               \
79 } while (0)
80
81 #define LASSERT(cond) LASSERTF(cond, "\n")
82
83 #else /* !LASSERT_CHECKED */
84
85 #define LASSERTF(cond, fmt, ...)                                        \
86 do {                                                                    \
87         if (unlikely(!(cond))) {                                        \
88                 LIBCFS_DEBUG_MSG_DATA_DECL(__msg_data, D_EMERG, NULL);  \
89                 libcfs_debug_msg(&__msg_data,                           \
90                                  "ASSERTION( %s ) failed: " fmt, #cond, \
91                                  ## __VA_ARGS__);                       \
92                 lbug_with_loc(&__msg_data);                             \
93         }                                                               \
94 } while (0)
95
96 #define LASSERT(cond) LASSERTF(cond, "\n")
97 #endif /* !LASSERT_CHECKED */
98 #else /* !LIBCFS_DEBUG */
99 /* sizeof is to use expression without evaluating it. */
100 # define LASSERT(e) ((void)sizeof!!(e))
101 # define LASSERTF(cond, ...) ((void)sizeof!!(cond))
102 #endif /* !LIBCFS_DEBUG */
103
104 #ifdef CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK
105 /**
106  * This is for more expensive checks that one doesn't want to be enabled all
107  * the time. LINVRNT() has to be explicitly enabled by --enable-invariants
108  * configure option.
109  */
110 # define LINVRNT(exp) LASSERT(exp)
111 #else
112 # define LINVRNT(exp) ((void)sizeof!!(exp))
113 #endif
114
115 #define KLASSERT(e) LASSERT(e)
116
117 void lbug_with_loc(struct libcfs_debug_msg_data *) __attribute__((noreturn));
118
119 #define LBUG()                                                          \
120 do {                                                                    \
121         LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_EMERG, NULL);             \
122         lbug_with_loc(&msgdata);                                        \
123 } while(0)
124
125 /*
126  * Memory
127  */
128 #ifdef LIBCFS_DEBUG
129
130 extern atomic_t libcfs_kmemory;
131
132 # define libcfs_kmem_inc(ptr, size)             \
133 do {                                            \
134         atomic_add(size, &libcfs_kmemory);      \
135 } while (0)
136
137 # define libcfs_kmem_dec(ptr, size)             \
138 do {                                            \
139         atomic_sub(size, &libcfs_kmemory);      \
140 } while (0)
141
142 # define libcfs_kmem_read()                     \
143         atomic_read(&libcfs_kmemory)
144
145 #else
146 # define libcfs_kmem_inc(ptr, size) do {} while (0)
147 # define libcfs_kmem_dec(ptr, size) do {} while (0)
148 # define libcfs_kmem_read()     (0)
149 #endif /* LIBCFS_DEBUG */
150
151 #ifndef LIBCFS_VMALLOC_SIZE
152 #define LIBCFS_VMALLOC_SIZE        (2 << PAGE_SHIFT) /* 2 pages */
153 #endif
154
155 #define LIBCFS_ALLOC_PRE(size, mask)                                        \
156 do {                                                                        \
157         LASSERT(!in_interrupt() ||                                          \
158                 ((size) <= LIBCFS_VMALLOC_SIZE &&                           \
159                  ((mask) & GFP_ATOMIC)) != 0);                      \
160 } while (0)
161
162 #define LIBCFS_ALLOC_POST(ptr, size)                                        \
163 do {                                                                        \
164         if (unlikely((ptr) == NULL)) {                                      \
165                 CERROR("LNET: out of memory at %s:%d (tried to alloc '"     \
166                        #ptr "' = %d)\n", __FILE__, __LINE__, (int)(size));  \
167                 CERROR("LNET: %d total bytes allocated by lnet\n",          \
168                        libcfs_kmem_read());                                 \
169         } else {                                                            \
170                 libcfs_kmem_inc((ptr), (size));                             \
171                 CDEBUG(D_MALLOC, "alloc '" #ptr "': %d at %p (tot %d).\n",  \
172                        (int)(size), (ptr), libcfs_kmem_read());             \
173         }                                                                   \
174 } while (0)
175
176 /**
177  * allocate memory with GFP flags @mask
178  * The allocated memory is zeroed-out.
179  */
180 #define LIBCFS_ALLOC_GFP(ptr, size, mask)                                   \
181 do {                                                                        \
182         LIBCFS_ALLOC_PRE((size), (mask));                                   \
183         (ptr) = (size) <= LIBCFS_VMALLOC_SIZE ?                             \
184                 kzalloc((size), (mask)) : vzalloc(size);                    \
185         LIBCFS_ALLOC_POST((ptr), (size));                                   \
186 } while (0)
187
188 /**
189  * default allocator
190  */
191 #define LIBCFS_ALLOC(ptr, size) \
192         LIBCFS_ALLOC_GFP(ptr, size, GFP_NOFS)
193
194 /**
195  * non-sleeping allocator
196  */
197 #define LIBCFS_ALLOC_ATOMIC(ptr, size) \
198         LIBCFS_ALLOC_GFP(ptr, size, GFP_ATOMIC)
199
200 /**
201  * allocate memory for specified CPU partition
202  *   \a cptab != NULL, \a cpt is CPU partition id of \a cptab
203  *   \a cptab == NULL, \a cpt is HW NUMA node id
204  * The allocated memory is zeroed-out.
205  */
206 #define LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, mask)                   \
207 do {                                                                        \
208         LIBCFS_ALLOC_PRE((size), (mask));                                   \
209         (ptr) = (size) <= LIBCFS_VMALLOC_SIZE ?                             \
210                 cfs_cpt_malloc((cptab), (cpt), (size), (mask) | __GFP_ZERO) : \
211                 cfs_cpt_vzalloc((cptab), (cpt), (size));                    \
212         LIBCFS_ALLOC_POST((ptr), (size));                                   \
213 } while (0)
214
215 /** default numa allocator */
216 #define LIBCFS_CPT_ALLOC(ptr, cptab, cpt, size)                             \
217         LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, GFP_NOFS)
218
219 #ifdef LLIST_HEAD
220 void init_libcfs_vfree_atomic(void);
221 void exit_libcfs_vfree_atomic(void);
222 #define HAVE_LIBCFS_VFREE_ATOMIC
223 #else
224 #define init_libcfs_vfree_atomic() do {} while(0)
225 #define exit_libcfs_vfree_atomic() do {} while(0)
226 #endif
227
228 #define LIBCFS_FREE(ptr, size)                                          \
229 do {                                                                    \
230         int s = (size);                                                 \
231         if (unlikely((ptr) == NULL)) {                                  \
232                 CERROR("LIBCFS: free NULL '" #ptr "' (%d bytes) at "    \
233                        "%s:%d\n", s, __FILE__, __LINE__);               \
234                 break;                                                  \
235         }                                                               \
236         libcfs_kmem_dec((ptr), s);                                      \
237         CDEBUG(D_MALLOC, "kfreed '" #ptr "': %d at %p (tot %d).\n",     \
238                s, (ptr), libcfs_kmem_read());                           \
239         if (unlikely(s > LIBCFS_VMALLOC_SIZE))                          \
240                 libcfs_vfree_atomic(ptr);                               \
241         else                                                            \
242                 kfree(ptr);                                             \
243 } while (0)
244
245 /******************************************************************************/
246
247 struct task_struct;
248
249 void libcfs_debug_dumpstack(struct task_struct *tsk);
250 void libcfs_debug_dumplog(void);
251 int libcfs_debug_init(unsigned long bufsize);
252 int libcfs_debug_cleanup(void);
253 int libcfs_debug_clear_buffer(void);
254 int libcfs_debug_mark_buffer(const char *text);
255
256 /*
257  * allocate a variable array, returned value is an array of pointers.
258  * Caller can specify length of array by count.
259  */
260 void *cfs_array_alloc(int count, unsigned int size);
261 void  cfs_array_free(void *vars);
262
263 #define LASSERT_ATOMIC_ENABLED          (1)
264
265 #if LASSERT_ATOMIC_ENABLED
266
267 /** assert value of @a is equal to @v */
268 #define LASSERT_ATOMIC_EQ(a, v)                                 \
269 do {                                                            \
270         LASSERTF(atomic_read(a) == v,                       \
271                  "value: %d\n", atomic_read((a)));          \
272 } while (0)
273
274 /** assert value of @a is unequal to @v */
275 #define LASSERT_ATOMIC_NE(a, v)                                 \
276 do {                                                            \
277         LASSERTF(atomic_read(a) != v,                       \
278                  "value: %d\n", atomic_read((a)));          \
279 } while (0)
280
281 /** assert value of @a is little than @v */
282 #define LASSERT_ATOMIC_LT(a, v)                                 \
283 do {                                                            \
284         LASSERTF(atomic_read(a) < v,                        \
285                  "value: %d\n", atomic_read((a)));          \
286 } while (0)
287
288 /** assert value of @a is little/equal to @v */
289 #define LASSERT_ATOMIC_LE(a, v)                                 \
290 do {                                                            \
291         LASSERTF(atomic_read(a) <= v,                       \
292                  "value: %d\n", atomic_read((a)));          \
293 } while (0)
294
295 /** assert value of @a is great than @v */
296 #define LASSERT_ATOMIC_GT(a, v)                                 \
297 do {                                                            \
298         LASSERTF(atomic_read(a) > v,                        \
299                  "value: %d\n", atomic_read((a)));          \
300 } while (0)
301
302 /** assert value of @a is great/equal to @v */
303 #define LASSERT_ATOMIC_GE(a, v)                                 \
304 do {                                                            \
305         LASSERTF(atomic_read(a) >= v,                       \
306                  "value: %d\n", atomic_read((a)));          \
307 } while (0)
308
309 /** assert value of @a is great than @v1 and little than @v2 */
310 #define LASSERT_ATOMIC_GT_LT(a, v1, v2)                         \
311 do {                                                            \
312         int __v = atomic_read(a);                           \
313         LASSERTF(__v > v1 && __v < v2, "value: %d\n", __v);     \
314 } while (0)
315
316 /** assert value of @a is great than @v1 and little/equal to @v2 */
317 #define LASSERT_ATOMIC_GT_LE(a, v1, v2)                         \
318 do {                                                            \
319         int __v = atomic_read(a);                           \
320         LASSERTF(__v > v1 && __v <= v2, "value: %d\n", __v);    \
321 } while (0)
322
323 /** assert value of @a is great/equal to @v1 and little than @v2 */
324 #define LASSERT_ATOMIC_GE_LT(a, v1, v2)                         \
325 do {                                                            \
326         int __v = atomic_read(a);                           \
327         LASSERTF(__v >= v1 && __v < v2, "value: %d\n", __v);    \
328 } while (0)
329
330 /** assert value of @a is great/equal to @v1 and little/equal to @v2 */
331 #define LASSERT_ATOMIC_GE_LE(a, v1, v2)                         \
332 do {                                                            \
333         int __v = atomic_read(a);                           \
334         LASSERTF(__v >= v1 && __v <= v2, "value: %d\n", __v);   \
335 } while (0)
336
337 #else /* !LASSERT_ATOMIC_ENABLED */
338
339 #define LASSERT_ATOMIC_EQ(a, v)                 do {} while (0)
340 #define LASSERT_ATOMIC_NE(a, v)                 do {} while (0)
341 #define LASSERT_ATOMIC_LT(a, v)                 do {} while (0)
342 #define LASSERT_ATOMIC_LE(a, v)                 do {} while (0)
343 #define LASSERT_ATOMIC_GT(a, v)                 do {} while (0)
344 #define LASSERT_ATOMIC_GE(a, v)                 do {} while (0)
345 #define LASSERT_ATOMIC_GT_LT(a, v1, v2)         do {} while (0)
346 #define LASSERT_ATOMIC_GT_LE(a, v1, v2)         do {} while (0)
347 #define LASSERT_ATOMIC_GE_LT(a, v1, v2)         do {} while (0)
348 #define LASSERT_ATOMIC_GE_LE(a, v1, v2)         do {} while (0)
349
350 #endif /* LASSERT_ATOMIC_ENABLED */
351
352 #define LASSERT_ATOMIC_ZERO(a)                  LASSERT_ATOMIC_EQ(a, 0)
353 #define LASSERT_ATOMIC_POS(a)                   LASSERT_ATOMIC_GT(a, 0)
354
355 #define CFS_ALLOC_PTR(ptr)      LIBCFS_ALLOC(ptr, sizeof (*(ptr)));
356 #define CFS_FREE_PTR(ptr)       LIBCFS_FREE(ptr, sizeof (*(ptr)));
357
358 /** Compile-time assertion.
359
360  * Check an invariant described by a constant expression at compile time by
361  * forcing a compiler error if it does not hold.  \a cond must be a constant
362  * expression as defined by the ISO C Standard:
363  *
364  *       6.8.4.2  The switch statement
365  *       ....
366  *       [#3] The expression of each case label shall be  an  integer
367  *       constant   expression  and  no  two  of  the  case  constant
368  *       expressions in the same switch statement shall have the same
369  *       value  after  conversion...
370  *
371  */
372 #define CLASSERT(cond) do {switch (1) {case (cond): case 0: break; } } while (0)
373
374 /* implication */
375 #define ergo(a, b) (!(a) || (b))
376 /* logical equivalence */
377 #define equi(a, b) (!!(a) == !!(b))
378
379 /* what used to be in portals_lib.h */
380 #ifndef MIN
381 # define MIN(a,b) (((a)<(b)) ? (a): (b))
382 #endif
383 #ifndef MAX
384 # define MAX(a,b) (((a)>(b)) ? (a): (b))
385 #endif
386
387 #define MKSTR(ptr) ((ptr))? (ptr) : ""
388
389 static inline size_t cfs_size_round4(size_t val)
390 {
391         return (val + 3) & (~0x3);
392 }
393
394 #ifndef HAVE_CFS_SIZE_ROUND
395 static inline size_t cfs_size_round(size_t val)
396 {
397         return (val + 7) & (~0x7);
398 }
399 #define HAVE_CFS_SIZE_ROUND
400 #endif
401
402 static inline size_t cfs_size_round16(size_t val)
403 {
404         return (val + 0xf) & (~0xf);
405 }
406
407 static inline size_t cfs_size_round32(size_t val)
408 {
409         return (val + 0x1f) & (~0x1f);
410 }
411
412 static inline size_t cfs_size_round0(size_t val)
413 {
414         if (!val)
415                 return 0;
416         return (val + 1 + 7) & (~0x7);
417 }
418
419 static inline size_t cfs_round_strlen(char *fset)
420 {
421         return cfs_size_round(strlen(fset) + 1);
422 }
423
424 extern struct cfs_psdev_ops libcfs_psdev_ops;
425 extern struct miscdevice libcfs_dev;
426 extern struct cfs_wi_sched *cfs_sched_rehash;
427
428 #endif