Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

coccicheck: enable parmap support

Coccinelle has had parmap support since 1.0.2, this means
it supports --jobs, enabling built-in multithreaded functionality,
instead of needing one to script it out. Just look for --jobs
in the help output to determine if this is supported and use it
only if your number of processors detected is > 1.

If parmap is enabled also enable the load balancing to be dynamic, so
that if a thread finishes early we keep feeding it.

stderr is currently sent to /dev/null, addressing a way to capture
that will be addressed next.

If --jobs is not supported we fallback to the old mechanism.
We expect to deprecate the old mechanism as soon as we can get
confirmation all users are ready.

While at it propagate back into the shell script any coccinelle error
code. When used in serialized mode where all cocci files are run this
also stops processing if an error has occured. This lets us handle some
errors in coccinelle cocci files and if they bail out we should inspect
the errors. This will be more useful later to help annotate coccinelle
version dependency requirements. This will let you run only SmPL files
that your system supports.

Extend Documentation/coccinelle.txt as well.

As a small example, prior to this change, on an 8-core system:

Before:

$ export COCCI=scripts/coccinelle/free/kfree.cocci
$ time make coccicheck MODE=report
...

real 29m14.912s
user 103m1.796s
sys 0m4.464s

After:

real 16m22.435s
user 128m30.060s
sys 0m2.712s

v4:

o expand Documentation/coccinelle.txt to reflect parmap support info
o update commit log to reflect what we actually do now with stderr
o split out DEBUG_FILE use into another patch
o detect number of CPUs and if its 1 then skip parmap support,
note that if you still support parmap, but have 1 CPU you will
also go through the new branches, so the old complex multithreaded process
is skipped as well.

v3:

o move USE_JOBS to avoid being overriden

v2:

o redirect coccinelle stderr to /dev/null by default and
only if DEBUG_FILE is used do we pass it to a file
o fix typo of paramap/parmap

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
Acked-by: Nicolas Palix <nicolas.palix@imag.fr>
Signed-off-by: Michal Marek <mmarek@suse.com>

authored by

Luis R. Rodriguez and committed by
Michal Marek
c930a1b2 8e826ad5

+47 -3
+15
Documentation/coccinelle.txt
··· 94 94 95 95 make coccicheck MODE=report V=1 96 96 97 + Coccinelle parallelization 98 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 99 + 97 100 By default, coccicheck tries to run as parallel as possible. To change 98 101 the parallelism, set the J= variable. For example, to run across 4 CPUs: 99 102 100 103 make coccicheck MODE=report J=4 101 104 105 + As of Coccinelle 1.0.2 Coccinelle uses Ocaml parmap for parallelization, 106 + if support for this is detected you will benefit from parmap parallelization. 107 + 108 + When parmap is enabled coccicheck will enable dynamic load balancing by using 109 + '--chunksize 1' argument, this ensures we keep feeding threads with work 110 + one by one, so that we avoid the situation where most work gets done by only 111 + a few threads. With dynamic load balancing, if a thread finishes early we keep 112 + feeding it more work. 113 + 114 + When parmap is enabled, if an error occurs in Coccinelle, this error 115 + value is propagated back, the return value of the 'make coccicheck' 116 + captures this return value. 102 117 103 118 Using Coccinelle with a single semantic patch 104 119 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+32 -3
scripts/coccicheck
··· 12 12 exit 1 13 13 fi 14 14 15 - trap kill_running SIGTERM SIGINT 16 - declare -a SPATCH_PID 15 + USE_JOBS="no" 16 + $SPATCH --help | grep "\-\-jobs" > /dev/null && USE_JOBS="yes" 17 17 18 18 # The verbosity may be set by the environmental parameter V= 19 19 # as for example with 'make V=1 coccicheck' ··· 56 56 OPTIONS="--patch $srctree $OPTIONS" 57 57 fi 58 58 59 + # You can override by using SPFLAGS 60 + if [ "$USE_JOBS" = "no" ]; then 61 + trap kill_running SIGTERM SIGINT 62 + declare -a SPATCH_PID 63 + elif [ "$NPROC" != "1" ]; then 64 + # Using 0 should work as well, refer to _SC_NPROCESSORS_ONLN use on 65 + # https://github.com/rdicosmo/parmap/blob/master/setcore_stubs.c 66 + OPTIONS="$OPTIONS --jobs $NPROC --chunksize 1" 67 + fi 68 + 59 69 if [ "$MODE" = "" ] ; then 60 70 if [ "$ONLINE" = "0" ] ; then 61 71 echo 'You have not explicitly specified the mode to use. Using default "report" mode.' ··· 92 82 echo '' 93 83 fi 94 84 95 - run_cmd() { 85 + run_cmd_parmap() { 86 + if [ $VERBOSE -ne 0 ] ; then 87 + echo "Running ($NPROC in parallel): $@" 88 + fi 89 + $@ 2>/dev/null 90 + if [[ $? -ne 0 ]]; then 91 + echo "coccicheck failed" 92 + exit $? 93 + fi 94 + } 95 + 96 + run_cmd_old() { 96 97 local i 97 98 if [ $VERBOSE -ne 0 ] ; then 98 99 echo "Running ($NPROC in parallel): $@" ··· 116 95 fi 117 96 done 118 97 wait 98 + } 99 + 100 + run_cmd() { 101 + if [ "$USE_JOBS" = "yes" ]; then 102 + run_cmd_parmap $@ 103 + else 104 + run_cmd_old $@ 105 + fi 119 106 } 120 107 121 108 kill_running() {