[PATCH v2 21/21] kbuild: use pigz for gzip compression if available
From: Lorenzo Stoakes (ARM)
Date: Mon Sep 14 2026 - 05:43:04 EST
The gzip step of a kernel build is very lengthily, especially for larger
builds such as allmodconfig.
gzip itself cannot be run in parallel, however an alternative tool exists
that can, providing the same feature set as gzip itself - pigz - which
works as a drop-in replacement.
On a 128-core Threadripper, gzip -9 of a 36 MiB x86-64 vmlinux.bin takes
1.6s, and with pigz it takes 0.09s, so the performance increase is
significant.
It is already possible to specify KGZIP on the make command line to make
use of pigz, however it seems sensible to make use of pigz if it is
available.
Therefore default to using pigz if it is available on the system upon which
the kernel is being built, otherwise fall back to gzip.
Modules are compressed one per make job at install time, so a parallel
compressor gains nothing there and with -jN would run N times the core
count in threads. Limit pigz to a single thread for module compression.
The output is byte-for-byte identical between pigz/gzip invocations, but
gzip and pigz do not produce the same stream as one another.
Therefore, for reproducible builds, the same set of tools should be used.
This seems to already be an implicit requirement in any case, but update
the reproducible build documentation to make this clear.
Also update the kbuild documentation to reflect the change.
Every x86 build ends with the compression of vmlinux.bin, 36MB for
defconfig and over 200MB for allmodconfig, no-op builds are unchanged.
Whole build, 128-thread Threadripper 9980X, best of N runs:
before after delta
-------------------------------
x86 defconfig, touch mm/vma.c, gcc 7.7s 6.0s -1.7s (-22%)
x86 defconfig, touch mm/vma.c, clang 6.9s 5.4s -1.5s (-21%)
x86 defconfig, clean, gcc 28.2s 26.3s -1.8s (-6%)
x86 defconfig, clean, clang 28.7s 27.2s -1.5s (-5%)
x86 allmodconfig, touch mm/vma.c, gcc 23.7s 15.4s -8.3s (-35%)
x86 allmodconfig, touch mm/vma.c, clang 22.5s 15.6s -7.0s (-31%)
x86 allmodconfig, clean, gcc 294.1s 278.6s -15.5s (-5%)
x86 allmodconfig, clean, clang 283.9s 266.8s -17.1s (-6%)
Link: https://zlib.net/pigz/
Assisted-by: LLM
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>
---
Documentation/kbuild/kbuild.rst | 15 +++++++++++++++
Documentation/kbuild/reproducible-builds.rst | 16 ++++++++++++++++
Makefile | 2 +-
scripts/Makefile.modinst | 4 +++-
4 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/Documentation/kbuild/kbuild.rst b/Documentation/kbuild/kbuild.rst
index 9b2b127676c3..ebfc2945ac03 100644
--- a/Documentation/kbuild/kbuild.rst
+++ b/Documentation/kbuild/kbuild.rst
@@ -110,6 +110,21 @@ HOSTLDLIBS
----------
Additional libraries to link against when building host programs.
+KGZIP
+-----
+The gzip compressor used for the compressed kernel image, compressed
+modules and packaging.
+
+Defaults to pigz (a parallel implementation of gzip) if it is available,
+otherwise gzip. Set ``KGZIP=`` on the make command line to use another
+program. Modules are compressed one per make job, so pigz is limited to a
+single thread there.
+
+KBZIP2, KLZOP, LZMA, LZ4, XZ, ZSTD
+----------------------------------
+The compressor programs for the other formats. Each defaults to the program
+of the same name.
+
.. _userkbuildflags:
USERCFLAGS
diff --git a/Documentation/kbuild/reproducible-builds.rst b/Documentation/kbuild/reproducible-builds.rst
index bc1eb82211df..ec0135da4464 100644
--- a/Documentation/kbuild/reproducible-builds.rst
+++ b/Documentation/kbuild/reproducible-builds.rst
@@ -76,6 +76,22 @@ include generated files. You should ensure the source tree is
pristine by running ``make mrproper`` or ``git clean -d -f -x`` before
building a source package.
+Compression tools
+-----------------
+
+The compressed kernel image, compressed modules and packages are produced
+using the program named by the make variable ``KGZIP`` (described in
+Documentation/kbuild/kbuild.rst).
+
+It defaults to ``pigz`` if installed (a parallel implementation of gzip),
+or ``gzip`` otherwise.
+
+The generated output between two invocations of identical builds with
+either of the default tools will be byte-for-byte equivalent.
+
+However, for reproducible builds, ensure the same tool is used on all build
+hosts, as different tools may generate different output from one another.
+
Module signing
--------------
diff --git a/Makefile b/Makefile
index 790ef23c5e8a..38c0cdc9f591 100644
--- a/Makefile
+++ b/Makefile
@@ -561,7 +561,7 @@ PERL = perl
PYTHON3 = python3
CHECK = sparse
BASH = bash
-KGZIP = gzip
+KGZIP := $(if $(shell command -v pigz 2>/dev/null),pigz,gzip)
KBZIP2 = bzip2
KLZOP = lzop
LZMA = lzma
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index 9ba45e5b32b1..58dafec8f910 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -145,8 +145,10 @@ endif
#
# Compression
#
+# Modules are compressed in parallel by make itself, so keep the compressor
+# single-threaded when it is pigz.
quiet_cmd_gzip = GZIP $@
- cmd_gzip = $(KGZIP) -n -f $<
+ cmd_gzip = $(KGZIP) $(if $(filter pigz,$(notdir $(firstword $(KGZIP)))),-p 1) -n -f $<
quiet_cmd_xz = XZ $@
cmd_xz = $(XZ) --check=crc32 --lzma2=dict=1MiB -f $<
quiet_cmd_zstd = ZSTD $@
--
2.55.0