Since KDUMP_COMMANDLINE is a global variable, prepare_cmdline can modify it directly instead of echoing back the result. This change enables it to output messages.
Changed some coding styles.
Signed-off-by: Xunlei Pang xlpang@redhat.com --- v1->v2: No change.
kdumpctl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/kdumpctl b/kdumpctl index cb6f004..b2068cc 100755 --- a/kdumpctl +++ b/kdumpctl @@ -105,10 +105,12 @@ append_cmdline() echo $cmdline }
-# This function performs a series of edits on the command line +# This function performs a series of edits on the command line. +# Store the final result in global $KDUMP_COMMANDLINE. prepare_cmdline() { - local cmdline; + local cmdline id + if [ -z "$KDUMP_COMMANDLINE" ]; then cmdline=`cat /proc/cmdline` # 'root' parameter will cause kdump failure in live images @@ -118,6 +120,7 @@ prepare_cmdline() else cmdline=${KDUMP_COMMANDLINE} fi + # These params should always be removed cmdline=`remove_cmdline_param "$cmdline" crashkernel panic_on_warn` # These params can be removed configurably @@ -125,12 +128,12 @@ prepare_cmdline()
cmdline="${cmdline} ${KDUMP_COMMANDLINE_APPEND}"
- local id=`get_bootcpu_initial_apicid` + id=`get_bootcpu_initial_apicid` if [ ! -z ${id} ] ; then cmdline=`append_cmdline "${cmdline}" disable_cpu_apicid ${id}` fi
- echo $cmdline + KDUMP_COMMANDLINE=$cmdline }
@@ -642,7 +645,7 @@ load_kdump() fi fi
- KDUMP_COMMANDLINE=`prepare_cmdline` + prepare_cmdline
# For secureboot enabled machines, use new kexec file based syscall. # Old syscall will always fail as it does not have capability to
Check the number of cpus for x86_64 kdump kernel to boot with. We met an issue for x86_64: kdump runs out of vectors with the default "nr_cpus=1", when requesting tons of irqs.
This patch detects such situation and warns users about the risk.
Signed-off-by: Xunlei Pang xlpang@redhat.com --- v1->v2: - When detecting risky cpu vectors, we just warn users instead of modifying "nr_cpus=X" forcely. - Improved code comments.
kdumpctl | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+)
diff --git a/kdumpctl b/kdumpctl index b2068cc..db78f76 100755 --- a/kdumpctl +++ b/kdumpctl @@ -105,6 +105,85 @@ append_cmdline() echo $cmdline }
+# Check the number of cpus for kdump kernel to boot with. +# We met an issue for x86_64: kdump runs out of vectors with +# "nr_cpus=1" when requesting tons of irqs, so here we check +# "nr_cpus=X" and warn users if kdump probably can't work. +check_kdump_cpus() +{ + local nr nr_old nr_min nr_max + local arch=$(uname -m) cmdline=$KDUMP_COMMANDLINE + + # Special treatment for x86_64 only currently. + if [ $arch != "x86_64" ]; then + return + fi + + # We only care about "nr_cpus=X" format for x86. + nr_old=$(echo $cmdline | grep -o "nr_cpus=[0-9]*" | wc -l) + if [ $nr_old -eq 0 ] ; then + # Do not need to process if no valid "nr_cpus=X" specified. + return + fi + + # Get value X of "nr_cpus=X" + nr_old=$(echo $cmdline | grep -o "nr_cpus=[0-9]*" | cut -d "=" -f2 | grep "[0-9]" | sort) + # In case there are multiple "nr_cpus=X", get the mininum value. + for nr in $nr_old; do + if [ $nr -gt 0 ]; then + nr_old=$nr + break + fi + done + if [ -z "$nr_old" ]; then + echo "Warning: Wrong "nr_cpus=" kernel cmdline detected" + return + fi + + # Online cpus in first kernel. + nr_max=$(nproc) + + # Calculate estimated minium cpus required by irqs(vectors). + nr_min=$(ls /proc/irq/ -l | grep ^d | wc -l) + + # We roughly use 256-32(see kernel FIRST_EXTERNAL_VECTOR)=224 as + # maximum supported vectors can be allocated to io devices percpu. + # As nr_min is a ballpart figure, also some high-numbered vectors + # are consumed by the kernel(see FIRST_SYSTEM_VECTOR), we need a + # variance for safety. + # + # We got a large machine with 240 cpus, 6TB memory, 8 iommus, and + # 12 io-apics, 132 irqs under /proc/irq/, it can boot successfully + # with "nr_cpus=1". (256-32-132)=92, so choosing 64 as the variance + # seems ok. Then we get the max external irqs supported per cpu: + # (256-32-64)=160 as the dividend. + nr_min=$(($nr_min + 160 - 1)) + nr_min=$(($nr_min / 160)) + if [ $nr_min -gt 1 ]; then + # The system seems to have tons of interrupts. while interrupts + # with multiple-cpu affinity can consume multiple vectors, with + # one vector for each cpu within the affinity mask. Fortunately + # for x2apic which is widely used on large modern machines, in + # default case of boot, device bringup etc will use a single cpu + # for the interrupt affinity to minimize vector pressure. + # + # For further safety, we add one more cpu and round it up to an + # even number which is commonly-used. + nr_min=$(($nr_min + 1)) + nr_min=$(($nr_min + $nr_min % 2)) + fi + + if [ $nr_min -gt $nr_max ]; then + nr_min=$nr_max + fi + + if [ $nr_old -ge $nr_min ]; then + return + fi + + echo "Warning: CPU vectors under pressure with "nr_cpus=$nr_old", please try "nr_cpus=$nr_min" or more" +} + # This function performs a series of edits on the command line. # Store the final result in global $KDUMP_COMMANDLINE. prepare_cmdline() @@ -134,6 +213,8 @@ prepare_cmdline() fi
KDUMP_COMMANDLINE=$cmdline + + check_kdump_cpus }