diff --git a/configs/arcbox-arm64.config b/configs/arcbox-arm64.config index 1878404..c4b853f 100644 --- a/configs/arcbox-arm64.config +++ b/configs/arcbox-arm64.config @@ -68,13 +68,17 @@ CONFIG_64BIT=y CONFIG_MMU=y CONFIG_SMP=y CONFIG_NR_CPUS=256 -# Lazy preemption: near-voluntary throughput, far lower scheduling -# latency for interactive guest work (container exec, port-forward -# first byte). Also forward-compatible — 7.0 removes voluntary for -# lazy-capable arches, and arm64/x86 both select ARCH_HAS_PREEMPT_LAZY. -CONFIG_PREEMPT_LAZY=y -CONFIG_HZ_100=y -CONFIG_HZ=100 +CONFIG_PREEMPT_VOLUNTARY=y +# HZ=1000 (1 ms tick) not 100 (10 ms): container start is a chain of +# jiffy-rounded scheduler waits (containerd poll, shim handshake +# completions, runc, dockerd↔containerd gRPC backoff). At HZ=100 each +# rounds up to 10 ms, making container churn ~5x slower than Colima's +# HZ=1000 guest — the dominant cost in multi-step `docker build` (each +# step is a container). NO_HZ_IDLE keeps the idle-CPU target intact +# (tickless when idle), so this is latency-only cost under active load. +# See ABX-496. +CONFIG_HZ_1000=y +CONFIG_HZ=1000 # Virtualization guest support CONFIG_PARAVIRT=y diff --git a/configs/arcbox-x86_64.config b/configs/arcbox-x86_64.config index 929d3a7..cfeb11d 100644 --- a/configs/arcbox-x86_64.config +++ b/configs/arcbox-x86_64.config @@ -67,13 +67,17 @@ CONFIG_X86=y CONFIG_MMU=y CONFIG_SMP=y CONFIG_NR_CPUS=256 -# Lazy preemption: near-voluntary throughput, far lower scheduling -# latency for interactive guest work (container exec, port-forward -# first byte). Also forward-compatible — 7.0 removes voluntary for -# lazy-capable arches, and arm64/x86 both select ARCH_HAS_PREEMPT_LAZY. -CONFIG_PREEMPT_LAZY=y -CONFIG_HZ_100=y -CONFIG_HZ=100 +CONFIG_PREEMPT_VOLUNTARY=y +# HZ=1000 (1 ms tick) not 100 (10 ms): container start is a chain of +# jiffy-rounded scheduler waits (containerd poll, shim handshake +# completions, runc, dockerd↔containerd gRPC backoff). At HZ=100 each +# rounds up to 10 ms, making container churn ~5x slower than Colima's +# HZ=1000 guest — the dominant cost in multi-step `docker build` (each +# step is a container). NO_HZ_IDLE keeps the idle-CPU target intact +# (tickless when idle), so this is latency-only cost under active load. +# See ABX-496. +CONFIG_HZ_1000=y +CONFIG_HZ=1000 # Virtualization guest support CONFIG_HYPERVISOR_GUEST=y diff --git a/scripts/build-kernel.sh b/scripts/build-kernel.sh index 1ba6bf4..89df738 100755 --- a/scripts/build-kernel.sh +++ b/scripts/build-kernel.sh @@ -73,25 +73,17 @@ do_build() { # dependency gate in the fragment otherwise degrades silently — 6.18 did # exactly that to the legacy iptables stack via NETFILTER_XTABLES_LEGACY). for sym in CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU CONFIG_IP_NF_NAT \ - CONFIG_IP6_NF_NAT; do + CONFIG_IP6_NF_NAT CONFIG_HZ_1000; do grep -q "^$sym=y" .config || { echo "ERROR: $sym missing after olddefconfig" >&2 exit 1 } done - # PREEMPT_LAZY exists only where the arch wires it up (x86 6.13+, - # arm64 6.16+). Assert it there; on an older KERNEL_VERSION override - # the choice falls back to its kconfig default, which is worth a - # warning but must not fail a bisect build. - if grep -q '^CONFIG_ARCH_HAS_PREEMPT_LAZY=y' .config; then - grep -q '^CONFIG_PREEMPT_LAZY=y' .config || { - echo 'ERROR: CONFIG_PREEMPT_LAZY missing after olddefconfig' >&2 - exit 1 - } - else - echo 'WARN: kernel lacks ARCH_HAS_PREEMPT_LAZY; preemption model falls back to the kconfig default' >&2 - fi + grep -q '^CONFIG_PREEMPT_VOLUNTARY=y' .config || { + echo 'ERROR: CONFIG_PREEMPT_VOLUNTARY missing after olddefconfig' >&2 + exit 1 + } # Build. echo "Building kernel..." @@ -132,20 +124,16 @@ cd linux-$KERNEL_VERSION sh /workspace/scripts/inject-drivers.sh /workspace cp /workspace/configs/arcbox-$TARGET_ARCH.config .config make ARCH=$TARGET_ARCH olddefconfig -for sym in CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU CONFIG_IP_NF_NAT CONFIG_IP6_NF_NAT; do +for sym in CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU CONFIG_IP_NF_NAT CONFIG_IP6_NF_NAT CONFIG_HZ_1000; do grep -q \"^\$sym=y\" .config || { echo \"ERROR: \$sym missing after olddefconfig\" >&2 exit 1 } done -if grep -q '^CONFIG_ARCH_HAS_PREEMPT_LAZY=y' .config; then - grep -q '^CONFIG_PREEMPT_LAZY=y' .config || { - echo 'ERROR: CONFIG_PREEMPT_LAZY missing after olddefconfig' >&2 - exit 1 - } -else - echo 'WARN: kernel lacks ARCH_HAS_PREEMPT_LAZY; preemption model falls back to the kconfig default' >&2 -fi +grep -q '^CONFIG_PREEMPT_VOLUNTARY=y' .config || { + echo 'ERROR: CONFIG_PREEMPT_VOLUNTARY missing after olddefconfig' >&2 + exit 1 +} echo 'Building kernel...' make ARCH=$TARGET_ARCH -j\$(nproc) $KERNEL_IMAGE cp arch/$TARGET_ARCH/boot/$KERNEL_IMAGE /output/kernel-$TARGET_ARCH