Whamcloud - gitweb
LU-18151 contrib: add example Coccinelle scripts 73/56073/2
authorTimothy Day <timday@amazon.com>
Fri, 16 Aug 2024 03:25:56 +0000 (23:25 -0400)
committerOleg Drokin <green@whamcloud.com>
Fri, 23 Aug 2024 22:09:49 +0000 (22:09 +0000)
Add a few example Coccinelle scripts to contrib/. Also,
update clang-and-static-analysis.txt to talk about
Coccinelle.

Test-Parameters: trivial
Signed-off-by: Timothy Day <timday@amazon.com>
Change-Id: I9a09b2f273bb2257e67c253cb3a69896c32d588a
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/56073
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Patrick Farrell <patrick.farrell@oracle.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: jsimmons <jsimmons@infradead.org>
Reviewed-by: Arshad Hussain <arshad.hussain@aeoncomputing.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Documentation/clang-and-static-analysis.txt
contrib/cocci/ldlm.cocci [new file with mode: 0644]
contrib/cocci/ldlm_flags.cocci [new file with mode: 0644]
contrib/cocci/lustre_free.cocci [new file with mode: 0644]

index 06b66d2..cdea821 100644 (file)
@@ -19,7 +19,8 @@ Contents
 4. Coverity
        4.1 Context
        4.2 References
-5. Miscellaneous Tools
+5. Coccinelle
+6. Miscellaneous Tools
 
 ===================
 = 1. Introduction =
@@ -131,8 +132,43 @@ details.
 Early Coverity: https://wiki.lustre.org/images/8/8a/LUG2013-Lustre_Static_Code_Analysis-Bull.pdf
 Coverity Scan Page: https://scan.coverity.com/projects/lustre
 
+=================
+= 5. Coccinelle =
+=================
+
+5.1 Context
+===========
+
+Coccinelle is a automated refactoring tool for C code. Coccinelle uses it's native
+understanding of the C language to automatically apply semantic patches (i.e Coccinelle
+scripts) to C files. This can be used to remove cruft, fix common coding mistakes,
+update APIs, and more. Coccinelle can readily obtained as a package in common Linux
+distributions.
+
+The primary tools for interacting with Coccinelle is `spatch`. A simple invocation could
+be:
+
+       spatch --sp-file test.cocci --in-place --dir lustre/
+
+This applies the `test.cocci` semantic patch directory to the Lustre codebase. The
+tool doesn't actually create patch files, so the developer must still manually
+create granular commits. Some example scripts can be found in `contrib/cocci`.
+
+For automatically generated patches, it's useful to include a message like:
+
+       The patch has been generated with the coccinelle script below.
+
+Either the full script should be added to the commit message, or a pointer should
+be provided to the source.
+
+5.2 References
+==============
+
+Official Website: https://coccinelle.gitlabpages.inria.fr/website/documentation.html
+Kernel Documentation: https://www.kernel.org/doc/html/latest/dev-tools/coccinelle.html
+
 ==========================
-= 5. Miscellaneous Tools =
+= 6. Miscellaneous Tools =
 ==========================
 
 Other tools that might be investigated, for those interested:
diff --git a/contrib/cocci/ldlm.cocci b/contrib/cocci/ldlm.cocci
new file mode 100644 (file)
index 0000000..1a2ff88
--- /dev/null
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2024, Amazon and/or its affiliates. All rights reserved.
+// Use is subject to license terms.
+//
+// Remove pointless macros. Demonstrates a simple find-and-replace with
+// Coccinelle.
+//
+// Author: Timothy Day <timday@amazon.com>
+//
+
+@@
+expression x;
+@@
+- LDLM_LOCK_PUT(x)
++ ldlm_lock_put(x)
+@@
+expression x;
+@@
+- LDLM_LOCK_RELEASE(x)
++ ldlm_lock_put(x)
+@@
+expression x;
+@@
+- LDLM_LOCK_GET(x)
++ ldlm_lock_get(x)
diff --git a/contrib/cocci/ldlm_flags.cocci b/contrib/cocci/ldlm_flags.cocci
new file mode 100644 (file)
index 0000000..fbd0da5
--- /dev/null
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2024, Amazon and/or its affiliates. All rights reserved.
+// Use is subject to license terms.
+//
+// Replace macros with explicit flag manipulation. Demonstrates Python
+// scripting available with Coccinelle.
+//
+// Author: Timothy Day <timday@amazon.com>
+//
+
+@ldlm_is@
+identifier MACRO =~ "ldlm_is";
+@@
+MACRO(...)
+
+@script:python get_flag_is@
+IDENT << ldlm_is.MACRO;
+MACRO;
+FLAG;
+@@
+coccinelle.MACRO = IDENT
+
+if "granted" in IDENT:
+   cocci.include_match(False)
+
+IDENT = IDENT.split("_")
+IDENT = IDENT[2:]
+IDENT = ["LDLM", "FL"] + IDENT
+IDENT = "_".join(IDENT).upper()
+coccinelle.FLAG = IDENT
+
+print(coccinelle.MACRO, coccinelle.FLAG)
+
+@convert_is@
+identifier get_flag_is.FLAG;
+identifier get_flag_is.MACRO;
+identifier L;
+@@
+- MACRO(L)
++ (L->l_flags & FLAG)
+
+@ldlm_set@
+identifier MACRO =~ "ldlm_set";
+@@
+MACRO(...)
+
+@script:python get_flag_set@
+IDENT << ldlm_set.MACRO;
+MACRO;
+FLAG;
+@@
+coccinelle.MACRO = IDENT
+
+IDENT = IDENT.split("_")
+IDENT = IDENT[2:]
+IDENT = ["LDLM", "FL"] + IDENT
+IDENT = "_".join(IDENT).upper()
+coccinelle.FLAG = IDENT
+
+print(coccinelle.MACRO, coccinelle.FLAG)
+
+@convert_set@
+identifier get_flag_set.FLAG;
+identifier get_flag_set.MACRO;
+identifier L;
+@@
+- MACRO(L)
++ (L->l_flags |= FLAG)
+
+@ldlm_clear@
+identifier MACRO =~ "ldlm_clear";
+@@
+MACRO(...)
+
+@script:python get_flag_clear@
+IDENT << ldlm_clear.MACRO;
+MACRO;
+FLAG;
+@@
+coccinelle.MACRO = IDENT
+
+if "blocking_lock" in IDENT:
+   cocci.include_match(False)
+if "blocking_data" in IDENT:
+   cocci.include_match(False)
+
+IDENT = IDENT.split("_")
+IDENT = IDENT[2:]
+IDENT = ["LDLM", "FL"] + IDENT
+IDENT = "_".join(IDENT).upper()
+coccinelle.FLAG = IDENT
+
+print(coccinelle.MACRO, coccinelle.FLAG)
+
+@convert_clear@
+identifier get_flag_clear.FLAG;
+identifier get_flag_clear.MACRO;
+identifier L;
+@@
+- MACRO(L)
++ (L->l_flags &= ~FLAG)
diff --git a/contrib/cocci/lustre_free.cocci b/contrib/cocci/lustre_free.cocci
new file mode 100644 (file)
index 0000000..8adaeb6
--- /dev/null
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2024, Amazon and/or its affiliates. All rights reserved.
+// Use is subject to license terms.
+//
+// Don't check for NULL with common free'ing macros.
+//
+// Author: Timothy Day <timday@amazon.com>
+//
+
+@@
+expression E;
+@@
+- if (E != NULL)
+(
+  OBD_FREE_PTR(E);
+|
+  OBD_FREE(E, ...);
+|
+  LIBCFS_FREE(E, ...);
+|
+  CFS_FREE_PTR(E);
+|
+  CFS_FREE_PTR_ARRAY(E, ...);
+)