diff --git a/arch/x86/tools/mcreboot-smp-x86.sh.in b/arch/x86/tools/mcreboot-smp-x86.sh.in index 2e9ee6d0..c72f4d41 100644 --- a/arch/x86/tools/mcreboot-smp-x86.sh.in +++ b/arch/x86/tools/mcreboot-smp-x86.sh.in @@ -258,6 +258,26 @@ if [ "${irqbalance_used}" == "yes" ]; then echo "error: stopping irqbalance" >&2 error_exit "aslr_disabled" fi; + + if ! etcdir=@ETCDIR@ perl -e 'use File::Copy qw(copy); $etcdir=$ENV{'etcdir'}; @files = grep { -f } glob "/proc/irq/*/smp_affinity"; foreach $file (@files) { $rel = substr($file, 1); $dir=substr($rel, 0, length($rel)-length("/smp_affinity")); if(0) { print "cp $file $etcdir/$rel\n";} if(system("mkdir -p $etcdir/$dir")){ exit 1;} if(!copy($file,"$etcdir/$rel")){ exit 1;} }'; then + echo "error: saving /proc/irq/*/smp_affinity" >&2 + error_exit "mcos_sys_mounted" + fi; + +# Prevent /proc/irq/*/smp_affinity from getting zero after offlining +# McKernel CPUs by using the following algorithm. +# if (smp_affinity & mck_cores) { +# smp_affinity = (mck_cores ^ -1); +# } + ncpus=`lscpu | grep -E '^CPU\(s\):' | awk '{print $2}'` + smp_affinity_mask=`echo $cpus | ncpus=$ncpus perl -e 'while(<>){@tokens = split /,/;foreach $token (@tokens) {@nums = split /-/,$token; for($num = $nums[0]; $num <= $nums[$#nums]; $num++) {$ndx=int($num/32); $mask[$ndx] |= (1<<($num % 32))}}} $nint32s = int(($ENV{'ncpus'}+31)/32); for($j = $nint32s - 1; $j >= 0; $j--) { if($j != $nint32s - 1){print ",";} $nblks = ($j != $nint32s - 1) ? 8 : ($ENV{'ncpus'} % 32 != 0) ? int((($ENV{'ncpus'} + 3) % 32) / 4) : 8; for($i = $nblks - 1;$i >= 0;$i--){ printf("%01x",($mask[$j] >> ($i*4)) & 0xf);}}'` +# echo cpus=$cpus ncpus=$ncpus smp_affinity_mask=$smp_affinity_mask + + if ! ncpus=$ncpus smp_affinity_mask=$smp_affinity_mask perl -e '@dirs = grep { -d } glob "/proc/irq/*"; foreach $dir (@dirs) { $hit = 0; $affinity_str = `cat $dir/smp_affinity`; chomp $affinity_str; @int32strs = split /,/, $affinity_str; @int32strs_mask=split /,/, $ENV{'smp_affinity_mask'}; for($i=0;$i <= $#int32strs_mask; $i++) { $int32strs_inv[$i] = sprintf("%08x",hex($int32strs_mask[$i])^0xffffffff); if($i == 0) { $len = int((($ENV{'ncpus'}%32)+3)/4); if($len != 0) { $int32strs_inv[$i] = substr($int32strs_inv[$i], -$len, $len); } } } $inv = join(",", @int32strs_inv); $nint32s = int(($ENV{'ncpus'}+31)/32); for($j = $nint32s - 1; $j >= 0; $j--) { if(hex($int32strs[$nint32s - 1 - $j]) & hex($int32strs_mask[$nint32s - 1 - $j])) { $hit = 1; }} if($hit == 1) { $cmd = "echo $inv > $dir/smp_affinity 2>/dev/null"; system $cmd;}}'; then + echo "error: modifying /proc/irq/*/smp_affinity" >&2 + error_exit "mcos_sys_mounted" + fi + fi # Load IHK if not loaded @@ -482,25 +502,6 @@ fi # Start irqbalance with CPUs and IRQ for McKernel banned if [ "${irqbalance_used}" == "yes" ]; then - if ! etcdir=@ETCDIR@ perl -e 'use File::Copy qw(copy); $etcdir=$ENV{'etcdir'}; @files = grep { -f } glob "/proc/irq/*/smp_affinity"; foreach $file (@files) { $rel = substr($file, 1); $dir=substr($rel, 0, length($rel)-length("/smp_affinity")); if(0) { print "cp $file $etcdir/$rel\n";} if(system("mkdir -p $etcdir/$dir")){ exit 1;} if(!copy($file,"$etcdir/$rel")){ exit 1;} }'; then - echo "error: saving /proc/irq/*/smp_affinity" >&2 - error_exit "mcos_sys_mounted" - fi; - -# Prevent /proc/irq/*/smp_affinity from getting zero after offlining -# McKernel CPUs by using the following algorithm. -# if (smp_affinity & mck_cores) { -# smp_affinity = (mck_cores ^ -1); -# } - ncpus=`lscpu | grep -E '^CPU\(s\):' | awk '{print $2}'` - smp_affinity_mask=`echo $cpus | ncpus=$ncpus perl -e 'while(<>){@tokens = split /,/;foreach $token (@tokens) {@nums = split /-/,$token; for($num = $nums[0]; $num <= $nums[$#nums]; $num++) {$ndx=int($num/32); $mask[$ndx] |= (1<<($num % 32))}}} $nint32s = int(($ENV{'ncpus'}+31)/32); for($j = $nint32s - 1; $j >= 0; $j--) { if($j != $nint32s - 1){print ",";} $nblks = ($j != $nint32s - 1) ? 8 : ($ENV{'ncpus'} % 32 != 0) ? int((($ENV{'ncpus'} + 3) % 32) / 4) : 8; for($i = $nblks - 1;$i >= 0;$i--){ printf("%01x",($mask[$j] >> ($i*4)) & 0xf);}}'` -# echo cpus=$cpus ncpus=$ncpus smp_affinity_mask=$smp_affinity_mask - - if ! ncpus=$ncpus smp_affinity_mask=$smp_affinity_mask perl -e '@dirs = grep { -d } glob "/proc/irq/*"; foreach $dir (@dirs) { $hit = 0; $affinity_str = `cat $dir/smp_affinity`; chomp $affinity_str; @int32strs = split /,/, $affinity_str; @int32strs_mask=split /,/, $ENV{'smp_affinity_mask'}; for($i=0;$i <= $#int32strs_mask; $i++) { $int32strs_inv[$i] = sprintf("%08x",hex($int32strs_mask[$i])^0xffffffff); if($i == 0) { $len = int((($ENV{'ncpus'}%32)+3)/4); $int32strs_inv[$i] = substr($int32strs_inv[$i], -$len, $len); } } $inv = join(",", @int32strs_inv); $nint32s = int(($ENV{'ncpus'}+31)/32); for($j = $nint32s - 1; $j >= 0; $j--) { if(hex($int32strs[$nint32s - 1 - $j]) & hex($int32strs_mask[$nint32s - 1 - $j])) { $hit = 1; }} if($hit == 1) { $cmd = "echo $inv > $dir/smp_affinity 2>/dev/null"; system $cmd;}}'; then - echo "error: modifying /proc/irq/*/smp_affinity" >&2 - error_exit "mcos_sys_mounted" - fi - banirq=`cat /proc/interrupts| perl -e 'while(<>) { if(/^\s*(\d+).*IHK\-SMP\s*$/) {print $1;}}'` sed "s/%mask%/$smp_affinity_mask/g" $ETCDIR/irqbalance_mck.in | sed "s/%banirq%/$banirq/g" > /tmp/irqbalance_mck diff --git a/arch/x86/tools/mcstop+release-smp-x86.sh.in b/arch/x86/tools/mcstop+release-smp-x86.sh.in index 9ed04613..e5b7cdf9 100644 --- a/arch/x86/tools/mcstop+release-smp-x86.sh.in +++ b/arch/x86/tools/mcstop+release-smp-x86.sh.in @@ -16,6 +16,7 @@ KERNDIR="@KERNDIR@" mem="" cpus="" +irqbalance_used="" # No SMP module? Exit. if ! grep ihk_smp_x86 /proc/modules &>/dev/null; then exit 0; fi @@ -26,6 +27,16 @@ do pkill -9 mcklogd done +if [ "`systemctl status irqbalance_mck.service 2> /dev/null |grep -E 'Active: active'`" != "" ]; then + irqbalance_used="yes" + if ! systemctl stop irqbalance_mck.service 2>/dev/null; then + echo "warning: failed to stop irqbalance_mck" >&2 + fi + if ! systemctl disable irqbalance_mck.service >/dev/null 2>/dev/null; then + echo "warning: failed to disable irqbalance_mck" >&2 + fi +fi + # Destroy all LWK instances if ls /dev/mcos* 1>/dev/null 2>&1; then for i in /dev/mcos*; do @@ -101,13 +112,7 @@ if grep -E 'ihk\s' /proc/modules &>/dev/null; then fi # Start irqbalance with the original settings -if [ "`systemctl status irqbalance_mck.service 2> /dev/null |grep -E 'Active: active'`" != "" ]; then - if ! systemctl stop irqbalance_mck.service 2>/dev/null; then - echo "warning: failed to stop irqbalance_mck" >&2 - fi - if ! systemctl disable irqbalance_mck.service >/dev/null 2>/dev/null; then - echo "warning: failed to disable irqbalance_mck" >&2 - fi +if [ "${irqbalance_used}" != "" ]; then if ! etcdir=@ETCDIR@ perl -e '$etcdir=$ENV{'etcdir'}; @files = grep { -f } glob "$etcdir/proc/irq/*/smp_affinity"; foreach $file (@files) { $dest = substr($file, length($etcdir)); if(0) {print "cp $file $dest\n";} system("cp $file $dest 2>/dev/null"); }'; then echo "warning: failed to restore /proc/irq/*/smp_affinity" >&2 fi