1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _LINUX_HELPER_MACROS_H_
3#define _LINUX_HELPER_MACROS_H_
4
5#include <linux/compiler_attributes.h>
6#include <linux/math.h>
7#include <linux/typecheck.h>
8#include <linux/stddef.h>
9
10/**
11 * for_each_if - helper for handling conditionals in various for_each macros
12 * @condition: The condition to check
13 *
14 * Typical use::
15 *
16 * #define for_each_foo_bar(x, y) \'
17 * list_for_each_entry(x, y->list, head) \'
18 * for_each_if(x->something == SOMETHING)
19 *
20 * The for_each_if() macro makes the use of for_each_foo_bar() less error
21 * prone.
22 */
23#define for_each_if(condition) if (!(condition)) {} else
24
25/**
26 * find_closest - locate the closest element in a sorted array
27 * @x: The reference value.
28 * @a: The array in which to look for the closest element. Must be sorted
29 * in ascending order.
30 * @as: Size of 'a'.
31 *
32 * Returns the index of the element closest to 'x'.
33 * Note: If using an array of negative numbers (or mixed positive numbers),
34 * then be sure that 'x' is of a signed-type to get good results.
35 */
36#define find_closest(x, a, as) \
37({ \
38 typeof(as) __fc_i, __fc_as = (as) - 1; \
39 long __fc_mid_x, __fc_x = (x); \
40 long __fc_left, __fc_right; \
41 typeof(*a) const *__fc_a = (a); \
42 for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \
43 __fc_mid_x = (__fc_a[__fc_i] + __fc_a[__fc_i + 1]) / 2; \
44 if (__fc_x <= __fc_mid_x) { \
45 __fc_left = __fc_x - __fc_a[__fc_i]; \
46 __fc_right = __fc_a[__fc_i + 1] - __fc_x; \
47 if (__fc_right < __fc_left) \
48 __fc_i++; \
49 break; \
50 } \
51 } \
52 (__fc_i); \
53})
54
55/**
56 * find_closest_descending - locate the closest element in a sorted array
57 * @x: The reference value.
58 * @a: The array in which to look for the closest element. Must be sorted
59 * in descending order.
60 * @as: Size of 'a'.
61 *
62 * Similar to find_closest() but 'a' is expected to be sorted in descending
63 * order. The iteration is done in reverse order, so that the comparison
64 * of '__fc_right' & '__fc_left' also works for unsigned numbers.
65 */
66#define find_closest_descending(x, a, as) \
67({ \
68 typeof(as) __fc_i, __fc_as = (as) - 1; \
69 long __fc_mid_x, __fc_x = (x); \
70 long __fc_left, __fc_right; \
71 typeof(*a) const *__fc_a = (a); \
72 for (__fc_i = __fc_as; __fc_i >= 1; __fc_i--) { \
73 __fc_mid_x = (__fc_a[__fc_i] + __fc_a[__fc_i - 1]) / 2; \
74 if (__fc_x <= __fc_mid_x) { \
75 __fc_left = __fc_x - __fc_a[__fc_i]; \
76 __fc_right = __fc_a[__fc_i - 1] - __fc_x; \
77 if (__fc_right < __fc_left) \
78 __fc_i--; \
79 break; \
80 } \
81 } \
82 (__fc_i); \
83})
84
85/**
86 * PTR_IF - evaluate to @ptr if @cond is true, or to NULL otherwise.
87 * @cond: A conditional, usually in a form of IS_ENABLED(CONFIG_FOO)
88 * @ptr: A pointer to assign if @cond is true.
89 *
90 * PTR_IF(IS_ENABLED(CONFIG_FOO), ptr) evaluates to @ptr if CONFIG_FOO is set
91 * to 'y' or 'm', or to NULL otherwise. The @ptr argument must be a pointer.
92 *
93 * The macro can be very useful to help compiler dropping dead code.
94 *
95 * For instance, consider the following::
96 *
97 * #ifdef CONFIG_FOO_SUSPEND
98 * static int foo_suspend(struct device *dev)
99 * {
100 * ...
101 * }
102 * #endif
103 *
104 * static struct pm_ops foo_ops = {
105 * #ifdef CONFIG_FOO_SUSPEND
106 * .suspend = foo_suspend,
107 * #endif
108 * };
109 *
110 * While this works, the foo_suspend() macro is compiled conditionally,
111 * only when CONFIG_FOO_SUSPEND is set. This is problematic, as there could
112 * be a build bug in this function, we wouldn't have a way to know unless
113 * the configuration option is set.
114 *
115 * An alternative is to declare foo_suspend() always, but mark it
116 * as __maybe_unused. This works, but the __maybe_unused attribute
117 * is required to instruct the compiler that the function may not
118 * be referenced anywhere, and is safe to remove without making
119 * a fuss about it. This makes the programmer responsible for tagging
120 * the functions that can be garbage-collected.
121 *
122 * With the macro it is possible to write the following:
123 *
124 * static int foo_suspend(struct device *dev)
125 * {
126 * ...
127 * }
128 *
129 * static struct pm_ops foo_ops = {
130 * .suspend = PTR_IF(IS_ENABLED(CONFIG_FOO_SUSPEND), foo_suspend),
131 * };
132 *
133 * The foo_suspend() function will now be automatically dropped by the
134 * compiler, and it does not require any specific attribute.
135 */
136#define PTR_IF(cond, ptr) ((cond) ? (ptr) : NULL)
137
138/**
139 * to_user_ptr - cast a pointer passed as u64 from user space to void __user *
140 * @x: The u64 value from user space, usually via IOCTL
141 *
142 * to_user_ptr() simply casts a pointer passed as u64 from user space to void
143 * __user * correctly. Using this lets us get rid of all the tiresome casts.
144 */
145#define u64_to_user_ptr(x) \
146({ \
147 typecheck(u64, (x)); \
148 (void __user *)(uintptr_t)(x); \
149})
150
151/**
152 * is_insidevar - check if the @ptr points inside the @var memory range.
153 * @ptr: the pointer to a memory address.
154 * @var: the variable which address and size identify the memory range.
155 *
156 * Evaluates to true if the address in @ptr lies within the memory
157 * range allocated to @var.
158 */
159#define is_insidevar(ptr, var) \
160 ((uintptr_t)(ptr) >= (uintptr_t)(var) && \
161 (uintptr_t)(ptr) < (uintptr_t)(var) + sizeof(var))
162
163#endif
164