1// SPDX-License-Identifier: GPL-2.0-only
2///
3/// Find if/else condition with kmalloc/vmalloc calls.
4/// Suggest to use kvmalloc instead. Same for kvfree.
5///
6// Confidence: High
7// Copyright: (C) 2020 Denis Efremov ISPRAS
8// Options: --no-includes --include-headers
9//
10
11virtual patch
12virtual report
13virtual org
14virtual context
15
16@initialize:python@
17@@
18filter = frozenset(['kvfree'])
19
20def relevant(p):
21    return not (filter & {el.current_element for el in p})
22
23@kvmalloc depends on !patch@
24expression E, E1, size;
25identifier flags;
26binary operator cmp = {<=, <, ==, >, >=};
27identifier x;
28type T;
29position p;
30@@
31
32(
33* if (size cmp E1 || ...)@p {
34    ...
35*    E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
36*          kmalloc_array\|kmalloc_array_node\|kcalloc_node\)
37*          (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...)
38    ...
39  } else {
40    ...
41*    E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...)
42    ...
43  }
44|
45* E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
46*       kmalloc_array\|kmalloc_array_node\|kcalloc_node\)
47*       (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...)
48  ... when != E = E1
49      when != size = E1
50      when any
51* if (E == NULL)@p {
52    ...
53*   E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...)
54    ...
55  }
56|
57* T x = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
58*         kmalloc_array\|kmalloc_array_node\|kcalloc_node\)
59*         (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...);
60  ... when != x = E1
61      when != size = E1
62      when any
63* if (x == NULL)@p {
64    ...
65*   x = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...)
66    ...
67  }
68)
69
70@kvfree depends on !patch@
71expression E;
72position p : script:python() { relevant(p) };
73@@
74
75* if (is_vmalloc_addr(E))@p {
76    ...
77*   vfree(E)
78    ...
79  } else {
80    ... when != krealloc(E, ...)
81        when any
82*   \(kfree\|kzfree\)(E)
83    ...
84  }
85
86@depends on patch@
87expression E, E1, size, node;
88binary operator cmp = {<=, <, ==, >, >=};
89identifier flags, x;
90type T;
91@@
92
93(
94- if (size cmp E1)
95-    E = kmalloc(size, flags);
96- else
97-    E = vmalloc(size);
98+ E = kvmalloc(size, flags);
99|
100- if (size cmp E1)
101-    E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
102- else
103-    E = vmalloc(size);
104+ E = kvmalloc(size, GFP_KERNEL);
105|
106- E = kmalloc(size, flags | __GFP_NOWARN);
107- if (E == NULL)
108-   E = vmalloc(size);
109+ E = kvmalloc(size, flags);
110|
111- E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
112- if (E == NULL)
113-   E = vmalloc(size);
114+ E = kvmalloc(size, GFP_KERNEL);
115|
116- T x = kmalloc(size, flags | __GFP_NOWARN);
117- if (x == NULL)
118-   x = vmalloc(size);
119+ T x = kvmalloc(size, flags);
120|
121- T x = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
122- if (x == NULL)
123-   x = vmalloc(size);
124+ T x = kvmalloc(size, GFP_KERNEL);
125|
126- if (size cmp E1)
127-    E = kzalloc(size, flags);
128- else
129-    E = vzalloc(size);
130+ E = kvzalloc(size, flags);
131|
132- if (size cmp E1)
133-    E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
134- else
135-    E = vzalloc(size);
136+ E = kvzalloc(size, GFP_KERNEL);
137|
138- E = kzalloc(size, flags | __GFP_NOWARN);
139- if (E == NULL)
140-   E = vzalloc(size);
141+ E = kvzalloc(size, flags);
142|
143- E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
144- if (E == NULL)
145-   E = vzalloc(size);
146+ E = kvzalloc(size, GFP_KERNEL);
147|
148- T x = kzalloc(size, flags | __GFP_NOWARN);
149- if (x == NULL)
150-   x = vzalloc(size);
151+ T x = kvzalloc(size, flags);
152|
153- T x = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
154- if (x == NULL)
155-   x = vzalloc(size);
156+ T x = kvzalloc(size, GFP_KERNEL);
157|
158- if (size cmp E1)
159-    E = kmalloc_node(size, flags, node);
160- else
161-    E = vmalloc_node(size, node);
162+ E = kvmalloc_node(size, flags, node);
163|
164- if (size cmp E1)
165-    E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
166- else
167-    E = vmalloc_node(size, node);
168+ E = kvmalloc_node(size, GFP_KERNEL, node);
169|
170- E = kmalloc_node(size, flags | __GFP_NOWARN, node);
171- if (E == NULL)
172-   E = vmalloc_node(size, node);
173+ E = kvmalloc_node(size, flags, node);
174|
175- E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
176- if (E == NULL)
177-   E = vmalloc_node(size, node);
178+ E = kvmalloc_node(size, GFP_KERNEL, node);
179|
180- T x = kmalloc_node(size, flags | __GFP_NOWARN, node);
181- if (x == NULL)
182-   x = vmalloc_node(size, node);
183+ T x = kvmalloc_node(size, flags, node);
184|
185- T x = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
186- if (x == NULL)
187-   x = vmalloc_node(size, node);
188+ T x = kvmalloc_node(size, GFP_KERNEL, node);
189|
190- if (size cmp E1)
191-    E = kvzalloc_node(size, flags, node);
192- else
193-    E = vzalloc_node(size, node);
194+ E = kvzalloc_node(size, flags, node);
195|
196- if (size cmp E1)
197-    E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
198- else
199-    E = vzalloc_node(size, node);
200+ E = kvzalloc_node(size, GFP_KERNEL, node);
201|
202- E = kvzalloc_node(size, flags | __GFP_NOWARN, node);
203- if (E == NULL)
204-   E = vzalloc_node(size, node);
205+ E = kvzalloc_node(size, flags, node);
206|
207- E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
208- if (E == NULL)
209-   E = vzalloc_node(size, node);
210+ E = kvzalloc_node(size, GFP_KERNEL, node);
211|
212- T x = kvzalloc_node(size, flags | __GFP_NOWARN, node);
213- if (x == NULL)
214-   x = vzalloc_node(size, node);
215+ T x = kvzalloc_node(size, flags, node);
216|
217- T x = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
218- if (x == NULL)
219-   x = vzalloc_node(size, node);
220+ T x = kvzalloc_node(size, GFP_KERNEL, node);
221)
222
223@depends on patch@
224expression E;
225position p : script:python() { relevant(p) };
226@@
227
228- if (is_vmalloc_addr(E))@p
229-   vfree(E);
230- else
231-   kfree(E);
232+ kvfree(E);
233
234@script: python depends on report@
235p << kvmalloc.p;
236@@
237
238coccilib.report.print_report(p[0], "WARNING opportunity for kvmalloc")
239
240@script: python depends on org@
241p << kvmalloc.p;
242@@
243
244coccilib.org.print_todo(p[0], "WARNING opportunity for kvmalloc")
245
246@script: python depends on report@
247p << kvfree.p;
248@@
249
250coccilib.report.print_report(p[0], "WARNING opportunity for kvfree")
251
252@script: python depends on org@
253p << kvfree.p;
254@@
255
256coccilib.org.print_todo(p[0], "WARNING opportunity for kvfree")
257