|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v6 15/44] xen/gunzip: process pending softirqs once per deflate block
Nothing in the gzip decompressor lets the CPU run softirqs. The NMI
watchdog treats a CPU as stuck once its timer softirq has not run for
the watchdog's timeout, 5s by default, so a decompression that runs
that long panics the host.
Decompression is normally quick, but it need not be. Every compressed
deflate block builds its Huffman tables with xmalloc() and frees them
with xfree(), and those calls reach the xenheap whenever a request is a
page or more, or a free empties an xmalloc pool page. A subsequent
change can make every xenheap free end in a TLB flush on all online
CPUs. With it in effect, decompressing the PV dom0 kernel and reading
its ELF headers on a 480-CPU host took 5.2s instead of 0.5s; with
cpufreq=xen:performance max_cstate=1,0 dom0_nodes=0,relaxed added to
the command line as well, the watchdog fired before decompression had
finished, on each of eight boots.
Process pending softirqs after each deflate block, as libelf does for
each ELF note since c5089fae0f6f ("x86: avoid tripping watchdog when
constructing dom0"), and as the PV and PVH dom0 builders do in their
long loops. Every caller of perform_gunzip() runs during domain
construction at boot, on the boot CPU with interrupts enabled and no
lock held: x86's PV and PVH dom0 builders, which call
process_pending_softirqs() themselves, and kernel_decompress(), which
Arm uses for dom0 and for dom0less domains.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: George Dunlap <gwd@xxxxxxxxxxxxxx>
---
Changes in v5:
- New in this version.
---
xen/common/gzip/gunzip.c | 1 +
xen/common/gzip/inflate.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/xen/common/gzip/gunzip.c b/xen/common/gzip/gunzip.c
index 89f45d4050..9551d470aa 100644
--- a/xen/common/gzip/gunzip.c
+++ b/xen/common/gzip/gunzip.c
@@ -3,6 +3,7 @@
#include <xen/init.h>
#include <xen/lib.h>
#include <xen/mm.h>
+#include <xen/softirq.h>
#define WSIZE 0x80000000U
diff --git a/xen/common/gzip/inflate.c b/xen/common/gzip/inflate.c
index cb146555c8..737aff505e 100644
--- a/xen/common/gzip/inflate.c
+++ b/xen/common/gzip/inflate.c
@@ -1018,6 +1018,7 @@ static int __init inflate(struct gunzip_state *s)
r = inflate_block(s, &e);
if (r)
return r;
+ process_pending_softirqs();
} while (!e);
/* Undo too much lookahead. The next read will be byte aligned so we
--
2.56.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |