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