18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/// 38c2ecf20Sopenharmony_ci/// Find if/else condition with kmalloc/vmalloc calls. 48c2ecf20Sopenharmony_ci/// Suggest to use kvmalloc instead. Same for kvfree. 58c2ecf20Sopenharmony_ci/// 68c2ecf20Sopenharmony_ci// Confidence: High 78c2ecf20Sopenharmony_ci// Copyright: (C) 2020 Denis Efremov ISPRAS 88c2ecf20Sopenharmony_ci// Options: --no-includes --include-headers 98c2ecf20Sopenharmony_ci// 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_civirtual patch 128c2ecf20Sopenharmony_civirtual report 138c2ecf20Sopenharmony_civirtual org 148c2ecf20Sopenharmony_civirtual context 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci@initialize:python@ 178c2ecf20Sopenharmony_ci@@ 188c2ecf20Sopenharmony_cifilter = frozenset(['kvfree']) 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cidef relevant(p): 218c2ecf20Sopenharmony_ci return not (filter & {el.current_element for el in p}) 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci@kvmalloc depends on !patch@ 248c2ecf20Sopenharmony_ciexpression E, E1, size; 258c2ecf20Sopenharmony_ciidentifier flags; 268c2ecf20Sopenharmony_cibinary operator cmp = {<=, <, ==, >, >=}; 278c2ecf20Sopenharmony_ciidentifier x; 288c2ecf20Sopenharmony_citype T; 298c2ecf20Sopenharmony_ciposition p; 308c2ecf20Sopenharmony_ci@@ 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci( 338c2ecf20Sopenharmony_ci* if (size cmp E1 || ...)@p { 348c2ecf20Sopenharmony_ci ... 358c2ecf20Sopenharmony_ci* E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| 368c2ecf20Sopenharmony_ci* kmalloc_array\|kmalloc_array_node\|kcalloc_node\) 378c2ecf20Sopenharmony_ci* (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...) 388c2ecf20Sopenharmony_ci ... 398c2ecf20Sopenharmony_ci } else { 408c2ecf20Sopenharmony_ci ... 418c2ecf20Sopenharmony_ci* E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) 428c2ecf20Sopenharmony_ci ... 438c2ecf20Sopenharmony_ci } 448c2ecf20Sopenharmony_ci| 458c2ecf20Sopenharmony_ci* E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| 468c2ecf20Sopenharmony_ci* kmalloc_array\|kmalloc_array_node\|kcalloc_node\) 478c2ecf20Sopenharmony_ci* (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...) 488c2ecf20Sopenharmony_ci ... when != E = E1 498c2ecf20Sopenharmony_ci when != size = E1 508c2ecf20Sopenharmony_ci when any 518c2ecf20Sopenharmony_ci* if (E == NULL)@p { 528c2ecf20Sopenharmony_ci ... 538c2ecf20Sopenharmony_ci* E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) 548c2ecf20Sopenharmony_ci ... 558c2ecf20Sopenharmony_ci } 568c2ecf20Sopenharmony_ci| 578c2ecf20Sopenharmony_ci* T x = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| 588c2ecf20Sopenharmony_ci* kmalloc_array\|kmalloc_array_node\|kcalloc_node\) 598c2ecf20Sopenharmony_ci* (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...); 608c2ecf20Sopenharmony_ci ... when != x = E1 618c2ecf20Sopenharmony_ci when != size = E1 628c2ecf20Sopenharmony_ci when any 638c2ecf20Sopenharmony_ci* if (x == NULL)@p { 648c2ecf20Sopenharmony_ci ... 658c2ecf20Sopenharmony_ci* x = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) 668c2ecf20Sopenharmony_ci ... 678c2ecf20Sopenharmony_ci } 688c2ecf20Sopenharmony_ci) 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci@kvfree depends on !patch@ 718c2ecf20Sopenharmony_ciexpression E; 728c2ecf20Sopenharmony_ciposition p : script:python() { relevant(p) }; 738c2ecf20Sopenharmony_ci@@ 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci* if (is_vmalloc_addr(E))@p { 768c2ecf20Sopenharmony_ci ... 778c2ecf20Sopenharmony_ci* vfree(E) 788c2ecf20Sopenharmony_ci ... 798c2ecf20Sopenharmony_ci } else { 808c2ecf20Sopenharmony_ci ... when != krealloc(E, ...) 818c2ecf20Sopenharmony_ci when any 828c2ecf20Sopenharmony_ci* \(kfree\|kzfree\)(E) 838c2ecf20Sopenharmony_ci ... 848c2ecf20Sopenharmony_ci } 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci@depends on patch@ 878c2ecf20Sopenharmony_ciexpression E, E1, size, node; 888c2ecf20Sopenharmony_cibinary operator cmp = {<=, <, ==, >, >=}; 898c2ecf20Sopenharmony_ciidentifier flags, x; 908c2ecf20Sopenharmony_citype T; 918c2ecf20Sopenharmony_ci@@ 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci( 948c2ecf20Sopenharmony_ci- if (size cmp E1) 958c2ecf20Sopenharmony_ci- E = kmalloc(size, flags); 968c2ecf20Sopenharmony_ci- else 978c2ecf20Sopenharmony_ci- E = vmalloc(size); 988c2ecf20Sopenharmony_ci+ E = kvmalloc(size, flags); 998c2ecf20Sopenharmony_ci| 1008c2ecf20Sopenharmony_ci- if (size cmp E1) 1018c2ecf20Sopenharmony_ci- E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 1028c2ecf20Sopenharmony_ci- else 1038c2ecf20Sopenharmony_ci- E = vmalloc(size); 1048c2ecf20Sopenharmony_ci+ E = kvmalloc(size, GFP_KERNEL); 1058c2ecf20Sopenharmony_ci| 1068c2ecf20Sopenharmony_ci- E = kmalloc(size, flags | __GFP_NOWARN); 1078c2ecf20Sopenharmony_ci- if (E == NULL) 1088c2ecf20Sopenharmony_ci- E = vmalloc(size); 1098c2ecf20Sopenharmony_ci+ E = kvmalloc(size, flags); 1108c2ecf20Sopenharmony_ci| 1118c2ecf20Sopenharmony_ci- E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 1128c2ecf20Sopenharmony_ci- if (E == NULL) 1138c2ecf20Sopenharmony_ci- E = vmalloc(size); 1148c2ecf20Sopenharmony_ci+ E = kvmalloc(size, GFP_KERNEL); 1158c2ecf20Sopenharmony_ci| 1168c2ecf20Sopenharmony_ci- T x = kmalloc(size, flags | __GFP_NOWARN); 1178c2ecf20Sopenharmony_ci- if (x == NULL) 1188c2ecf20Sopenharmony_ci- x = vmalloc(size); 1198c2ecf20Sopenharmony_ci+ T x = kvmalloc(size, flags); 1208c2ecf20Sopenharmony_ci| 1218c2ecf20Sopenharmony_ci- T x = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 1228c2ecf20Sopenharmony_ci- if (x == NULL) 1238c2ecf20Sopenharmony_ci- x = vmalloc(size); 1248c2ecf20Sopenharmony_ci+ T x = kvmalloc(size, GFP_KERNEL); 1258c2ecf20Sopenharmony_ci| 1268c2ecf20Sopenharmony_ci- if (size cmp E1) 1278c2ecf20Sopenharmony_ci- E = kzalloc(size, flags); 1288c2ecf20Sopenharmony_ci- else 1298c2ecf20Sopenharmony_ci- E = vzalloc(size); 1308c2ecf20Sopenharmony_ci+ E = kvzalloc(size, flags); 1318c2ecf20Sopenharmony_ci| 1328c2ecf20Sopenharmony_ci- if (size cmp E1) 1338c2ecf20Sopenharmony_ci- E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 1348c2ecf20Sopenharmony_ci- else 1358c2ecf20Sopenharmony_ci- E = vzalloc(size); 1368c2ecf20Sopenharmony_ci+ E = kvzalloc(size, GFP_KERNEL); 1378c2ecf20Sopenharmony_ci| 1388c2ecf20Sopenharmony_ci- E = kzalloc(size, flags | __GFP_NOWARN); 1398c2ecf20Sopenharmony_ci- if (E == NULL) 1408c2ecf20Sopenharmony_ci- E = vzalloc(size); 1418c2ecf20Sopenharmony_ci+ E = kvzalloc(size, flags); 1428c2ecf20Sopenharmony_ci| 1438c2ecf20Sopenharmony_ci- E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 1448c2ecf20Sopenharmony_ci- if (E == NULL) 1458c2ecf20Sopenharmony_ci- E = vzalloc(size); 1468c2ecf20Sopenharmony_ci+ E = kvzalloc(size, GFP_KERNEL); 1478c2ecf20Sopenharmony_ci| 1488c2ecf20Sopenharmony_ci- T x = kzalloc(size, flags | __GFP_NOWARN); 1498c2ecf20Sopenharmony_ci- if (x == NULL) 1508c2ecf20Sopenharmony_ci- x = vzalloc(size); 1518c2ecf20Sopenharmony_ci+ T x = kvzalloc(size, flags); 1528c2ecf20Sopenharmony_ci| 1538c2ecf20Sopenharmony_ci- T x = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 1548c2ecf20Sopenharmony_ci- if (x == NULL) 1558c2ecf20Sopenharmony_ci- x = vzalloc(size); 1568c2ecf20Sopenharmony_ci+ T x = kvzalloc(size, GFP_KERNEL); 1578c2ecf20Sopenharmony_ci| 1588c2ecf20Sopenharmony_ci- if (size cmp E1) 1598c2ecf20Sopenharmony_ci- E = kmalloc_node(size, flags, node); 1608c2ecf20Sopenharmony_ci- else 1618c2ecf20Sopenharmony_ci- E = vmalloc_node(size, node); 1628c2ecf20Sopenharmony_ci+ E = kvmalloc_node(size, flags, node); 1638c2ecf20Sopenharmony_ci| 1648c2ecf20Sopenharmony_ci- if (size cmp E1) 1658c2ecf20Sopenharmony_ci- E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 1668c2ecf20Sopenharmony_ci- else 1678c2ecf20Sopenharmony_ci- E = vmalloc_node(size, node); 1688c2ecf20Sopenharmony_ci+ E = kvmalloc_node(size, GFP_KERNEL, node); 1698c2ecf20Sopenharmony_ci| 1708c2ecf20Sopenharmony_ci- E = kmalloc_node(size, flags | __GFP_NOWARN, node); 1718c2ecf20Sopenharmony_ci- if (E == NULL) 1728c2ecf20Sopenharmony_ci- E = vmalloc_node(size, node); 1738c2ecf20Sopenharmony_ci+ E = kvmalloc_node(size, flags, node); 1748c2ecf20Sopenharmony_ci| 1758c2ecf20Sopenharmony_ci- E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 1768c2ecf20Sopenharmony_ci- if (E == NULL) 1778c2ecf20Sopenharmony_ci- E = vmalloc_node(size, node); 1788c2ecf20Sopenharmony_ci+ E = kvmalloc_node(size, GFP_KERNEL, node); 1798c2ecf20Sopenharmony_ci| 1808c2ecf20Sopenharmony_ci- T x = kmalloc_node(size, flags | __GFP_NOWARN, node); 1818c2ecf20Sopenharmony_ci- if (x == NULL) 1828c2ecf20Sopenharmony_ci- x = vmalloc_node(size, node); 1838c2ecf20Sopenharmony_ci+ T x = kvmalloc_node(size, flags, node); 1848c2ecf20Sopenharmony_ci| 1858c2ecf20Sopenharmony_ci- T x = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 1868c2ecf20Sopenharmony_ci- if (x == NULL) 1878c2ecf20Sopenharmony_ci- x = vmalloc_node(size, node); 1888c2ecf20Sopenharmony_ci+ T x = kvmalloc_node(size, GFP_KERNEL, node); 1898c2ecf20Sopenharmony_ci| 1908c2ecf20Sopenharmony_ci- if (size cmp E1) 1918c2ecf20Sopenharmony_ci- E = kvzalloc_node(size, flags, node); 1928c2ecf20Sopenharmony_ci- else 1938c2ecf20Sopenharmony_ci- E = vzalloc_node(size, node); 1948c2ecf20Sopenharmony_ci+ E = kvzalloc_node(size, flags, node); 1958c2ecf20Sopenharmony_ci| 1968c2ecf20Sopenharmony_ci- if (size cmp E1) 1978c2ecf20Sopenharmony_ci- E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 1988c2ecf20Sopenharmony_ci- else 1998c2ecf20Sopenharmony_ci- E = vzalloc_node(size, node); 2008c2ecf20Sopenharmony_ci+ E = kvzalloc_node(size, GFP_KERNEL, node); 2018c2ecf20Sopenharmony_ci| 2028c2ecf20Sopenharmony_ci- E = kvzalloc_node(size, flags | __GFP_NOWARN, node); 2038c2ecf20Sopenharmony_ci- if (E == NULL) 2048c2ecf20Sopenharmony_ci- E = vzalloc_node(size, node); 2058c2ecf20Sopenharmony_ci+ E = kvzalloc_node(size, flags, node); 2068c2ecf20Sopenharmony_ci| 2078c2ecf20Sopenharmony_ci- E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 2088c2ecf20Sopenharmony_ci- if (E == NULL) 2098c2ecf20Sopenharmony_ci- E = vzalloc_node(size, node); 2108c2ecf20Sopenharmony_ci+ E = kvzalloc_node(size, GFP_KERNEL, node); 2118c2ecf20Sopenharmony_ci| 2128c2ecf20Sopenharmony_ci- T x = kvzalloc_node(size, flags | __GFP_NOWARN, node); 2138c2ecf20Sopenharmony_ci- if (x == NULL) 2148c2ecf20Sopenharmony_ci- x = vzalloc_node(size, node); 2158c2ecf20Sopenharmony_ci+ T x = kvzalloc_node(size, flags, node); 2168c2ecf20Sopenharmony_ci| 2178c2ecf20Sopenharmony_ci- T x = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 2188c2ecf20Sopenharmony_ci- if (x == NULL) 2198c2ecf20Sopenharmony_ci- x = vzalloc_node(size, node); 2208c2ecf20Sopenharmony_ci+ T x = kvzalloc_node(size, GFP_KERNEL, node); 2218c2ecf20Sopenharmony_ci) 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci@depends on patch@ 2248c2ecf20Sopenharmony_ciexpression E; 2258c2ecf20Sopenharmony_ciposition p : script:python() { relevant(p) }; 2268c2ecf20Sopenharmony_ci@@ 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci- if (is_vmalloc_addr(E))@p 2298c2ecf20Sopenharmony_ci- vfree(E); 2308c2ecf20Sopenharmony_ci- else 2318c2ecf20Sopenharmony_ci- kfree(E); 2328c2ecf20Sopenharmony_ci+ kvfree(E); 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci@script: python depends on report@ 2358c2ecf20Sopenharmony_cip << kvmalloc.p; 2368c2ecf20Sopenharmony_ci@@ 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_cicoccilib.report.print_report(p[0], "WARNING opportunity for kvmalloc") 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci@script: python depends on org@ 2418c2ecf20Sopenharmony_cip << kvmalloc.p; 2428c2ecf20Sopenharmony_ci@@ 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_cicoccilib.org.print_todo(p[0], "WARNING opportunity for kvmalloc") 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci@script: python depends on report@ 2478c2ecf20Sopenharmony_cip << kvfree.p; 2488c2ecf20Sopenharmony_ci@@ 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_cicoccilib.report.print_report(p[0], "WARNING opportunity for kvfree") 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci@script: python depends on org@ 2538c2ecf20Sopenharmony_cip << kvfree.p; 2548c2ecf20Sopenharmony_ci@@ 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_cicoccilib.org.print_todo(p[0], "WARNING opportunity for kvfree") 257